From be655d122aec8d99ba4bee3a4d342ec3cccdf39a Mon Sep 17 00:00:00 2001 From: Danil Date: Wed, 10 Jul 2024 11:41:06 +0200 Subject: [PATCH 01/21] Some features Signed-off-by: Danil --- zk_toolbox/crates/common/src/git.rs | 31 +++++++++++++++ zk_toolbox/crates/common/src/lib.rs | 1 + .../zk_inception/src/commands/chain/init.rs | 3 +- .../zk_inception/src/commands/containers.rs | 3 ++ .../src/commands/ecosystem/create.rs | 38 +++++-------------- .../src/commands/ecosystem/init.rs | 4 +- .../src/commands/prover/init_bellman_cuda.rs | 18 ++++----- 7 files changed, 57 insertions(+), 41 deletions(-) create mode 100644 zk_toolbox/crates/common/src/git.rs diff --git a/zk_toolbox/crates/common/src/git.rs b/zk_toolbox/crates/common/src/git.rs new file mode 100644 index 000000000000..7ebedf0f6283 --- /dev/null +++ b/zk_toolbox/crates/common/src/git.rs @@ -0,0 +1,31 @@ +use std::path::PathBuf; + +use xshell::{cmd, Shell}; + +use crate::cmd::Cmd; + +pub fn clone( + shell: &Shell, + path: PathBuf, + repository: &str, + name: &str, +) -> anyhow::Result { + let _dir = shell.push_dir(path); + Cmd::new(cmd!( + shell, + "git clone --recurse-submodules {repository} {name}" + )) + .run()?; + Ok(shell.current_dir().join(name)) +} + +pub fn submodule_update(shell: &Shell, link_to_code: PathBuf) -> anyhow::Result<()> { + let _dir_guard = shell.push_dir(link_to_code); + Cmd::new(cmd!( + shell, + "git submodule update --init --recursive +" + )) + .run()?; + Ok(()) +} diff --git a/zk_toolbox/crates/common/src/lib.rs b/zk_toolbox/crates/common/src/lib.rs index 022f8df7052e..2ab5c5f10e13 100644 --- a/zk_toolbox/crates/common/src/lib.rs +++ b/zk_toolbox/crates/common/src/lib.rs @@ -9,6 +9,7 @@ pub mod docker; pub mod ethereum; pub mod files; pub mod forge; +pub mod git; pub mod server; pub mod wallets; diff --git a/zk_toolbox/crates/zk_inception/src/commands/chain/init.rs b/zk_toolbox/crates/zk_inception/src/commands/chain/init.rs index b30b20227d90..69233a94e45f 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/chain/init.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/chain/init.rs @@ -3,7 +3,7 @@ use common::{ cmd::Cmd, config::global_config, forge::{Forge, ForgeScriptArgs}, - logger, + git, logger, spinner::Spinner, }; use config::{ @@ -43,6 +43,7 @@ pub(crate) async fn run(args: InitArgs, shell: &Shell) -> anyhow::Result<()> { logger::note(MSG_SELECTED_CONFIG, logger::object_to_string(&chain_config)); logger::info(msg_initializing_chain("")); + git::submodule_update(shell, config.link_to_code.clone())?; init(&mut args, shell, &config, &chain_config).await?; diff --git a/zk_toolbox/crates/zk_inception/src/commands/containers.rs b/zk_toolbox/crates/zk_inception/src/commands/containers.rs index bba19fb89f94..b34b598afbe1 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/containers.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/containers.rs @@ -74,5 +74,8 @@ fn copy_dockerfile(shell: &Shell, link_to_code: PathBuf) -> anyhow::Result<()> { let data = docker_compose_text.replace(original_source, new_source); shell.write_file(DOCKER_COMPOSE_FILE, data)?; + // For some reasons our docker-compose sometimes required .env file while we are investigating this behaviour + // it's better to create file and don't make the life of customers harder + shell.write_file(".env", "")?; Ok(()) } diff --git a/zk_toolbox/crates/zk_inception/src/commands/ecosystem/create.rs b/zk_toolbox/crates/zk_inception/src/commands/ecosystem/create.rs index a94c189d2b2b..0514c0918040 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/ecosystem/create.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/ecosystem/create.rs @@ -1,16 +1,13 @@ -use std::{ - path::{Path, PathBuf}, - str::FromStr, -}; +use std::{path::PathBuf, str::FromStr}; use anyhow::bail; -use common::{cmd::Cmd, logger, spinner::Spinner}; +use common::{git, logger, spinner::Spinner}; use config::{ create_local_configs_dir, create_wallets, get_default_era_chain_id, traits::SaveConfigWithBasePath, EcosystemConfig, EcosystemConfigFromFileError, ZKSYNC_ERA_GIT_REPO, }; -use xshell::{cmd, Shell}; +use xshell::Shell; use crate::{ commands::{ @@ -55,12 +52,17 @@ fn create(args: EcosystemCreateArgs, shell: &Shell) -> anyhow::Result<()> { let link_to_code = if args.link_to_code.is_empty() { let spinner = Spinner::new(MSG_CLONING_ERA_REPO_SPINNER); - let link_to_code = clone_era_repo(shell)?; + let link_to_code = git::clone( + shell, + shell.current_dir(), + ZKSYNC_ERA_GIT_REPO, + "zksync-era", + )?; spinner.finish(); link_to_code } else { let path = PathBuf::from_str(&args.link_to_code)?; - update_submodules_recursive(shell, &path)?; + git::submodule_update(shell, path.clone())?; path }; @@ -112,23 +114,3 @@ fn create(args: EcosystemCreateArgs, shell: &Shell) -> anyhow::Result<()> { logger::outro(MSG_CREATED_ECOSYSTEM); Ok(()) } - -fn clone_era_repo(shell: &Shell) -> anyhow::Result { - Cmd::new(cmd!( - shell, - "git clone --recurse-submodules {ZKSYNC_ERA_GIT_REPO}" - )) - .run()?; - Ok(shell.current_dir().join("zksync-era")) -} - -fn update_submodules_recursive(shell: &Shell, link_to_code: &Path) -> anyhow::Result<()> { - let _dir_guard = shell.push_dir(link_to_code); - Cmd::new(cmd!( - shell, - "git submodule update --init --recursive -" - )) - .run()?; - Ok(()) -} diff --git a/zk_toolbox/crates/zk_inception/src/commands/ecosystem/init.rs b/zk_toolbox/crates/zk_inception/src/commands/ecosystem/init.rs index 7579a4ac6231..4fa6c8c47d8d 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/ecosystem/init.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/ecosystem/init.rs @@ -8,7 +8,7 @@ use common::{ cmd::Cmd, config::global_config, forge::{Forge, ForgeScriptArgs}, - logger, + git, logger, spinner::Spinner, Prompt, }; @@ -54,6 +54,8 @@ use crate::{ pub async fn run(args: EcosystemInitArgs, shell: &Shell) -> anyhow::Result<()> { let ecosystem_config = EcosystemConfig::from_file(shell)?; + git::submodule_update(shell, ecosystem_config.link_to_code.clone())?; + let initial_deployment_config = match ecosystem_config.get_initial_deployment_config() { Ok(config) => config, Err(_) => create_initial_deployments_config(shell, &ecosystem_config.config)?, diff --git a/zk_toolbox/crates/zk_inception/src/commands/prover/init_bellman_cuda.rs b/zk_toolbox/crates/zk_inception/src/commands/prover/init_bellman_cuda.rs index fd8efcd6eeb8..c6c5d3ef23d9 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/prover/init_bellman_cuda.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/prover/init_bellman_cuda.rs @@ -1,5 +1,5 @@ use anyhow::Context; -use common::{check_prover_prequisites, cmd::Cmd, logger, spinner::Spinner}; +use common::{check_prover_prequisites, cmd::Cmd, git, logger, spinner::Spinner}; use config::{traits::SaveConfigWithBasePath, EcosystemConfig}; use xshell::{cmd, Shell}; @@ -38,19 +38,15 @@ pub(crate) async fn run(shell: &Shell, args: InitBellmanCudaArgs) -> anyhow::Res fn clone_bellman_cuda(shell: &Shell) -> anyhow::Result { let spinner = Spinner::new(MSG_CLONING_BELLMAN_CUDA_SPINNER); - Cmd::new(cmd!( + let path = git::clone( shell, - "git clone https://github.com/matter-labs/era-bellman-cuda" - )) - .run()?; + shell.current_dir(), + "https://github.com/matter-labs/era-bellman-cuda", + BELLMAN_CUDA_DIR, + )?; spinner.finish(); - Ok(shell - .current_dir() - .join(BELLMAN_CUDA_DIR) - .to_str() - .context(MSG_BELLMAN_CUDA_DIR_ERR)? - .to_string()) + Ok(path.to_str().context(MSG_BELLMAN_CUDA_DIR_ERR)?.to_string()) } fn build_bellman_cuda(shell: &Shell, bellman_cuda_dir: &str) -> anyhow::Result<()> { From ec8cd4cb15141100b27e6fa5ebe0dc411238a185 Mon Sep 17 00:00:00 2001 From: matias-gonz Date: Wed, 10 Jul 2024 14:57:05 +0200 Subject: [PATCH 02/21] Add contract verifier support for zk toolbox --- .../src/commands/contract_verifier.rs | 27 +++++++++++++++++++ .../crates/zk_inception/src/commands/mod.rs | 1 + .../zk_inception/src/commands/prover/run.rs | 2 +- zk_toolbox/crates/zk_inception/src/main.rs | 3 +++ .../crates/zk_inception/src/messages.rs | 4 +++ 5 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 zk_toolbox/crates/zk_inception/src/commands/contract_verifier.rs diff --git a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier.rs b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier.rs new file mode 100644 index 000000000000..c8fa2dd82b5f --- /dev/null +++ b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier.rs @@ -0,0 +1,27 @@ +use anyhow::Context; +use common::{cmd::Cmd, logger}; +use config::EcosystemConfig; +use xshell::{cmd, Shell}; + +use crate::messages::{ + MSG_CHAIN_NOT_FOUND_ERR, MSG_FAILED_TO_RUN_CONTRACT_VERIFIER_ERR, MSG_RUNNING_CONTRACT_VERIFIER, +}; + +pub(crate) async fn run(shell: &Shell) -> anyhow::Result<()> { + let ecosystem = EcosystemConfig::from_file(shell)?; + let chain = ecosystem + .load_chain(Some(ecosystem.default_chain.clone())) + .context(MSG_CHAIN_NOT_FOUND_ERR)?; + + let config_path = chain.path_to_general_config(); + let secrets_path = chain.path_to_secrets_config(); + + let _dir_guard = shell.push_dir(&chain.link_to_code); + + logger::info(MSG_RUNNING_CONTRACT_VERIFIER); + + Cmd::new(cmd!( + shell, + "cargo run --bin zksync_contract_verifier -- --config-path={config_path} --secrets-path={secrets_path}" + )).run().context(MSG_FAILED_TO_RUN_CONTRACT_VERIFIER_ERR) +} diff --git a/zk_toolbox/crates/zk_inception/src/commands/mod.rs b/zk_toolbox/crates/zk_inception/src/commands/mod.rs index db34e1d8647d..5cba51265981 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/mod.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/mod.rs @@ -1,6 +1,7 @@ pub mod args; pub mod chain; pub mod containers; +pub mod contract_verifier; pub mod ecosystem; pub mod external_node; pub mod prover; diff --git a/zk_toolbox/crates/zk_inception/src/commands/prover/run.rs b/zk_toolbox/crates/zk_inception/src/commands/prover/run.rs index f91e992f1fdc..898cf0e45d66 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/prover/run.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/prover/run.rs @@ -16,6 +16,7 @@ use crate::messages::{ }; pub(crate) async fn run(args: ProverRunArgs, shell: &Shell) -> anyhow::Result<()> { + check_prover_prequisites(shell); let args = args.fill_values_with_prompt()?; let ecosystem_config = EcosystemConfig::from_file(shell)?; let chain = ecosystem_config @@ -42,7 +43,6 @@ pub(crate) async fn run(args: ProverRunArgs, shell: &Shell) -> anyhow::Result<() } fn run_gateway(shell: &Shell, chain: &ChainConfig) -> anyhow::Result<()> { - check_prover_prequisites(shell); logger::info(MSG_RUNNING_PROVER_GATEWAY); let config_path = chain.path_to_general_config(); let secrets_path = chain.path_to_secrets_config(); diff --git a/zk_toolbox/crates/zk_inception/src/main.rs b/zk_toolbox/crates/zk_inception/src/main.rs index 0f8ade3690a8..df80fc3406e7 100644 --- a/zk_toolbox/crates/zk_inception/src/main.rs +++ b/zk_toolbox/crates/zk_inception/src/main.rs @@ -48,6 +48,8 @@ pub enum InceptionSubcommands { ExternalNode(ExternalNodeCommands), /// Run containers for local development Containers, + /// Run contract verifier + ContractVerifier, } #[derive(Parser, Debug)] @@ -102,6 +104,7 @@ async fn run_subcommand(inception_args: Inception, shell: &Shell) -> anyhow::Res InceptionSubcommands::ExternalNode(args) => { commands::external_node::run(shell, args).await? } + InceptionSubcommands::ContractVerifier => commands::contract_verifier::run(shell).await?, } Ok(()) } diff --git a/zk_toolbox/crates/zk_inception/src/messages.rs b/zk_toolbox/crates/zk_inception/src/messages.rs index 7e27a9ac366d..40628b16ee1f 100644 --- a/zk_toolbox/crates/zk_inception/src/messages.rs +++ b/zk_toolbox/crates/zk_inception/src/messages.rs @@ -275,3 +275,7 @@ pub(super) const MSG_BELLMAN_CUDA_SELECTION_PATH: &str = "I have the code alread pub(super) fn msg_bucket_created(bucket_name: &str) -> String { format!("Bucket created successfully with url: gs://{bucket_name}") } + +/// Contract verifier related messages +pub(super) const MSG_RUNNING_CONTRACT_VERIFIER: &str = "Running contract verifier"; +pub(super) const MSG_FAILED_TO_RUN_CONTRACT_VERIFIER_ERR: &str = "Failed to run contract verifier"; From 00c921848bb60393becf87ed3c90f37d866251fe Mon Sep 17 00:00:00 2001 From: matias-gonz Date: Wed, 10 Jul 2024 15:48:58 +0200 Subject: [PATCH 03/21] Move contract verifier command into subcommand --- .../src/commands/contract_verifier/init.rs | 0 .../src/commands/contract_verifier/mod.rs | 16 ++++++++++++++++ .../run.rs} | 0 zk_toolbox/crates/zk_inception/src/main.rs | 8 ++++++-- 4 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs create mode 100644 zk_toolbox/crates/zk_inception/src/commands/contract_verifier/mod.rs rename zk_toolbox/crates/zk_inception/src/commands/{contract_verifier.rs => contract_verifier/run.rs} (100%) diff --git a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/mod.rs b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/mod.rs new file mode 100644 index 000000000000..9b8ce1648410 --- /dev/null +++ b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/mod.rs @@ -0,0 +1,16 @@ +use clap::Subcommand; +use xshell::Shell; + +pub mod run; + +#[derive(Subcommand, Debug)] +pub enum ContractVerifierCommands { + /// Run contract verifier + Run, +} + +pub(crate) async fn run(shell: &Shell, args: ContractVerifierCommands) -> anyhow::Result<()> { + match args { + ContractVerifierCommands::Run => run::run(shell).await, + } +} diff --git a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier.rs b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/run.rs similarity index 100% rename from zk_toolbox/crates/zk_inception/src/commands/contract_verifier.rs rename to zk_toolbox/crates/zk_inception/src/commands/contract_verifier/run.rs diff --git a/zk_toolbox/crates/zk_inception/src/main.rs b/zk_toolbox/crates/zk_inception/src/main.rs index df80fc3406e7..de6ebb52aaea 100644 --- a/zk_toolbox/crates/zk_inception/src/main.rs +++ b/zk_toolbox/crates/zk_inception/src/main.rs @@ -1,4 +1,5 @@ use clap::{command, Parser, Subcommand}; +use commands::contract_verifier::ContractVerifierCommands; use common::{ check_general_prerequisites, config::{global_config, init_global_config, GlobalConfig}, @@ -49,7 +50,8 @@ pub enum InceptionSubcommands { /// Run containers for local development Containers, /// Run contract verifier - ContractVerifier, + #[command(subcommand)] + ContractVerifier(ContractVerifierCommands), } #[derive(Parser, Debug)] @@ -104,7 +106,9 @@ async fn run_subcommand(inception_args: Inception, shell: &Shell) -> anyhow::Res InceptionSubcommands::ExternalNode(args) => { commands::external_node::run(shell, args).await? } - InceptionSubcommands::ContractVerifier => commands::contract_verifier::run(shell).await?, + InceptionSubcommands::ContractVerifier(args) => { + commands::contract_verifier::run(shell, args).await? + } } Ok(()) } From f8a71190744d10fc4260b966c2962426dc4ac9aa Mon Sep 17 00:00:00 2001 From: matias-gonz Date: Wed, 10 Jul 2024 17:28:34 +0200 Subject: [PATCH 04/21] Add get_zksolc_releases --- .../commands/contract_verifier/args/init.rs | 155 ++++++++++++++++++ .../commands/contract_verifier/args/mod.rs | 1 + .../src/commands/contract_verifier/init.rs | 8 + .../src/commands/contract_verifier/mod.rs | 5 + .../crates/zk_inception/src/messages.rs | 8 + 5 files changed, 177 insertions(+) create mode 100644 zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/init.rs create mode 100644 zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/mod.rs diff --git a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/init.rs b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/init.rs new file mode 100644 index 000000000000..04cae0d7afc9 --- /dev/null +++ b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/init.rs @@ -0,0 +1,155 @@ +use std::str::FromStr; + +use anyhow::Context; +use clap::{Parser, ValueEnum}; +use common::{cmd::Cmd, spinner::Spinner, PromptSelect}; +use strum::IntoEnumIterator; +use xshell::{cmd, Shell}; + +use crate::messages::{ + MSG_ARCH_SLECTION_PROMPT, MSG_FETCHING_ZKSOLC_RELEASES_SPINNER, MSG_GET_ZKSOLC_RELEASES_ERR, + MSG_INVALID_ARCH_ERR, MSG_NO_RELEASES_FOUND_ERR, MSG_NO_VERSION_FOUND_ERR, + MSG_ZKSOLC_VERSION_PROMPT, +}; + +#[derive(Debug, Clone, Parser, Default)] +pub struct InitContractVerifierArgs { + /// Version of zksolc to install + #[clap(long)] + pub version: Option, + /// Architecture of zksolc to install + #[clap(long)] + pub arch: Option, +} + +#[derive(Debug, Clone)] +pub struct InitContractVerifierArgsFinal { + pub zksolc_version: ZkSolcVersion, +} + +#[derive(Debug, Clone)] +pub struct ZkSolcVersion { + pub version: String, + pub arch: Arch, + pub url: String, +} + +#[derive(Debug, Clone, ValueEnum, strum::EnumIter, PartialEq, Eq, Copy)] +pub enum Arch { + LinuxAmd, + LinuxArm, + MacosAmd, + MacosArm, + WindowsAmd, +} + +impl std::fmt::Display for Arch { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Arch::LinuxAmd => write!(f, "linux-amd64"), + Arch::LinuxArm => write!(f, "linux-arm64"), + Arch::MacosAmd => write!(f, "macos-amd64"), + Arch::MacosArm => write!(f, "macos-arm64"), + Arch::WindowsAmd => write!(f, "windows-amd64"), + } + } +} + +impl std::str::FromStr for Arch { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + if s.contains("linux-amd64") { + Ok(Arch::LinuxAmd) + } else if s.contains("linux-arm64") { + Ok(Arch::LinuxArm) + } else if s.contains("macosx-amd64") { + Ok(Arch::MacosAmd) + } else if s.contains("macosx-arm64") { + Ok(Arch::MacosArm) + } else if s.contains("windows-amd64") { + Ok(Arch::WindowsAmd) + } else { + Err(anyhow::anyhow!(MSG_INVALID_ARCH_ERR)) + } + } +} + +impl InitContractVerifierArgs { + pub fn fill_values_with_prompt( + self, + shell: &Shell, + ) -> anyhow::Result { + let spinner = Spinner::new(MSG_FETCHING_ZKSOLC_RELEASES_SPINNER); + let releases = get_zksolc_releases(shell)?; + spinner.finish(); + + let arch = self + .arch + .unwrap_or_else(|| PromptSelect::new(MSG_ARCH_SLECTION_PROMPT, Arch::iter()).ask()); + + let releases = releases + .into_iter() + .filter(|r| r.arch == arch) + .collect::>(); + + if releases.is_empty() { + anyhow::bail!(MSG_NO_RELEASES_FOUND_ERR); + } + + let version = self.version.unwrap_or_else(|| { + PromptSelect::new( + MSG_ZKSOLC_VERSION_PROMPT, + releases.iter().map(|r| &r.version), + ) + .ask() + .into() + }); + + let zksolc_version = releases + .iter() + .find(|r| r.version == version) + .context(MSG_NO_VERSION_FOUND_ERR)? + .to_owned(); + + Ok(InitContractVerifierArgsFinal { zksolc_version }) + } +} + +fn get_zksolc_releases(shell: &Shell) -> anyhow::Result> { + let response: std::process::Output = Cmd::new(cmd!( + shell, + "curl https://api.github.com/repos/matter-labs/zksolc-bin/releases" + )) + .run_with_output()?; + let response = String::from_utf8(response.stdout)?; + let response: serde_json::Value = serde_json::from_str(&response)?; + + let mut releases = vec![]; + + for r in response.as_array().context(MSG_GET_ZKSOLC_RELEASES_ERR)? { + let version = r["name"] + .as_str() + .context(MSG_GET_ZKSOLC_RELEASES_ERR)? + .to_string(); + let assets = r["assets"] + .as_array() + .context(MSG_GET_ZKSOLC_RELEASES_ERR)?; + for a in assets.iter() { + let arch = ::from_str( + a["name"].as_str().context(MSG_GET_ZKSOLC_RELEASES_ERR)?, + )?; + let url = a["browser_download_url"] + .as_str() + .context(MSG_GET_ZKSOLC_RELEASES_ERR)? + .to_string(); + releases.push(ZkSolcVersion { + version: version.clone(), + arch, + url, + }); + } + } + + Ok(releases) +} diff --git a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/mod.rs b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/mod.rs new file mode 100644 index 000000000000..43763f10a418 --- /dev/null +++ b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/mod.rs @@ -0,0 +1 @@ +pub mod init; diff --git a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs index e69de29bb2d1..f3e12719771d 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs @@ -0,0 +1,8 @@ +use xshell::Shell; + +use super::args::init::InitContractVerifierArgs; + +pub(crate) async fn run(shell: &Shell, args: InitContractVerifierArgs) -> anyhow::Result<()> { + args.fill_values_with_prompt(shell)?; + Ok(()) +} diff --git a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/mod.rs b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/mod.rs index 9b8ce1648410..2f6f8192912e 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/mod.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/mod.rs @@ -1,16 +1,21 @@ +use args::init::InitContractVerifierArgs; use clap::Subcommand; use xshell::Shell; +pub mod args; +pub mod init; pub mod run; #[derive(Subcommand, Debug)] pub enum ContractVerifierCommands { /// Run contract verifier Run, + Init(InitContractVerifierArgs), } pub(crate) async fn run(shell: &Shell, args: ContractVerifierCommands) -> anyhow::Result<()> { match args { ContractVerifierCommands::Run => run::run(shell).await, + ContractVerifierCommands::Init(args) => init::run(shell, args).await, } } diff --git a/zk_toolbox/crates/zk_inception/src/messages.rs b/zk_toolbox/crates/zk_inception/src/messages.rs index 40628b16ee1f..50d92d3dcd92 100644 --- a/zk_toolbox/crates/zk_inception/src/messages.rs +++ b/zk_toolbox/crates/zk_inception/src/messages.rs @@ -279,3 +279,11 @@ pub(super) fn msg_bucket_created(bucket_name: &str) -> String { /// Contract verifier related messages pub(super) const MSG_RUNNING_CONTRACT_VERIFIER: &str = "Running contract verifier"; pub(super) const MSG_FAILED_TO_RUN_CONTRACT_VERIFIER_ERR: &str = "Failed to run contract verifier"; +pub(super) const MSG_INVALID_ARCH_ERR: &str = "Invalid arch"; +pub(super) const MSG_GET_ZKSOLC_RELEASES_ERR: &str = "Failed to get zksolc releases"; +pub(super) const MSG_FETCHING_ZKSOLC_RELEASES_SPINNER: &str = "Fetching zksolc releases..."; +pub(super) const MSG_ARCH_SLECTION_PROMPT: &str = "Select your architecture:"; +pub(super) const MSG_ZKSOLC_VERSION_PROMPT: &str = "Select the zksolc version:"; +pub(super) const MSG_NO_RELEASES_FOUND_ERR: &str = + "No releases found for the selected architecture"; +pub(super) const MSG_NO_VERSION_FOUND_ERR: &str = "No version found"; From 868bd59e0bc086c151f30ec0bec8833863cdce06 Mon Sep 17 00:00:00 2001 From: Danil Date: Wed, 10 Jul 2024 18:49:02 +0200 Subject: [PATCH 05/21] add aliases Signed-off-by: Danil --- core/lib/contracts/src/lib.rs | 4 ++-- zk_toolbox/crates/common/src/cmd.rs | 2 +- .../crates/zk_inception/src/commands/chain/init.rs | 9 --------- zk_toolbox/crates/zk_inception/src/commands/chain/mod.rs | 2 ++ .../crates/zk_inception/src/commands/ecosystem/mod.rs | 1 + .../crates/zk_inception/src/commands/prover/mod.rs | 2 ++ zk_toolbox/crates/zk_inception/src/main.rs | 9 +++++---- zk_toolbox/crates/zk_supervisor/src/commands/test/mod.rs | 4 ++-- zk_toolbox/crates/zk_supervisor/src/main.rs | 4 ++-- 9 files changed, 17 insertions(+), 20 deletions(-) diff --git a/core/lib/contracts/src/lib.rs b/core/lib/contracts/src/lib.rs index 3374631a1814..b431085aad0b 100644 --- a/core/lib/contracts/src/lib.rs +++ b/core/lib/contracts/src/lib.rs @@ -39,8 +39,8 @@ const STATE_TRANSITION_CONTRACT_FILE: (&str, &str) = ( "IStateTransitionManager.sol/IStateTransitionManager.json", ); const ZKSYNC_HYPERCHAIN_CONTRACT_FILE: (&str, &str) = ( - "state-transition/", - "chain-interfaces/IZkSyncHyperchain.sol/IZkSyncHyperchain.json", + "state-transition/chain-interfaces", + "IZkSyncHyperchain.sol/IZkSyncHyperchain.json", ); const DIAMOND_INIT_CONTRACT_FILE: (&str, &str) = ( "state-transition", diff --git a/zk_toolbox/crates/common/src/cmd.rs b/zk_toolbox/crates/common/src/cmd.rs index a0a4b7d10ba9..128196b8a9d7 100644 --- a/zk_toolbox/crates/common/src/cmd.rs +++ b/zk_toolbox/crates/common/src/cmd.rs @@ -148,7 +148,7 @@ fn check_output_status(command_text: &str, output: &std::process::Output) -> Cmd fn run_low_level_process_command(mut command: Command) -> io::Result { command.stdout(Stdio::inherit()); - command.stderr(Stdio::piped()); + command.stderr(Stdio::inherit()); let child = command.spawn()?; child.wait_with_output() } diff --git a/zk_toolbox/crates/zk_inception/src/commands/chain/init.rs b/zk_toolbox/crates/zk_inception/src/commands/chain/init.rs index 69233a94e45f..9732a5cc024c 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/chain/init.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/chain/init.rs @@ -58,7 +58,6 @@ pub async fn init( chain_config: &ChainConfig, ) -> anyhow::Result<()> { copy_configs(shell, &ecosystem_config.link_to_code, &chain_config.configs)?; - build_l1_contracts(shell, ecosystem_config)?; let mut genesis_config = chain_config.get_genesis_config()?; genesis_config.update_from_chain_config(chain_config); @@ -162,11 +161,3 @@ async fn register_chain( contracts.set_chain_contracts(®ister_chain_output); Ok(()) } - -fn build_l1_contracts(shell: &Shell, ecosystem_config: &EcosystemConfig) -> anyhow::Result<()> { - let _dir_guard = shell.push_dir(ecosystem_config.path_to_foundry()); - let spinner = Spinner::new(MSG_BUILDING_L1_CONTRACTS); - Cmd::new(cmd!(shell, "yarn build")).run()?; - spinner.finish(); - Ok(()) -} diff --git a/zk_toolbox/crates/zk_inception/src/commands/chain/mod.rs b/zk_toolbox/crates/zk_inception/src/commands/chain/mod.rs index aabb0d714c53..fa4f81d76312 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/chain/mod.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/chain/mod.rs @@ -22,8 +22,10 @@ pub enum ChainCommands { /// Run server genesis Genesis(GenesisArgs), /// Initialize bridges on l2 + #[command(alias = "bridge")] InitializeBridges(ForgeScriptArgs), /// Initialize bridges on l2 + #[command(alias = "paymaster")] DeployPaymaster(ForgeScriptArgs), } diff --git a/zk_toolbox/crates/zk_inception/src/commands/ecosystem/mod.rs b/zk_toolbox/crates/zk_inception/src/commands/ecosystem/mod.rs index e4074ed3070b..1e4b4f9bd2af 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/ecosystem/mod.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/ecosystem/mod.rs @@ -21,6 +21,7 @@ pub enum EcosystemCommands { /// deploying necessary contracts and performing on-chain operations Init(EcosystemInitArgs), /// Change the default chain + #[command(alias = "cd")] ChangeDefaultChain(ChangeDefaultChain), } diff --git a/zk_toolbox/crates/zk_inception/src/commands/prover/mod.rs b/zk_toolbox/crates/zk_inception/src/commands/prover/mod.rs index d69e1e772e91..31c3a02e3806 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/prover/mod.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/prover/mod.rs @@ -15,10 +15,12 @@ pub enum ProverCommands { /// Initialize prover Init(Box), /// Generate setup keys + #[command(alias = "sk")] GenerateSK, /// Run prover Run(ProverRunArgs), /// Initialize bellman-cuda + #[command(alias = "cuda")] InitBellmanCuda(Box), } diff --git a/zk_toolbox/crates/zk_inception/src/main.rs b/zk_toolbox/crates/zk_inception/src/main.rs index 0f8ade3690a8..741d6df12e4e 100644 --- a/zk_toolbox/crates/zk_inception/src/main.rs +++ b/zk_toolbox/crates/zk_inception/src/main.rs @@ -33,20 +33,21 @@ struct Inception { #[derive(Subcommand, Debug)] pub enum InceptionSubcommands { /// Ecosystem related commands - #[command(subcommand)] + #[command(subcommand, alias = "e")] Ecosystem(EcosystemCommands), /// Chain related commands - #[command(subcommand)] + #[command(subcommand, alias = "c")] Chain(ChainCommands), /// Prover related commands - #[command(subcommand)] + #[command(subcommand, alias = "p")] Prover(ProverCommands), /// Run server Server(RunServerArgs), // Run External Node - #[command(subcommand)] + #[command(subcommand, alias = "en")] ExternalNode(ExternalNodeCommands), /// Run containers for local development + #[command(subcommand, alias = "up")] Containers, } diff --git a/zk_toolbox/crates/zk_supervisor/src/commands/test/mod.rs b/zk_toolbox/crates/zk_supervisor/src/commands/test/mod.rs index c930ab0cc0e2..857190dba3b0 100644 --- a/zk_toolbox/crates/zk_supervisor/src/commands/test/mod.rs +++ b/zk_toolbox/crates/zk_supervisor/src/commands/test/mod.rs @@ -10,9 +10,9 @@ mod revert; #[derive(Subcommand, Debug)] pub enum TestCommands { - #[clap(about = MSG_INTEGRATION_TESTS_ABOUT)] + #[clap(about = MSG_INTEGRATION_TESTS_ABOUT, alias = "i")] Integration(IntegrationArgs), - #[clap(about = MSG_REVERT_TEST_ABOUT)] + #[clap(about = MSG_REVERT_TEST_ABOUT, alias = "r")] Revert(RevertArgs), } diff --git a/zk_toolbox/crates/zk_supervisor/src/main.rs b/zk_toolbox/crates/zk_supervisor/src/main.rs index 17ad5c577996..d6cc82c0994d 100644 --- a/zk_toolbox/crates/zk_supervisor/src/main.rs +++ b/zk_toolbox/crates/zk_supervisor/src/main.rs @@ -30,9 +30,9 @@ struct Supervisor { #[derive(Subcommand, Debug)] enum SupervisorSubcommands { - #[command(subcommand, about = MSG_SUBCOMMAND_DATABASE_ABOUT)] + #[command(subcommand, about = MSG_SUBCOMMAND_DATABASE_ABOUT, alias = "db")] Database(DatabaseCommands), - #[command(subcommand, about = MSG_SUBCOMMAND_TESTS_ABOUT)] + #[command(subcommand, about = MSG_SUBCOMMAND_TESTS_ABOUT, alias = "t")] Test(TestCommands), #[command(subcommand, about = MSG_SUBCOMMAND_CLEAN)] Clean(CleanCommands), From 529df72eb0f86a1ebb6fbc9049327441a4b16983 Mon Sep 17 00:00:00 2001 From: Danil Date: Wed, 10 Jul 2024 19:23:01 +0200 Subject: [PATCH 06/21] Remove build l1 contract Signed-off-by: Danil --- .../crates/zk_inception/src/commands/chain/init.rs | 9 ++++----- zk_toolbox/crates/zk_inception/src/messages.rs | 1 - 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/zk_toolbox/crates/zk_inception/src/commands/chain/init.rs b/zk_toolbox/crates/zk_inception/src/commands/chain/init.rs index 9732a5cc024c..985885f30fe4 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/chain/init.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/chain/init.rs @@ -1,6 +1,5 @@ use anyhow::Context; use common::{ - cmd::Cmd, config::global_config, forge::{Forge, ForgeScriptArgs}, git, logger, @@ -15,7 +14,7 @@ use config::{ traits::{ReadConfig, SaveConfig, SaveConfigWithBasePath}, ChainConfig, ContractsConfig, EcosystemConfig, }; -use xshell::{cmd, Shell}; +use xshell::Shell; use crate::{ accept_ownership::accept_admin, @@ -26,9 +25,9 @@ use crate::{ initialize_bridges, }, messages::{ - msg_initializing_chain, MSG_ACCEPTING_ADMIN_SPINNER, MSG_BUILDING_L1_CONTRACTS, - MSG_CHAIN_INITIALIZED, MSG_CHAIN_NOT_FOUND_ERR, MSG_GENESIS_DATABASE_ERR, - MSG_REGISTERING_CHAIN_SPINNER, MSG_SELECTED_CONFIG, + msg_initializing_chain, MSG_ACCEPTING_ADMIN_SPINNER, MSG_CHAIN_INITIALIZED, + MSG_CHAIN_NOT_FOUND_ERR, MSG_GENESIS_DATABASE_ERR, MSG_REGISTERING_CHAIN_SPINNER, + MSG_SELECTED_CONFIG, }, utils::forge::{check_the_balance, fill_forge_private_key}, }; diff --git a/zk_toolbox/crates/zk_inception/src/messages.rs b/zk_toolbox/crates/zk_inception/src/messages.rs index 7e27a9ac366d..b9d9f5f02418 100644 --- a/zk_toolbox/crates/zk_inception/src/messages.rs +++ b/zk_toolbox/crates/zk_inception/src/messages.rs @@ -185,7 +185,6 @@ pub(super) const MSG_FAILED_TO_FIND_ECOSYSTEM_ERR: &str = "Failed to find ecosys /// Server related messages pub(super) const MSG_STARTING_SERVER: &str = "Starting server"; pub(super) const MSG_FAILED_TO_RUN_SERVER_ERR: &str = "Failed to start server"; -pub(super) const MSG_BUILDING_L1_CONTRACTS: &str = "Building L1 contracts..."; pub(super) const MSG_PREPARING_EN_CONFIGS: &str = "Preparing External Node config"; /// Forge utils related messages From f429d333618e5e4079d07b14958395aca8970b49 Mon Sep 17 00:00:00 2001 From: Danil Date: Wed, 10 Jul 2024 19:28:00 +0200 Subject: [PATCH 07/21] Print stderr always Signed-off-by: Danil --- .github/workflows/ci-zk-toolbox-reusable.yml | 5 +++++ zk_toolbox/crates/common/src/cmd.rs | 10 ++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-zk-toolbox-reusable.yml b/.github/workflows/ci-zk-toolbox-reusable.yml index 102c3d56c331..7ff5eb3f1cf4 100644 --- a/.github/workflows/ci-zk-toolbox-reusable.yml +++ b/.github/workflows/ci-zk-toolbox-reusable.yml @@ -73,6 +73,7 @@ jobs: echo $(pwd)/bin >> $GITHUB_PATH echo IN_DOCKER=1 >> .env + - name: Start services run: | ci_localnet_up @@ -80,6 +81,10 @@ jobs: - name: Initialize ecosystem run: | + ci_run git config --global --add safe.directory /usr/src/zksync + ci_run git config --global --add safe.directory /usr/src/zksync/contracts/system-contracts + ci_run git config --global --add safe.directory /usr/src/zksync/contracts + ci_run zk_inception ecosystem init --deploy-paymaster --deploy-erc20 \ --deploy-ecosystem --l1-rpc-url=http://reth:8545 \ --server-db-url=postgres://postgres:notsecurepassword@postgres:5432 \ diff --git a/zk_toolbox/crates/common/src/cmd.rs b/zk_toolbox/crates/common/src/cmd.rs index 128196b8a9d7..ca0f285882a3 100644 --- a/zk_toolbox/crates/common/src/cmd.rs +++ b/zk_toolbox/crates/common/src/cmd.rs @@ -93,7 +93,13 @@ impl<'a> Cmd<'a> { let output = if global_config().verbose || self.force_run { logger::debug(format!("Running: {}", self.inner)); logger::new_empty_line(); - run_low_level_process_command(self.inner.into())? + let output = run_low_level_process_command(self.inner.into())?; + if let Ok(data) = String::from_utf8(output.stderr.clone()) { + if !data.is_empty() { + logger::info(data) + } + } + output } else { // Command will be logged manually. self.inner.set_quiet(true); @@ -148,7 +154,7 @@ fn check_output_status(command_text: &str, output: &std::process::Output) -> Cmd fn run_low_level_process_command(mut command: Command) -> io::Result { command.stdout(Stdio::inherit()); - command.stderr(Stdio::inherit()); + command.stderr(Stdio::piped()); let child = command.spawn()?; child.wait_with_output() } From 5b4e634d7d5672fb846cafca120ae102e5380b93 Mon Sep 17 00:00:00 2001 From: Danil Date: Thu, 11 Jul 2024 10:22:24 +0200 Subject: [PATCH 08/21] Improve error messages from Daniels pr Signed-off-by: Danil --- zk_toolbox/crates/config/src/ecosystem.rs | 11 +++++++---- .../zk_inception/src/commands/ecosystem/create.rs | 2 +- zk_toolbox/crates/zk_inception/src/messages.rs | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/zk_toolbox/crates/config/src/ecosystem.rs b/zk_toolbox/crates/config/src/ecosystem.rs index de709c14f239..7a7456ded1cb 100644 --- a/zk_toolbox/crates/config/src/ecosystem.rs +++ b/zk_toolbox/crates/config/src/ecosystem.rs @@ -102,8 +102,10 @@ impl EcosystemConfig { pub fn from_file(shell: &Shell) -> Result { let path = PathBuf::from(CONFIG_NAME); - if !shell.path_exists(path) { - return Err(EcosystemConfigFromFileError::NotExists); + if !shell.path_exists(&path) { + return Err(EcosystemConfigFromFileError::NotExists { + path: shell.current_dir(), + }); } let mut config = EcosystemConfig::read(shell, CONFIG_NAME) @@ -229,8 +231,9 @@ impl EcosystemConfig { /// Result of checking if the ecosystem exists. #[derive(Error, Debug)] pub enum EcosystemConfigFromFileError { - #[error("Ecosystem configuration not found")] - NotExists, + #[error("Ecosystem configuration not found (Could not find 'ZkStack.toml' in {path:?}: Make sure you have created an ecosystem & are in the new folder `cd path/to/ecosystem/name`)" + )] + NotExists { path: PathBuf }, #[error("Invalid ecosystem configuration")] InvalidConfig { source: anyhow::Error }, } diff --git a/zk_toolbox/crates/zk_inception/src/commands/ecosystem/create.rs b/zk_toolbox/crates/zk_inception/src/commands/ecosystem/create.rs index 0514c0918040..e4b06154e37e 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/ecosystem/create.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/ecosystem/create.rs @@ -32,7 +32,7 @@ pub fn run(args: EcosystemCreateArgs, shell: &Shell) -> anyhow::Result<()> { Err(EcosystemConfigFromFileError::InvalidConfig { .. }) => { bail!(MSG_ECOSYSTEM_CONFIG_INVALID_ERR) } - Err(EcosystemConfigFromFileError::NotExists) => create(args, shell)?, + Err(EcosystemConfigFromFileError::NotExists { .. }) => create(args, shell)?, }; Ok(()) diff --git a/zk_toolbox/crates/zk_inception/src/messages.rs b/zk_toolbox/crates/zk_inception/src/messages.rs index b9d9f5f02418..c98f76b751c8 100644 --- a/zk_toolbox/crates/zk_inception/src/messages.rs +++ b/zk_toolbox/crates/zk_inception/src/messages.rs @@ -22,7 +22,7 @@ pub(super) const MSG_L1_NETWORK_PROMPT: &str = "Select the L1 network"; pub(super) const MSG_START_CONTAINERS_PROMPT: &str = "Do you want to start containers after creating the ecosystem?"; pub(super) const MSG_CREATING_ECOSYSTEM: &str = "Creating ecosystem"; -pub(super) const MSG_CREATED_ECOSYSTEM: &str = "Ecosystem created successfully"; +pub(super) const MSG_CREATED_ECOSYSTEM: &str = "Ecosystem created successfully (All subsequent commands should be executed from ecosystem folder `cd path/to/ecosystem/name`)"; pub(super) const MSG_CLONING_ERA_REPO_SPINNER: &str = "Cloning zksync-era repository..."; pub(super) const MSG_CREATING_INITIAL_CONFIGURATIONS_SPINNER: &str = "Creating initial configurations..."; From 14e8293ff6336711947a302f1ed277faad619305 Mon Sep 17 00:00:00 2001 From: matias-gonz Date: Thu, 11 Jul 2024 11:36:23 +0200 Subject: [PATCH 09/21] Refactor get_zksolc_releases --- .../commands/contract_verifier/args/init.rs | 129 ++++-------------- .../commands/contract_verifier/args/mod.rs | 1 + .../contract_verifier/args/zksolc_releases.rs | 83 +++++++++++ .../crates/zk_inception/src/messages.rs | 6 +- 4 files changed, 117 insertions(+), 102 deletions(-) create mode 100644 zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/zksolc_releases.rs diff --git a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/init.rs b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/init.rs index 04cae0d7afc9..5a541b023076 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/init.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/init.rs @@ -1,25 +1,21 @@ -use std::str::FromStr; - use anyhow::Context; -use clap::{Parser, ValueEnum}; -use common::{cmd::Cmd, spinner::Spinner, PromptSelect}; -use strum::IntoEnumIterator; -use xshell::{cmd, Shell}; +use clap::Parser; +use common::{spinner::Spinner, PromptSelect}; +use xshell::Shell; use crate::messages::{ - MSG_ARCH_SLECTION_PROMPT, MSG_FETCHING_ZKSOLC_RELEASES_SPINNER, MSG_GET_ZKSOLC_RELEASES_ERR, - MSG_INVALID_ARCH_ERR, MSG_NO_RELEASES_FOUND_ERR, MSG_NO_VERSION_FOUND_ERR, + MSG_ARCH_NOT_SUPPORTED_ERR, MSG_FETCHING_ZKSOLC_RELEASES_SPINNER, MSG_GET_ZKSOLC_RELEASES_ERR, + MSG_NO_RELEASES_FOUND_ERR, MSG_NO_VERSION_FOUND_ERR, MSG_OS_NOT_SUPPORTED_ERR, MSG_ZKSOLC_VERSION_PROMPT, }; +use super::zksolc_releases::{get_zksolc_releases, Arch, ZkSolcVersion}; + #[derive(Debug, Clone, Parser, Default)] pub struct InitContractVerifierArgs { /// Version of zksolc to install #[clap(long)] pub version: Option, - /// Architecture of zksolc to install - #[clap(long)] - pub arch: Option, } #[derive(Debug, Clone)] @@ -27,66 +23,16 @@ pub struct InitContractVerifierArgsFinal { pub zksolc_version: ZkSolcVersion, } -#[derive(Debug, Clone)] -pub struct ZkSolcVersion { - pub version: String, - pub arch: Arch, - pub url: String, -} - -#[derive(Debug, Clone, ValueEnum, strum::EnumIter, PartialEq, Eq, Copy)] -pub enum Arch { - LinuxAmd, - LinuxArm, - MacosAmd, - MacosArm, - WindowsAmd, -} - -impl std::fmt::Display for Arch { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Arch::LinuxAmd => write!(f, "linux-amd64"), - Arch::LinuxArm => write!(f, "linux-arm64"), - Arch::MacosAmd => write!(f, "macos-amd64"), - Arch::MacosArm => write!(f, "macos-arm64"), - Arch::WindowsAmd => write!(f, "windows-amd64"), - } - } -} - -impl std::str::FromStr for Arch { - type Err = anyhow::Error; - - fn from_str(s: &str) -> Result { - if s.contains("linux-amd64") { - Ok(Arch::LinuxAmd) - } else if s.contains("linux-arm64") { - Ok(Arch::LinuxArm) - } else if s.contains("macosx-amd64") { - Ok(Arch::MacosAmd) - } else if s.contains("macosx-arm64") { - Ok(Arch::MacosArm) - } else if s.contains("windows-amd64") { - Ok(Arch::WindowsAmd) - } else { - Err(anyhow::anyhow!(MSG_INVALID_ARCH_ERR)) - } - } -} - impl InitContractVerifierArgs { pub fn fill_values_with_prompt( self, shell: &Shell, ) -> anyhow::Result { let spinner = Spinner::new(MSG_FETCHING_ZKSOLC_RELEASES_SPINNER); - let releases = get_zksolc_releases(shell)?; + let releases = get_zksolc_releases(shell).context(MSG_GET_ZKSOLC_RELEASES_ERR)?; spinner.finish(); - let arch = self - .arch - .unwrap_or_else(|| PromptSelect::new(MSG_ARCH_SLECTION_PROMPT, Arch::iter()).ask()); + let arch = get_arch()?; let releases = releases .into_iter() @@ -116,40 +62,25 @@ impl InitContractVerifierArgs { } } -fn get_zksolc_releases(shell: &Shell) -> anyhow::Result> { - let response: std::process::Output = Cmd::new(cmd!( - shell, - "curl https://api.github.com/repos/matter-labs/zksolc-bin/releases" - )) - .run_with_output()?; - let response = String::from_utf8(response.stdout)?; - let response: serde_json::Value = serde_json::from_str(&response)?; - - let mut releases = vec![]; - - for r in response.as_array().context(MSG_GET_ZKSOLC_RELEASES_ERR)? { - let version = r["name"] - .as_str() - .context(MSG_GET_ZKSOLC_RELEASES_ERR)? - .to_string(); - let assets = r["assets"] - .as_array() - .context(MSG_GET_ZKSOLC_RELEASES_ERR)?; - for a in assets.iter() { - let arch = ::from_str( - a["name"].as_str().context(MSG_GET_ZKSOLC_RELEASES_ERR)?, - )?; - let url = a["browser_download_url"] - .as_str() - .context(MSG_GET_ZKSOLC_RELEASES_ERR)? - .to_string(); - releases.push(ZkSolcVersion { - version: version.clone(), - arch, - url, - }); - } - } - - Ok(releases) +fn get_arch() -> anyhow::Result { + let os = std::env::consts::OS; + let arch = std::env::consts::ARCH; + + let arch = match os { + "linux" => match arch { + "x86_64" => Arch::LinuxAmd, + "aarch64" => Arch::LinuxArm, + "arm" => Arch::LinuxArm, + _ => anyhow::bail!(MSG_ARCH_NOT_SUPPORTED_ERR), + }, + "macos" => match arch { + "x86_64" => Arch::MacosAmd, + "aarch64" => Arch::MacosArm, + "arm" => Arch::MacosArm, + _ => anyhow::bail!(MSG_ARCH_NOT_SUPPORTED_ERR), + }, + _ => anyhow::bail!(MSG_OS_NOT_SUPPORTED_ERR), + }; + + Ok(arch) } diff --git a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/mod.rs b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/mod.rs index 43763f10a418..6b13181f51b9 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/mod.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/mod.rs @@ -1 +1,2 @@ pub mod init; +pub mod zksolc_releases; diff --git a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/zksolc_releases.rs b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/zksolc_releases.rs new file mode 100644 index 000000000000..739a4b050a6f --- /dev/null +++ b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/zksolc_releases.rs @@ -0,0 +1,83 @@ +use std::str::FromStr; + +use common::cmd::Cmd; +use serde::Deserialize; +use xshell::{cmd, Shell}; + +use crate::messages::MSG_INVALID_ARCH_ERR; + +#[derive(Deserialize)] +struct GitHubRelease { + name: String, + assets: Vec, +} + +#[derive(Deserialize)] +struct GitHubAsset { + name: String, + browser_download_url: String, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ZkSolcVersion { + pub version: String, + pub arch: Arch, + pub url: String, +} + +#[derive(Debug, Clone, PartialEq, Eq, Copy)] +pub enum Arch { + LinuxAmd, + LinuxArm, + MacosAmd, + MacosArm, +} + +impl std::str::FromStr for Arch { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + if s.contains("linux-amd64") { + Ok(Arch::LinuxAmd) + } else if s.contains("linux-arm64") { + Ok(Arch::LinuxArm) + } else if s.contains("macosx-amd64") { + Ok(Arch::MacosAmd) + } else if s.contains("macosx-arm64") { + Ok(Arch::MacosArm) + } else { + Err(anyhow::anyhow!(MSG_INVALID_ARCH_ERR)) + } + } +} + +pub fn get_zksolc_releases(shell: &Shell) -> anyhow::Result> { + let response: std::process::Output = Cmd::new(cmd!( + shell, + "curl https://api.github.com/repos/matter-labs/zksolc-bin/releases" + )) + .run_with_output()?; + + let response = String::from_utf8(response.stdout)?; + let releases: Vec = serde_json::from_str(&response)?; + + let mut zk_solc_versions = vec![]; + + for release in releases { + let version = release.name; + for asset in release.assets { + let arch = match Arch::from_str(&asset.name) { + Ok(arch) => arch, + Err(_) => continue, + }; + let url = asset.browser_download_url; + zk_solc_versions.push(ZkSolcVersion { + version: version.clone(), + arch, + url, + }); + } + } + + Ok(zk_solc_versions) +} diff --git a/zk_toolbox/crates/zk_inception/src/messages.rs b/zk_toolbox/crates/zk_inception/src/messages.rs index 50d92d3dcd92..5c05abe2d1db 100644 --- a/zk_toolbox/crates/zk_inception/src/messages.rs +++ b/zk_toolbox/crates/zk_inception/src/messages.rs @@ -282,8 +282,8 @@ pub(super) const MSG_FAILED_TO_RUN_CONTRACT_VERIFIER_ERR: &str = "Failed to run pub(super) const MSG_INVALID_ARCH_ERR: &str = "Invalid arch"; pub(super) const MSG_GET_ZKSOLC_RELEASES_ERR: &str = "Failed to get zksolc releases"; pub(super) const MSG_FETCHING_ZKSOLC_RELEASES_SPINNER: &str = "Fetching zksolc releases..."; -pub(super) const MSG_ARCH_SLECTION_PROMPT: &str = "Select your architecture:"; pub(super) const MSG_ZKSOLC_VERSION_PROMPT: &str = "Select the zksolc version:"; -pub(super) const MSG_NO_RELEASES_FOUND_ERR: &str = - "No releases found for the selected architecture"; +pub(super) const MSG_NO_RELEASES_FOUND_ERR: &str = "No releases found for current architecture"; pub(super) const MSG_NO_VERSION_FOUND_ERR: &str = "No version found"; +pub(super) const MSG_ARCH_NOT_SUPPORTED_ERR: &str = "Architecture not supported"; +pub(super) const MSG_OS_NOT_SUPPORTED_ERR: &str = "OS not supported"; From c3d7c06d800c34f5742fbd4e099c3f5a70e54946 Mon Sep 17 00:00:00 2001 From: matias-gonz Date: Thu, 11 Jul 2024 12:44:27 +0200 Subject: [PATCH 10/21] Add Vyper version selection --- .../commands/contract_verifier/args/init.rs | 85 ++++++++++++------- .../commands/contract_verifier/args/mod.rs | 2 +- .../args/{zksolc_releases.rs => releases.rs} | 52 +++++++++--- .../crates/zk_inception/src/messages.rs | 3 + 4 files changed, 98 insertions(+), 44 deletions(-) rename zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/{zksolc_releases.rs => releases.rs} (54%) diff --git a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/init.rs b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/init.rs index 5a541b023076..1d6e079f7c74 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/init.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/init.rs @@ -1,26 +1,33 @@ use anyhow::Context; use clap::Parser; -use common::{spinner::Spinner, PromptSelect}; +use common::{ + spinner::{self, Spinner}, + PromptSelect, +}; use xshell::Shell; +use super::releases::{get_releases_with_arch, Arch, Version}; use crate::messages::{ - MSG_ARCH_NOT_SUPPORTED_ERR, MSG_FETCHING_ZKSOLC_RELEASES_SPINNER, MSG_GET_ZKSOLC_RELEASES_ERR, - MSG_NO_RELEASES_FOUND_ERR, MSG_NO_VERSION_FOUND_ERR, MSG_OS_NOT_SUPPORTED_ERR, + MSG_ARCH_NOT_SUPPORTED_ERR, MSG_FETCHING_VYPER_RELEASES_SPINNER, + MSG_FETCHING_ZKSOLC_RELEASES_SPINNER, MSG_GET_VYPER_RELEASES_ERR, MSG_GET_ZKSOLC_RELEASES_ERR, + MSG_NO_VERSION_FOUND_ERR, MSG_OS_NOT_SUPPORTED_ERR, MSG_VYPER_VERSION_PROMPT, MSG_ZKSOLC_VERSION_PROMPT, }; -use super::zksolc_releases::{get_zksolc_releases, Arch, ZkSolcVersion}; - #[derive(Debug, Clone, Parser, Default)] pub struct InitContractVerifierArgs { /// Version of zksolc to install #[clap(long)] - pub version: Option, + pub zksolc_version: Option, + /// Version of vyper to install + #[clap(long)] + pub vyper_version: Option, } #[derive(Debug, Clone)] pub struct InitContractVerifierArgsFinal { - pub zksolc_version: ZkSolcVersion, + pub zksolc_version: Version, + pub vyper_version: Version, } impl InitContractVerifierArgs { @@ -28,37 +35,31 @@ impl InitContractVerifierArgs { self, shell: &Shell, ) -> anyhow::Result { + let arch = get_arch()?; + let spinner = Spinner::new(MSG_FETCHING_ZKSOLC_RELEASES_SPINNER); - let releases = get_zksolc_releases(shell).context(MSG_GET_ZKSOLC_RELEASES_ERR)?; + let zksolc_releases = get_releases_with_arch(shell, "matter-labs/zksolc-bin", arch) + .context(MSG_GET_ZKSOLC_RELEASES_ERR)?; spinner.finish(); - let arch = get_arch()?; + let spinner = spinner::Spinner::new(MSG_FETCHING_VYPER_RELEASES_SPINNER); + let vyper_releases = get_releases_with_arch(shell, "vyperlang/vyper", arch) + .context(MSG_GET_VYPER_RELEASES_ERR)?; + spinner.finish(); - let releases = releases - .into_iter() - .filter(|r| r.arch == arch) - .collect::>(); + let zksolc_version = select_version( + self.zksolc_version, + zksolc_releases, + MSG_ZKSOLC_VERSION_PROMPT, + )?; - if releases.is_empty() { - anyhow::bail!(MSG_NO_RELEASES_FOUND_ERR); - } + let vyper_version = + select_version(self.vyper_version, vyper_releases, MSG_VYPER_VERSION_PROMPT)?; - let version = self.version.unwrap_or_else(|| { - PromptSelect::new( - MSG_ZKSOLC_VERSION_PROMPT, - releases.iter().map(|r| &r.version), - ) - .ask() - .into() - }); - - let zksolc_version = releases - .iter() - .find(|r| r.version == version) - .context(MSG_NO_VERSION_FOUND_ERR)? - .to_owned(); - - Ok(InitContractVerifierArgsFinal { zksolc_version }) + Ok(InitContractVerifierArgsFinal { + zksolc_version, + vyper_version, + }) } } @@ -84,3 +85,23 @@ fn get_arch() -> anyhow::Result { Ok(arch) } + +fn select_version( + selected: Option, + versions: Vec, + prompt_msg: &str, +) -> anyhow::Result { + let selected = selected.unwrap_or_else(|| { + PromptSelect::new(prompt_msg, versions.iter().map(|r| &r.version)) + .ask() + .into() + }); + + let selected = versions + .iter() + .find(|r| r.version == selected) + .context(MSG_NO_VERSION_FOUND_ERR)? + .to_owned(); + + Ok(selected) +} diff --git a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/mod.rs b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/mod.rs index 6b13181f51b9..7f5df830d114 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/mod.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/mod.rs @@ -1,2 +1,2 @@ pub mod init; -pub mod zksolc_releases; +pub mod releases; diff --git a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/zksolc_releases.rs b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/releases.rs similarity index 54% rename from zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/zksolc_releases.rs rename to zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/releases.rs index 739a4b050a6f..b4756ff190df 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/zksolc_releases.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/releases.rs @@ -4,11 +4,11 @@ use common::cmd::Cmd; use serde::Deserialize; use xshell::{cmd, Shell}; -use crate::messages::MSG_INVALID_ARCH_ERR; +use crate::messages::{MSG_INVALID_ARCH_ERR, MSG_NO_RELEASES_FOUND_ERR}; #[derive(Deserialize)] struct GitHubRelease { - name: String, + tag_name: String, assets: Vec, } @@ -19,9 +19,9 @@ struct GitHubAsset { } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct ZkSolcVersion { +pub struct Version { pub version: String, - pub arch: Arch, + pub arch: Vec, pub url: String, } @@ -51,27 +51,41 @@ impl std::str::FromStr for Arch { } } -pub fn get_zksolc_releases(shell: &Shell) -> anyhow::Result> { +fn get_compatible_archs(asset_name: &str) -> anyhow::Result> { + if let Ok(arch) = Arch::from_str(asset_name) { + Ok(vec![arch]) + } else { + if asset_name.contains(".linux") { + Ok(vec![Arch::LinuxAmd, Arch::LinuxArm]) + } else if asset_name.contains(".darwin") { + Ok(vec![Arch::MacosAmd, Arch::MacosArm]) + } else { + Err(anyhow::anyhow!(MSG_INVALID_ARCH_ERR)) + } + } +} + +fn get_releases(shell: &Shell, repo: &str) -> anyhow::Result> { let response: std::process::Output = Cmd::new(cmd!( shell, - "curl https://api.github.com/repos/matter-labs/zksolc-bin/releases" + "curl https://api.github.com/repos/{repo}/releases" )) .run_with_output()?; let response = String::from_utf8(response.stdout)?; let releases: Vec = serde_json::from_str(&response)?; - let mut zk_solc_versions = vec![]; + let mut versions = vec![]; for release in releases { - let version = release.name; + let version = release.tag_name; for asset in release.assets { - let arch = match Arch::from_str(&asset.name) { + let arch = match get_compatible_archs(&asset.name) { Ok(arch) => arch, Err(_) => continue, }; let url = asset.browser_download_url; - zk_solc_versions.push(ZkSolcVersion { + versions.push(Version { version: version.clone(), arch, url, @@ -79,5 +93,21 @@ pub fn get_zksolc_releases(shell: &Shell) -> anyhow::Result> } } - Ok(zk_solc_versions) + Ok(versions) +} + +pub fn get_releases_with_arch( + shell: &Shell, + repo: &str, + arch: Arch, +) -> anyhow::Result> { + let releases = get_releases(shell, repo)?; + let releases = releases + .into_iter() + .filter(|r| r.arch.contains(&arch)) + .collect::>(); + if releases.is_empty() { + anyhow::bail!(MSG_NO_RELEASES_FOUND_ERR); + } + Ok(releases) } diff --git a/zk_toolbox/crates/zk_inception/src/messages.rs b/zk_toolbox/crates/zk_inception/src/messages.rs index 5c05abe2d1db..3eb8118f90cb 100644 --- a/zk_toolbox/crates/zk_inception/src/messages.rs +++ b/zk_toolbox/crates/zk_inception/src/messages.rs @@ -283,7 +283,10 @@ pub(super) const MSG_INVALID_ARCH_ERR: &str = "Invalid arch"; pub(super) const MSG_GET_ZKSOLC_RELEASES_ERR: &str = "Failed to get zksolc releases"; pub(super) const MSG_FETCHING_ZKSOLC_RELEASES_SPINNER: &str = "Fetching zksolc releases..."; pub(super) const MSG_ZKSOLC_VERSION_PROMPT: &str = "Select the zksolc version:"; +pub(super) const MSG_VYPER_VERSION_PROMPT: &str = "Select the vyper version:"; pub(super) const MSG_NO_RELEASES_FOUND_ERR: &str = "No releases found for current architecture"; pub(super) const MSG_NO_VERSION_FOUND_ERR: &str = "No version found"; pub(super) const MSG_ARCH_NOT_SUPPORTED_ERR: &str = "Architecture not supported"; pub(super) const MSG_OS_NOT_SUPPORTED_ERR: &str = "OS not supported"; +pub(super) const MSG_FETCHING_VYPER_RELEASES_SPINNER: &str = "Fetching vyper releases..."; +pub(super) const MSG_GET_VYPER_RELEASES_ERR: &str = "Failed to get vyper releases"; From 5794e5223754270441ba3374086871f10e04a977 Mon Sep 17 00:00:00 2001 From: Danil Date: Thu, 11 Jul 2024 14:20:06 +0200 Subject: [PATCH 11/21] Add ecosystem name Signed-off-by: Danil --- zk_toolbox/crates/config/src/ecosystem.rs | 2 +- .../crates/zk_inception/src/commands/ecosystem/create.rs | 4 ++-- zk_toolbox/crates/zk_inception/src/messages.rs | 6 +++++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/zk_toolbox/crates/config/src/ecosystem.rs b/zk_toolbox/crates/config/src/ecosystem.rs index 7a7456ded1cb..60ca22e9a9b0 100644 --- a/zk_toolbox/crates/config/src/ecosystem.rs +++ b/zk_toolbox/crates/config/src/ecosystem.rs @@ -102,7 +102,7 @@ impl EcosystemConfig { pub fn from_file(shell: &Shell) -> Result { let path = PathBuf::from(CONFIG_NAME); - if !shell.path_exists(&path) { + if !shell.path_exists(path) { return Err(EcosystemConfigFromFileError::NotExists { path: shell.current_dir(), }); diff --git a/zk_toolbox/crates/zk_inception/src/commands/ecosystem/create.rs b/zk_toolbox/crates/zk_inception/src/commands/ecosystem/create.rs index e4b06154e37e..52d116038f69 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/ecosystem/create.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/ecosystem/create.rs @@ -19,7 +19,7 @@ use crate::{ }, }, messages::{ - MSG_CLONING_ERA_REPO_SPINNER, MSG_CREATED_ECOSYSTEM, MSG_CREATING_DEFAULT_CHAIN_SPINNER, + msg_created_ecosystem, MSG_CLONING_ERA_REPO_SPINNER, MSG_CREATING_DEFAULT_CHAIN_SPINNER, MSG_CREATING_ECOSYSTEM, MSG_CREATING_INITIAL_CONFIGURATIONS_SPINNER, MSG_ECOSYSTEM_ALREADY_EXISTS_ERR, MSG_ECOSYSTEM_CONFIG_INVALID_ERR, MSG_SELECTED_CONFIG, MSG_STARTING_CONTAINERS_SPINNER, @@ -111,6 +111,6 @@ fn create(args: EcosystemCreateArgs, shell: &Shell) -> anyhow::Result<()> { spinner.finish(); } - logger::outro(MSG_CREATED_ECOSYSTEM); + logger::outro(msg_created_ecosystem(&ecosystem_name)); Ok(()) } diff --git a/zk_toolbox/crates/zk_inception/src/messages.rs b/zk_toolbox/crates/zk_inception/src/messages.rs index c98f76b751c8..94614ee86e6f 100644 --- a/zk_toolbox/crates/zk_inception/src/messages.rs +++ b/zk_toolbox/crates/zk_inception/src/messages.rs @@ -22,7 +22,11 @@ pub(super) const MSG_L1_NETWORK_PROMPT: &str = "Select the L1 network"; pub(super) const MSG_START_CONTAINERS_PROMPT: &str = "Do you want to start containers after creating the ecosystem?"; pub(super) const MSG_CREATING_ECOSYSTEM: &str = "Creating ecosystem"; -pub(super) const MSG_CREATED_ECOSYSTEM: &str = "Ecosystem created successfully (All subsequent commands should be executed from ecosystem folder `cd path/to/ecosystem/name`)"; + +pub fn msg_created_ecosystem(name: &str) -> String { + format!("Ecosystem {name} created successfully (All subsequent commands should be executed from ecosystem folder `cd path/to/ecosystem/name`)") +} + pub(super) const MSG_CLONING_ERA_REPO_SPINNER: &str = "Cloning zksync-era repository..."; pub(super) const MSG_CREATING_INITIAL_CONFIGURATIONS_SPINNER: &str = "Creating initial configurations..."; From 4c4ffc8adb17cb20fe1c131d0be2044a173528c8 Mon Sep 17 00:00:00 2001 From: Danil Date: Thu, 11 Jul 2024 14:41:16 +0200 Subject: [PATCH 12/21] Update zk_toolbox/crates/zk_inception/src/messages.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matías Ignacio González --- zk_toolbox/crates/zk_inception/src/commands/ecosystem/create.rs | 2 +- zk_toolbox/crates/zk_inception/src/messages.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/zk_toolbox/crates/zk_inception/src/commands/ecosystem/create.rs b/zk_toolbox/crates/zk_inception/src/commands/ecosystem/create.rs index 52d116038f69..b7fdfee855f6 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/ecosystem/create.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/ecosystem/create.rs @@ -111,6 +111,6 @@ fn create(args: EcosystemCreateArgs, shell: &Shell) -> anyhow::Result<()> { spinner.finish(); } - logger::outro(msg_created_ecosystem(&ecosystem_name)); + logger::outro(msg_created_ecosystem(ecosystem_name)); Ok(()) } diff --git a/zk_toolbox/crates/zk_inception/src/messages.rs b/zk_toolbox/crates/zk_inception/src/messages.rs index 94614ee86e6f..d0b146c9a4c5 100644 --- a/zk_toolbox/crates/zk_inception/src/messages.rs +++ b/zk_toolbox/crates/zk_inception/src/messages.rs @@ -24,7 +24,7 @@ pub(super) const MSG_START_CONTAINERS_PROMPT: &str = pub(super) const MSG_CREATING_ECOSYSTEM: &str = "Creating ecosystem"; pub fn msg_created_ecosystem(name: &str) -> String { - format!("Ecosystem {name} created successfully (All subsequent commands should be executed from ecosystem folder `cd path/to/ecosystem/name`)") + format!("Ecosystem {name} created successfully (All subsequent commands should be executed from ecosystem folder `cd {name}`)") } pub(super) const MSG_CLONING_ERA_REPO_SPINNER: &str = "Cloning zksync-era repository..."; From 2f4b1fc72787a82b4a40ebd48c251279bd264036 Mon Sep 17 00:00:00 2001 From: matias-gonz Date: Thu, 11 Jul 2024 16:12:56 +0200 Subject: [PATCH 13/21] Add download_binary --- .../commands/contract_verifier/args/init.rs | 51 ++++++++++++++----- .../contract_verifier/args/releases.rs | 5 +- .../src/commands/contract_verifier/init.rs | 42 ++++++++++++++- .../crates/zk_inception/src/messages.rs | 11 ++++ 4 files changed, 92 insertions(+), 17 deletions(-) diff --git a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/init.rs b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/init.rs index 1d6e079f7c74..2c21551b13a5 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/init.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/init.rs @@ -1,17 +1,15 @@ use anyhow::Context; use clap::Parser; -use common::{ - spinner::{self, Spinner}, - PromptSelect, -}; +use common::PromptSelect; use xshell::Shell; use super::releases::{get_releases_with_arch, Arch, Version}; use crate::messages::{ MSG_ARCH_NOT_SUPPORTED_ERR, MSG_FETCHING_VYPER_RELEASES_SPINNER, - MSG_FETCHING_ZKSOLC_RELEASES_SPINNER, MSG_GET_VYPER_RELEASES_ERR, MSG_GET_ZKSOLC_RELEASES_ERR, + MSG_FETCHING_ZKSOLC_RELEASES_SPINNER, MSG_FETCHING_ZKVYPER_RELEASES_SPINNER, + MSG_GET_VYPER_RELEASES_ERR, MSG_GET_ZKSOLC_RELEASES_ERR, MSG_GET_ZKVYPER_RELEASES_ERR, MSG_NO_VERSION_FOUND_ERR, MSG_OS_NOT_SUPPORTED_ERR, MSG_VYPER_VERSION_PROMPT, - MSG_ZKSOLC_VERSION_PROMPT, + MSG_ZKSOLC_VERSION_PROMPT, MSG_ZKVYPER_VERSION_PROMPT, }; #[derive(Debug, Clone, Parser, Default)] @@ -19,6 +17,9 @@ pub struct InitContractVerifierArgs { /// Version of zksolc to install #[clap(long)] pub zksolc_version: Option, + /// Version of zkvyper to install + #[clap(long)] + pub zkvyper_version: Option, /// Version of vyper to install #[clap(long)] pub vyper_version: Option, @@ -27,6 +28,7 @@ pub struct InitContractVerifierArgs { #[derive(Debug, Clone)] pub struct InitContractVerifierArgsFinal { pub zksolc_version: Version, + pub zkvyper_version: Version, pub vyper_version: Version, } @@ -37,15 +39,29 @@ impl InitContractVerifierArgs { ) -> anyhow::Result { let arch = get_arch()?; - let spinner = Spinner::new(MSG_FETCHING_ZKSOLC_RELEASES_SPINNER); - let zksolc_releases = get_releases_with_arch(shell, "matter-labs/zksolc-bin", arch) - .context(MSG_GET_ZKSOLC_RELEASES_ERR)?; - spinner.finish(); + let zksolc_releases = get_releases_with_arch( + shell, + "matter-labs/zksolc-bin", + arch, + MSG_FETCHING_ZKSOLC_RELEASES_SPINNER, + ) + .context(MSG_GET_ZKSOLC_RELEASES_ERR)?; + + let zkvyper_releases = get_releases_with_arch( + shell, + "matter-labs/zkvyper-bin", + arch, + MSG_FETCHING_ZKVYPER_RELEASES_SPINNER, + ) + .context(MSG_GET_ZKVYPER_RELEASES_ERR)?; - let spinner = spinner::Spinner::new(MSG_FETCHING_VYPER_RELEASES_SPINNER); - let vyper_releases = get_releases_with_arch(shell, "vyperlang/vyper", arch) - .context(MSG_GET_VYPER_RELEASES_ERR)?; - spinner.finish(); + let vyper_releases = get_releases_with_arch( + shell, + "vyperlang/vyper", + arch, + MSG_FETCHING_VYPER_RELEASES_SPINNER, + ) + .context(MSG_GET_VYPER_RELEASES_ERR)?; let zksolc_version = select_version( self.zksolc_version, @@ -53,11 +69,18 @@ impl InitContractVerifierArgs { MSG_ZKSOLC_VERSION_PROMPT, )?; + let zkvyper_version = select_version( + self.zkvyper_version, + zkvyper_releases, + MSG_ZKVYPER_VERSION_PROMPT, + )?; + let vyper_version = select_version(self.vyper_version, vyper_releases, MSG_VYPER_VERSION_PROMPT)?; Ok(InitContractVerifierArgsFinal { zksolc_version, + zkvyper_version, vyper_version, }) } diff --git a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/releases.rs b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/releases.rs index b4756ff190df..b46e845ad9a7 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/releases.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/releases.rs @@ -1,6 +1,6 @@ use std::str::FromStr; -use common::cmd::Cmd; +use common::{cmd::Cmd, spinner::Spinner}; use serde::Deserialize; use xshell::{cmd, Shell}; @@ -100,7 +100,9 @@ pub fn get_releases_with_arch( shell: &Shell, repo: &str, arch: Arch, + message: &str, ) -> anyhow::Result> { + let spinner = Spinner::new(message); let releases = get_releases(shell, repo)?; let releases = releases .into_iter() @@ -109,5 +111,6 @@ pub fn get_releases_with_arch( if releases.is_empty() { anyhow::bail!(MSG_NO_RELEASES_FOUND_ERR); } + spinner.finish(); Ok(releases) } diff --git a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs index f3e12719771d..c14fda406bd9 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs @@ -1,8 +1,46 @@ -use xshell::Shell; +use std::path::PathBuf; + +use common::{cmd::Cmd, logger, spinner::Spinner}; +use config::EcosystemConfig; +use xshell::{cmd, Shell}; + +use crate::messages::{msg_binary_already_exists, msg_downloading_binary_spinner}; use super::args::init::InitContractVerifierArgs; pub(crate) async fn run(shell: &Shell, args: InitContractVerifierArgs) -> anyhow::Result<()> { - args.fill_values_with_prompt(shell)?; + let args = args.fill_values_with_prompt(shell)?; + let ecosystem = EcosystemConfig::from_file(shell)?; + let link_to_code = ecosystem.link_to_code; + let zksolc_path = link_to_code + .join("etc/zksolc-bin/") + .join(args.zksolc_version.version); + let zkvyper_path = link_to_code + .join("etc/zkvyper-bin/") + .join(args.zkvyper_version.version); + let vyper_path = link_to_code + .join("etc/vyper-bin/") + .join(args.vyper_version.version.replace("v", "")); + + download_binary(shell, &args.zksolc_version.url, &zksolc_path, "zksolc")?; + download_binary(shell, &args.zkvyper_version.url, &zkvyper_path, "zkvyper")?; + download_binary(shell, &args.vyper_version.url, &vyper_path, "vyper")?; + + Ok(()) +} + +fn download_binary(shell: &Shell, url: &str, path: &PathBuf, name: &str) -> anyhow::Result<()> { + let binary_path = path.join(name); + if shell.path_exists(binary_path.clone()) { + logger::info(&msg_binary_already_exists(name)); + return Ok(()); + } + + let spinner = Spinner::new(&msg_downloading_binary_spinner(name)); + Cmd::new(cmd!(shell, "mkdir -p {path}")).run()?; + Cmd::new(cmd!(shell, "wget {url} -O {binary_path}")).run()?; + Cmd::new(cmd!(shell, "chmod +x {binary_path}")).run()?; + spinner.finish(); + Ok(()) } diff --git a/zk_toolbox/crates/zk_inception/src/messages.rs b/zk_toolbox/crates/zk_inception/src/messages.rs index 7cbc3ac327ff..f7b6f85f20ee 100644 --- a/zk_toolbox/crates/zk_inception/src/messages.rs +++ b/zk_toolbox/crates/zk_inception/src/messages.rs @@ -285,7 +285,9 @@ pub(super) const MSG_FAILED_TO_RUN_CONTRACT_VERIFIER_ERR: &str = "Failed to run pub(super) const MSG_INVALID_ARCH_ERR: &str = "Invalid arch"; pub(super) const MSG_GET_ZKSOLC_RELEASES_ERR: &str = "Failed to get zksolc releases"; pub(super) const MSG_FETCHING_ZKSOLC_RELEASES_SPINNER: &str = "Fetching zksolc releases..."; +pub(super) const MSG_FETCHING_ZKVYPER_RELEASES_SPINNER: &str = "Fetching zkvyper releases..."; pub(super) const MSG_ZKSOLC_VERSION_PROMPT: &str = "Select the zksolc version:"; +pub(super) const MSG_ZKVYPER_VERSION_PROMPT: &str = "Select the zkvyper version:"; pub(super) const MSG_VYPER_VERSION_PROMPT: &str = "Select the vyper version:"; pub(super) const MSG_NO_RELEASES_FOUND_ERR: &str = "No releases found for current architecture"; pub(super) const MSG_NO_VERSION_FOUND_ERR: &str = "No version found"; @@ -293,3 +295,12 @@ pub(super) const MSG_ARCH_NOT_SUPPORTED_ERR: &str = "Architecture not supported" pub(super) const MSG_OS_NOT_SUPPORTED_ERR: &str = "OS not supported"; pub(super) const MSG_FETCHING_VYPER_RELEASES_SPINNER: &str = "Fetching vyper releases..."; pub(super) const MSG_GET_VYPER_RELEASES_ERR: &str = "Failed to get vyper releases"; +pub(super) const MSG_GET_ZKVYPER_RELEASES_ERR: &str = "Failed to get zkvyper releases"; + +pub(super) fn msg_binary_already_exists(name: &str) -> String { + format!("{} binary already exists. Skipping download.", name) +} + +pub(super) fn msg_downloading_binary_spinner(name: &str) -> String { + format!("Downloading {} binary", name) +} From 385f990efe2a36b16a0f4f67f52953c3a740d8cc Mon Sep 17 00:00:00 2001 From: matias-gonz Date: Thu, 11 Jul 2024 16:13:24 +0200 Subject: [PATCH 14/21] fmt --- .../crates/zk_inception/src/commands/contract_verifier/init.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs index c14fda406bd9..bd9ac12c16aa 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs @@ -4,9 +4,8 @@ use common::{cmd::Cmd, logger, spinner::Spinner}; use config::EcosystemConfig; use xshell::{cmd, Shell}; -use crate::messages::{msg_binary_already_exists, msg_downloading_binary_spinner}; - use super::args::init::InitContractVerifierArgs; +use crate::messages::{msg_binary_already_exists, msg_downloading_binary_spinner}; pub(crate) async fn run(shell: &Shell, args: InitContractVerifierArgs) -> anyhow::Result<()> { let args = args.fill_values_with_prompt(shell)?; From c119fd9fe6797564eaa1f5b228263944e35d3552 Mon Sep 17 00:00:00 2001 From: matias-gonz Date: Fri, 12 Jul 2024 10:24:43 +0200 Subject: [PATCH 15/21] Download all binaries above version --- .../commands/contract_verifier/args/init.rs | 44 +++++++--- .../src/commands/contract_verifier/init.rs | 82 +++++++++++++++---- .../crates/zk_inception/src/messages.rs | 17 ++-- 3 files changed, 107 insertions(+), 36 deletions(-) diff --git a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/init.rs b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/init.rs index 2c21551b13a5..de226ff45c33 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/init.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/init.rs @@ -27,9 +27,9 @@ pub struct InitContractVerifierArgs { #[derive(Debug, Clone)] pub struct InitContractVerifierArgsFinal { - pub zksolc_version: Version, - pub zkvyper_version: Version, - pub vyper_version: Version, + pub zksolc_releases: Vec, + pub zkvyper_releases: Vec, + pub vyper_releases: Vec, } impl InitContractVerifierArgs { @@ -63,25 +63,31 @@ impl InitContractVerifierArgs { ) .context(MSG_GET_VYPER_RELEASES_ERR)?; - let zksolc_version = select_version( + let zksolc_version = select_min_version( self.zksolc_version, - zksolc_releases, + zksolc_releases.clone(), MSG_ZKSOLC_VERSION_PROMPT, )?; + let zksolc_releases = get_releases_above_version(zksolc_releases, zksolc_version)?; - let zkvyper_version = select_version( + let zkvyper_version = select_min_version( self.zkvyper_version, - zkvyper_releases, + zkvyper_releases.clone(), MSG_ZKVYPER_VERSION_PROMPT, )?; + let zkvyper_releases = get_releases_above_version(zkvyper_releases, zkvyper_version)?; - let vyper_version = - select_version(self.vyper_version, vyper_releases, MSG_VYPER_VERSION_PROMPT)?; + let vyper_version = select_min_version( + self.vyper_version, + vyper_releases.clone(), + MSG_VYPER_VERSION_PROMPT, + )?; + let vyper_releases = get_releases_above_version(vyper_releases, vyper_version)?; Ok(InitContractVerifierArgsFinal { - zksolc_version, - zkvyper_version, - vyper_version, + zksolc_releases, + zkvyper_releases, + vyper_releases, }) } } @@ -109,7 +115,7 @@ fn get_arch() -> anyhow::Result { Ok(arch) } -fn select_version( +fn select_min_version( selected: Option, versions: Vec, prompt_msg: &str, @@ -128,3 +134,15 @@ fn select_version( Ok(selected) } + +fn get_releases_above_version( + releases: Vec, + version: Version, +) -> anyhow::Result> { + let pos = releases + .iter() + .position(|r| r.version == version.version) + .context(MSG_NO_VERSION_FOUND_ERR)?; + + Ok(releases[..=pos].to_vec()) +} diff --git a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs index bd9ac12c16aa..a54d0f7ffbaf 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs @@ -4,38 +4,74 @@ use common::{cmd::Cmd, logger, spinner::Spinner}; use config::EcosystemConfig; use xshell::{cmd, Shell}; -use super::args::init::InitContractVerifierArgs; +use super::args::{init::InitContractVerifierArgs, releases::Version}; use crate::messages::{msg_binary_already_exists, msg_downloading_binary_spinner}; pub(crate) async fn run(shell: &Shell, args: InitContractVerifierArgs) -> anyhow::Result<()> { let args = args.fill_values_with_prompt(shell)?; let ecosystem = EcosystemConfig::from_file(shell)?; let link_to_code = ecosystem.link_to_code; - let zksolc_path = link_to_code - .join("etc/zksolc-bin/") - .join(args.zksolc_version.version); - let zkvyper_path = link_to_code - .join("etc/zkvyper-bin/") - .join(args.zkvyper_version.version); - let vyper_path = link_to_code - .join("etc/vyper-bin/") - .join(args.vyper_version.version.replace("v", "")); - download_binary(shell, &args.zksolc_version.url, &zksolc_path, "zksolc")?; - download_binary(shell, &args.zkvyper_version.url, &zkvyper_path, "zkvyper")?; - download_binary(shell, &args.vyper_version.url, &vyper_path, "vyper")?; + download_binaries( + shell, + args.zksolc_releases, + get_zksolc_path, + &link_to_code, + "zksolc", + )?; + + download_binaries( + shell, + args.zkvyper_releases, + get_zkvyper_path, + &link_to_code, + "zkvyper", + )?; + download_binaries( + shell, + args.vyper_releases, + get_vyper_path, + &link_to_code, + "vyper", + )?; + + Ok(()) +} + +fn download_binaries( + shell: &Shell, + releases: Vec, + get_path: fn(&PathBuf, &str) -> PathBuf, + link_to_code: &PathBuf, + name: &str, +) -> anyhow::Result<()> { + for release in releases { + download_binary( + shell, + &release.url, + &get_path(link_to_code, &release.version), + name, + &release.version, + )?; + } Ok(()) } -fn download_binary(shell: &Shell, url: &str, path: &PathBuf, name: &str) -> anyhow::Result<()> { +fn download_binary( + shell: &Shell, + url: &str, + path: &PathBuf, + name: &str, + version: &str, +) -> anyhow::Result<()> { let binary_path = path.join(name); if shell.path_exists(binary_path.clone()) { - logger::info(&msg_binary_already_exists(name)); + logger::info(&msg_binary_already_exists(name, version)); return Ok(()); } - let spinner = Spinner::new(&msg_downloading_binary_spinner(name)); + let spinner = Spinner::new(&msg_downloading_binary_spinner(name, version)); Cmd::new(cmd!(shell, "mkdir -p {path}")).run()?; Cmd::new(cmd!(shell, "wget {url} -O {binary_path}")).run()?; Cmd::new(cmd!(shell, "chmod +x {binary_path}")).run()?; @@ -43,3 +79,17 @@ fn download_binary(shell: &Shell, url: &str, path: &PathBuf, name: &str) -> anyh Ok(()) } + +fn get_zksolc_path(link_to_code: &PathBuf, version: &str) -> PathBuf { + link_to_code.join("etc/zksolc-bin/").join(version) +} + +fn get_zkvyper_path(link_to_code: &PathBuf, version: &str) -> PathBuf { + link_to_code.join("etc/zkvyper-bin/").join(version) +} + +fn get_vyper_path(link_to_code: &PathBuf, version: &str) -> PathBuf { + link_to_code + .join("etc/vyper-bin/") + .join(version.replace("v", "")) +} diff --git a/zk_toolbox/crates/zk_inception/src/messages.rs b/zk_toolbox/crates/zk_inception/src/messages.rs index f7b6f85f20ee..0b5f9e21e77e 100644 --- a/zk_toolbox/crates/zk_inception/src/messages.rs +++ b/zk_toolbox/crates/zk_inception/src/messages.rs @@ -286,9 +286,9 @@ pub(super) const MSG_INVALID_ARCH_ERR: &str = "Invalid arch"; pub(super) const MSG_GET_ZKSOLC_RELEASES_ERR: &str = "Failed to get zksolc releases"; pub(super) const MSG_FETCHING_ZKSOLC_RELEASES_SPINNER: &str = "Fetching zksolc releases..."; pub(super) const MSG_FETCHING_ZKVYPER_RELEASES_SPINNER: &str = "Fetching zkvyper releases..."; -pub(super) const MSG_ZKSOLC_VERSION_PROMPT: &str = "Select the zksolc version:"; -pub(super) const MSG_ZKVYPER_VERSION_PROMPT: &str = "Select the zkvyper version:"; -pub(super) const MSG_VYPER_VERSION_PROMPT: &str = "Select the vyper version:"; +pub(super) const MSG_ZKSOLC_VERSION_PROMPT: &str = "Select the minimal zksolc version:"; +pub(super) const MSG_ZKVYPER_VERSION_PROMPT: &str = "Select the minimalzkvyper version:"; +pub(super) const MSG_VYPER_VERSION_PROMPT: &str = "Select the minimal vyper version:"; pub(super) const MSG_NO_RELEASES_FOUND_ERR: &str = "No releases found for current architecture"; pub(super) const MSG_NO_VERSION_FOUND_ERR: &str = "No version found"; pub(super) const MSG_ARCH_NOT_SUPPORTED_ERR: &str = "Architecture not supported"; @@ -297,10 +297,13 @@ pub(super) const MSG_FETCHING_VYPER_RELEASES_SPINNER: &str = "Fetching vyper rel pub(super) const MSG_GET_VYPER_RELEASES_ERR: &str = "Failed to get vyper releases"; pub(super) const MSG_GET_ZKVYPER_RELEASES_ERR: &str = "Failed to get zkvyper releases"; -pub(super) fn msg_binary_already_exists(name: &str) -> String { - format!("{} binary already exists. Skipping download.", name) +pub(super) fn msg_binary_already_exists(name: &str, version: &str) -> String { + format!( + "{} {} binary already exists. Skipping download.", + name, version + ) } -pub(super) fn msg_downloading_binary_spinner(name: &str) -> String { - format!("Downloading {} binary", name) +pub(super) fn msg_downloading_binary_spinner(name: &str, version: &str) -> String { + format!("Downloading {} {} binary", name, version) } From 5832abe4b4429cd07a696a567a8d73b5a97bf3b0 Mon Sep 17 00:00:00 2001 From: matias-gonz Date: Fri, 12 Jul 2024 11:03:13 +0200 Subject: [PATCH 16/21] Add get_solc_releases --- .../commands/contract_verifier/args/init.rs | 25 +++++++++- .../contract_verifier/args/releases.rs | 49 ++++++++++++++++++- .../src/commands/contract_verifier/init.rs | 12 +++++ .../crates/zk_inception/src/messages.rs | 7 ++- 4 files changed, 87 insertions(+), 6 deletions(-) diff --git a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/init.rs b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/init.rs index de226ff45c33..c74e4a4f765e 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/init.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/init.rs @@ -7,8 +7,9 @@ use super::releases::{get_releases_with_arch, Arch, Version}; use crate::messages::{ MSG_ARCH_NOT_SUPPORTED_ERR, MSG_FETCHING_VYPER_RELEASES_SPINNER, MSG_FETCHING_ZKSOLC_RELEASES_SPINNER, MSG_FETCHING_ZKVYPER_RELEASES_SPINNER, - MSG_GET_VYPER_RELEASES_ERR, MSG_GET_ZKSOLC_RELEASES_ERR, MSG_GET_ZKVYPER_RELEASES_ERR, - MSG_NO_VERSION_FOUND_ERR, MSG_OS_NOT_SUPPORTED_ERR, MSG_VYPER_VERSION_PROMPT, + MSG_FETCH_SOLC_RELEASES_SPINNER, MSG_GET_SOLC_RELEASES_ERR, MSG_GET_VYPER_RELEASES_ERR, + MSG_GET_ZKSOLC_RELEASES_ERR, MSG_GET_ZKVYPER_RELEASES_ERR, MSG_NO_VERSION_FOUND_ERR, + MSG_OS_NOT_SUPPORTED_ERR, MSG_SOLC_VERSION_PROMPT, MSG_VYPER_VERSION_PROMPT, MSG_ZKSOLC_VERSION_PROMPT, MSG_ZKVYPER_VERSION_PROMPT, }; @@ -20,6 +21,9 @@ pub struct InitContractVerifierArgs { /// Version of zkvyper to install #[clap(long)] pub zkvyper_version: Option, + /// Version of solc to install + #[clap(long)] + pub solc_version: Option, /// Version of vyper to install #[clap(long)] pub vyper_version: Option, @@ -29,6 +33,7 @@ pub struct InitContractVerifierArgs { pub struct InitContractVerifierArgsFinal { pub zksolc_releases: Vec, pub zkvyper_releases: Vec, + pub solc_releases: Vec, pub vyper_releases: Vec, } @@ -55,6 +60,14 @@ impl InitContractVerifierArgs { ) .context(MSG_GET_ZKVYPER_RELEASES_ERR)?; + let solc_releases = get_releases_with_arch( + shell, + "ethereum/solc-bin", + arch, + MSG_FETCH_SOLC_RELEASES_SPINNER, + ) + .context(MSG_GET_SOLC_RELEASES_ERR)?; + let vyper_releases = get_releases_with_arch( shell, "vyperlang/vyper", @@ -77,6 +90,13 @@ impl InitContractVerifierArgs { )?; let zkvyper_releases = get_releases_above_version(zkvyper_releases, zkvyper_version)?; + let solc_version = select_min_version( + self.solc_version, + solc_releases.clone(), + MSG_SOLC_VERSION_PROMPT, + )?; + let solc_releases = get_releases_above_version(solc_releases, solc_version)?; + let vyper_version = select_min_version( self.vyper_version, vyper_releases.clone(), @@ -87,6 +107,7 @@ impl InitContractVerifierArgs { Ok(InitContractVerifierArgsFinal { zksolc_releases, zkvyper_releases, + solc_releases, vyper_releases, }) } diff --git a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/releases.rs b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/releases.rs index b46e845ad9a7..c34afe7b573b 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/releases.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/releases.rs @@ -18,6 +18,17 @@ struct GitHubAsset { browser_download_url: String, } +#[derive(Deserialize)] +struct SolcList { + builds: Vec, +} + +#[derive(Deserialize)] +struct SolcBuild { + path: String, + version: String, +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct Version { pub version: String, @@ -65,7 +76,11 @@ fn get_compatible_archs(asset_name: &str) -> anyhow::Result> { } } -fn get_releases(shell: &Shell, repo: &str) -> anyhow::Result> { +fn get_releases(shell: &Shell, repo: &str, arch: Arch) -> anyhow::Result> { + if repo == "ethereum/solc-bin" { + return get_solc_releases(shell, arch); + } + let response: std::process::Output = Cmd::new(cmd!( shell, "curl https://api.github.com/repos/{repo}/releases" @@ -96,6 +111,36 @@ fn get_releases(shell: &Shell, repo: &str) -> anyhow::Result> { Ok(versions) } +fn get_solc_releases(shell: &Shell, arch: Arch) -> anyhow::Result> { + let (arch_str, compatible_archs) = match arch { + Arch::LinuxAmd => ("linux-amd64", vec![Arch::LinuxAmd, Arch::LinuxArm]), + Arch::LinuxArm => ("linux-amd64", vec![Arch::LinuxAmd, Arch::LinuxArm]), + Arch::MacosAmd => ("macosx-amd64", vec![Arch::MacosAmd, Arch::MacosArm]), + Arch::MacosArm => ("macosx-amd64", vec![Arch::MacosAmd, Arch::MacosArm]), + }; + + let response: std::process::Output = Cmd::new(cmd!( + shell, + "curl https://raw.githubusercontent.com/ethereum/solc-bin/gh-pages/{arch_str}/list.json" + )) + .run_with_output()?; + + let response = String::from_utf8(response.stdout)?; + let solc_list: SolcList = serde_json::from_str(&response)?; + + let mut versions = vec![]; + for build in solc_list.builds { + let path = build.path; + versions.push(Version { + version: build.version, + arch: compatible_archs.clone(), + url: format!("https://github.com/ethereum/solc-bin/raw/gh-pages/{arch_str}/{path}"), + }); + } + versions.reverse(); + Ok(versions) +} + pub fn get_releases_with_arch( shell: &Shell, repo: &str, @@ -103,7 +148,7 @@ pub fn get_releases_with_arch( message: &str, ) -> anyhow::Result> { let spinner = Spinner::new(message); - let releases = get_releases(shell, repo)?; + let releases = get_releases(shell, repo, arch)?; let releases = releases .into_iter() .filter(|r| r.arch.contains(&arch)) diff --git a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs index a54d0f7ffbaf..b13b20e0292a 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs @@ -28,6 +28,14 @@ pub(crate) async fn run(shell: &Shell, args: InitContractVerifierArgs) -> anyhow "zkvyper", )?; + download_binaries( + shell, + args.solc_releases, + get_solc_path, + &link_to_code, + "solc", + )?; + download_binaries( shell, args.vyper_releases, @@ -93,3 +101,7 @@ fn get_vyper_path(link_to_code: &PathBuf, version: &str) -> PathBuf { .join("etc/vyper-bin/") .join(version.replace("v", "")) } + +fn get_solc_path(link_to_code: &PathBuf, version: &str) -> PathBuf { + link_to_code.join("etc/solc-bin/").join(version) +} diff --git a/zk_toolbox/crates/zk_inception/src/messages.rs b/zk_toolbox/crates/zk_inception/src/messages.rs index 0b5f9e21e77e..af40b48e5795 100644 --- a/zk_toolbox/crates/zk_inception/src/messages.rs +++ b/zk_toolbox/crates/zk_inception/src/messages.rs @@ -286,15 +286,18 @@ pub(super) const MSG_INVALID_ARCH_ERR: &str = "Invalid arch"; pub(super) const MSG_GET_ZKSOLC_RELEASES_ERR: &str = "Failed to get zksolc releases"; pub(super) const MSG_FETCHING_ZKSOLC_RELEASES_SPINNER: &str = "Fetching zksolc releases..."; pub(super) const MSG_FETCHING_ZKVYPER_RELEASES_SPINNER: &str = "Fetching zkvyper releases..."; +pub(super) const MSG_FETCH_SOLC_RELEASES_SPINNER: &str = "Fetching solc releases..."; +pub(super) const MSG_FETCHING_VYPER_RELEASES_SPINNER: &str = "Fetching vyper releases..."; pub(super) const MSG_ZKSOLC_VERSION_PROMPT: &str = "Select the minimal zksolc version:"; -pub(super) const MSG_ZKVYPER_VERSION_PROMPT: &str = "Select the minimalzkvyper version:"; +pub(super) const MSG_ZKVYPER_VERSION_PROMPT: &str = "Select the minimal zkvyper version:"; +pub(super) const MSG_SOLC_VERSION_PROMPT: &str = "Select the minimal solc version:"; pub(super) const MSG_VYPER_VERSION_PROMPT: &str = "Select the minimal vyper version:"; pub(super) const MSG_NO_RELEASES_FOUND_ERR: &str = "No releases found for current architecture"; pub(super) const MSG_NO_VERSION_FOUND_ERR: &str = "No version found"; pub(super) const MSG_ARCH_NOT_SUPPORTED_ERR: &str = "Architecture not supported"; pub(super) const MSG_OS_NOT_SUPPORTED_ERR: &str = "OS not supported"; -pub(super) const MSG_FETCHING_VYPER_RELEASES_SPINNER: &str = "Fetching vyper releases..."; pub(super) const MSG_GET_VYPER_RELEASES_ERR: &str = "Failed to get vyper releases"; +pub(super) const MSG_GET_SOLC_RELEASES_ERR: &str = "Failed to get solc releases"; pub(super) const MSG_GET_ZKVYPER_RELEASES_ERR: &str = "Failed to get zkvyper releases"; pub(super) fn msg_binary_already_exists(name: &str, version: &str) -> String { From 3971196e5d1057b28c83aec687d8d6a13bef86b4 Mon Sep 17 00:00:00 2001 From: matias-gonz Date: Fri, 12 Jul 2024 11:08:02 +0200 Subject: [PATCH 17/21] lint --- .../commands/contract_verifier/args/releases.rs | 12 +++++------- .../src/commands/contract_verifier/init.rs | 16 ++++++++-------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/releases.rs b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/releases.rs index c34afe7b573b..6f7eae4c1685 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/releases.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/args/releases.rs @@ -65,14 +65,12 @@ impl std::str::FromStr for Arch { fn get_compatible_archs(asset_name: &str) -> anyhow::Result> { if let Ok(arch) = Arch::from_str(asset_name) { Ok(vec![arch]) + } else if asset_name.contains(".linux") { + Ok(vec![Arch::LinuxAmd, Arch::LinuxArm]) + } else if asset_name.contains(".darwin") { + Ok(vec![Arch::MacosAmd, Arch::MacosArm]) } else { - if asset_name.contains(".linux") { - Ok(vec![Arch::LinuxAmd, Arch::LinuxArm]) - } else if asset_name.contains(".darwin") { - Ok(vec![Arch::MacosAmd, Arch::MacosArm]) - } else { - Err(anyhow::anyhow!(MSG_INVALID_ARCH_ERR)) - } + Err(anyhow::anyhow!(MSG_INVALID_ARCH_ERR)) } } diff --git a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs index b13b20e0292a..5a53a70db4ac 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs @@ -1,4 +1,4 @@ -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use common::{cmd::Cmd, logger, spinner::Spinner}; use config::EcosystemConfig; @@ -50,7 +50,7 @@ pub(crate) async fn run(shell: &Shell, args: InitContractVerifierArgs) -> anyhow fn download_binaries( shell: &Shell, releases: Vec, - get_path: fn(&PathBuf, &str) -> PathBuf, + get_path: fn(&Path, &str) -> PathBuf, link_to_code: &PathBuf, name: &str, ) -> anyhow::Result<()> { @@ -75,7 +75,7 @@ fn download_binary( ) -> anyhow::Result<()> { let binary_path = path.join(name); if shell.path_exists(binary_path.clone()) { - logger::info(&msg_binary_already_exists(name, version)); + logger::info(msg_binary_already_exists(name, version)); return Ok(()); } @@ -88,20 +88,20 @@ fn download_binary( Ok(()) } -fn get_zksolc_path(link_to_code: &PathBuf, version: &str) -> PathBuf { +fn get_zksolc_path(link_to_code: &Path, version: &str) -> PathBuf { link_to_code.join("etc/zksolc-bin/").join(version) } -fn get_zkvyper_path(link_to_code: &PathBuf, version: &str) -> PathBuf { +fn get_zkvyper_path(link_to_code: &Path, version: &str) -> PathBuf { link_to_code.join("etc/zkvyper-bin/").join(version) } -fn get_vyper_path(link_to_code: &PathBuf, version: &str) -> PathBuf { +fn get_vyper_path(link_to_code: &Path, version: &str) -> PathBuf { link_to_code .join("etc/vyper-bin/") - .join(version.replace("v", "")) + .join(version.replace('v', "")) } -fn get_solc_path(link_to_code: &PathBuf, version: &str) -> PathBuf { +fn get_solc_path(link_to_code: &Path, version: &str) -> PathBuf { link_to_code.join("etc/solc-bin/").join(version) } From d1eea82c390392acb3cd7c6341bdea7255e15abb Mon Sep 17 00:00:00 2001 From: matias-gonz Date: Fri, 12 Jul 2024 11:09:41 +0200 Subject: [PATCH 18/21] Add docs --- .../crates/zk_inception/src/commands/contract_verifier/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/mod.rs b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/mod.rs index 2f6f8192912e..78bdc5fae7ec 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/mod.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/mod.rs @@ -10,6 +10,7 @@ pub mod run; pub enum ContractVerifierCommands { /// Run contract verifier Run, + /// Download required binaries for contract verifier Init(InitContractVerifierArgs), } From 6709f1d454e21b39b06eb95888c12619844ae65f Mon Sep 17 00:00:00 2001 From: matias-gonz Date: Fri, 12 Jul 2024 11:33:23 +0200 Subject: [PATCH 19/21] Show output from contract verifier --- .../zk_inception/src/commands/contract_verifier/run.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/run.rs b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/run.rs index c8fa2dd82b5f..1ae06c810ba1 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/run.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/run.rs @@ -20,8 +20,10 @@ pub(crate) async fn run(shell: &Shell) -> anyhow::Result<()> { logger::info(MSG_RUNNING_CONTRACT_VERIFIER); - Cmd::new(cmd!( + let mut cmd = Cmd::new(cmd!( shell, "cargo run --bin zksync_contract_verifier -- --config-path={config_path} --secrets-path={secrets_path}" - )).run().context(MSG_FAILED_TO_RUN_CONTRACT_VERIFIER_ERR) + )); + cmd = cmd.with_force_run(); + cmd.run().context(MSG_FAILED_TO_RUN_CONTRACT_VERIFIER_ERR) } From 0140c5816e73c24b7195fff30273da1cac790c15 Mon Sep 17 00:00:00 2001 From: matias-gonz Date: Fri, 12 Jul 2024 12:53:05 +0200 Subject: [PATCH 20/21] lint --- .../crates/zk_inception/src/commands/contract_verifier/init.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs index 5a53a70db4ac..38bb4bd43028 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs @@ -69,7 +69,7 @@ fn download_binaries( fn download_binary( shell: &Shell, url: &str, - path: &PathBuf, + path: &Path, name: &str, version: &str, ) -> anyhow::Result<()> { From abe468f963b60068780c0726b9b183f5da30f425 Mon Sep 17 00:00:00 2001 From: matias-gonz Date: Fri, 12 Jul 2024 13:02:44 +0200 Subject: [PATCH 21/21] lint --- .../crates/zk_inception/src/commands/contract_verifier/init.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs index 38bb4bd43028..5fd482ae5fff 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/contract_verifier/init.rs @@ -51,7 +51,7 @@ fn download_binaries( shell: &Shell, releases: Vec, get_path: fn(&Path, &str) -> PathBuf, - link_to_code: &PathBuf, + link_to_code: &Path, name: &str, ) -> anyhow::Result<()> { for release in releases {