diff --git a/.github/workflows/ci-core-reusable.yml b/.github/workflows/ci-core-reusable.yml index 9aaa476d740..35bf4d9a390 100644 --- a/.github/workflows/ci-core-reusable.yml +++ b/.github/workflows/ci-core-reusable.yml @@ -148,7 +148,7 @@ jobs: - name: Run server run: | ci_run zkstack dev config-writer --path ${{ matrix.vm_mode == 'NEW' && 'etc/env/file_based/overrides/tests/loadtest-new.yaml' || 'etc/env/file_based/overrides/tests/loadtest-old.yaml' }} --chain legacy - ci_run zkstack server --uring --chain=legacy --components api,tree,eth,state_keeper,housekeeper,commitment_generator,vm_runner_protective_reads &>server.log & + ci_run zkstack chain server --uring --chain=legacy --components api,tree,eth,state_keeper,housekeeper,commitment_generator,vm_runner_protective_reads &>server.log & ci_run sleep 60 - name: Perform loadtest @@ -351,15 +351,15 @@ jobs: - name: Initialize Contract verifier run: | - ci_run zkstack contract-verifier init --zksolc-version=v1.5.3 --zkvyper-version=v1.5.4 --solc-version=0.8.26 --vyper-version=v0.3.10 --era-vm-solc-version=0.8.26-1.0.1 --only --chain era - ci_run zkstack contract-verifier run --chain era &> ${{ env.SERVER_LOGS_DIR }}/contract-verifier-rollup.log & + ci_run zkstack chain contract-verifier init --zksolc-version=v1.5.3 --zkvyper-version=v1.5.4 --solc-version=0.8.26 --vyper-version=v0.3.10 --era-vm-solc-version=0.8.26-1.0.1 --only --chain era + ci_run zkstack chain contract-verifier run --chain era &> ${{ env.SERVER_LOGS_DIR }}/contract-verifier-rollup.log & - name: Run servers run: | - ci_run zkstack server --ignore-prerequisites --chain era &> ${{ env.SERVER_LOGS_DIR }}/rollup.log & - ci_run zkstack server --ignore-prerequisites --chain validium &> ${{ env.SERVER_LOGS_DIR }}/validium.log & - ci_run zkstack server --ignore-prerequisites --chain custom_token &> ${{ env.SERVER_LOGS_DIR }}/custom_token.log & - ci_run zkstack server --ignore-prerequisites --chain consensus \ + ci_run zkstack chain server --ignore-prerequisites --chain era &> ${{ env.SERVER_LOGS_DIR }}/rollup.log & + ci_run zkstack chain server --ignore-prerequisites --chain validium &> ${{ env.SERVER_LOGS_DIR }}/validium.log & + ci_run zkstack chain server --ignore-prerequisites --chain custom_token &> ${{ env.SERVER_LOGS_DIR }}/custom_token.log & + ci_run zkstack chain server --ignore-prerequisites --chain consensus \ --components=api,tree,eth,state_keeper,housekeeper,commitment_generator,vm_runner_protective_reads,vm_runner_bwip,vm_playground,da_dispatcher,consensus \ &> ${{ env.SERVER_LOGS_DIR }}/consensus.log & @@ -367,7 +367,7 @@ jobs: - name: Setup attester committee for the consensus chain run: | - ci_run zkstack consensus set-attester-committee --chain consensus --from-genesis &> ${{ env.INTEGRATION_TESTS_LOGS_DIR }}/consensus.log + ci_run zkstack chain consensus set-attester-committee --chain consensus --from-genesis &> ${{ env.INTEGRATION_TESTS_LOGS_DIR }}/consensus.log - name: Run integration tests run: | diff --git a/zkstack_cli/crates/config/src/chain.rs b/zkstack_cli/crates/config/src/chain.rs index 6c82d6ef3c3..f1983fd92ec 100644 --- a/zkstack_cli/crates/config/src/chain.rs +++ b/zkstack_cli/crates/config/src/chain.rs @@ -3,6 +3,7 @@ use std::{ path::{Path, PathBuf}, }; +use anyhow::bail; use serde::{Deserialize, Serialize, Serializer}; use types::{BaseToken, L1BatchCommitmentMode, L1Network, ProverMode, WalletCreation}; use xshell::Shell; @@ -18,7 +19,8 @@ use crate::{ FileConfigWithDefaultName, ReadConfig, ReadConfigWithBasePath, SaveConfig, SaveConfigWithBasePath, ZkStackConfig, }, - ContractsConfig, GeneralConfig, GenesisConfig, SecretsConfig, WalletsConfig, + utils::find_file, + ContractsConfig, EcosystemConfig, GeneralConfig, GenesisConfig, SecretsConfig, WalletsConfig, }; /// Chain configuration file. This file is created in the chain @@ -33,6 +35,8 @@ pub struct ChainConfigInternal { pub prover_version: ProverMode, pub configs: PathBuf, pub rocks_db_path: PathBuf, + pub l1_network: Option, + pub link_to_code: Option, pub external_node_config_path: Option, pub artifacts_path: Option, pub l1_batch_commit_data_generator_mode: L1BatchCommitmentMode, @@ -97,6 +101,7 @@ impl ChainConfig { } anyhow::bail!("Wallets configs has not been found"); } + pub fn get_contracts_config(&self) -> anyhow::Result { ContractsConfig::read_with_base_path(self.get_shell(), &self.configs) } @@ -153,6 +158,8 @@ impl ChainConfig { rocks_db_path: self.rocks_db_path.clone(), external_node_config_path: self.external_node_config_path.clone(), artifacts_path: Some(self.artifacts.clone()), + l1_network: Some(self.l1_network), + link_to_code: Some(self.link_to_code.clone()), l1_batch_commit_data_generator_mode: self.l1_batch_commit_data_generator_mode, base_token: self.base_token.clone(), wallet_creation: self.wallet_creation, @@ -161,6 +168,28 @@ impl ChainConfig { } } +impl ChainConfigInternal { + pub fn from_file(shell: &Shell) -> anyhow::Result { + let Ok(path) = find_file(shell, shell.current_dir(), CONFIG_NAME) else { + bail!("Chain config not found") + }; + + shell.change_dir(&path); + + match ChainConfigInternal::read(shell, CONFIG_NAME) { + Ok(config) => Ok(config), + Err(err) => { + if let Ok(ecosystem) = EcosystemConfig::read(shell, CONFIG_NAME) { + let chain = ecosystem.load_current_chain()?; + Ok(chain.get_internal()) + } else { + Err(err) + } + } + } + } +} + impl FileConfigWithDefaultName for ChainConfigInternal { const FILE_NAME: &'static str = CONFIG_NAME; } diff --git a/zkstack_cli/crates/config/src/consts.rs b/zkstack_cli/crates/config/src/consts.rs index f462ce33b8f..360e3fffa3b 100644 --- a/zkstack_cli/crates/config/src/consts.rs +++ b/zkstack_cli/crates/config/src/consts.rs @@ -36,8 +36,8 @@ pub(crate) const LOCAL_APPS_PATH: &str = "apps/"; pub(crate) const LOCAL_CHAINS_PATH: &str = "chains/"; pub(crate) const LOCAL_CONFIGS_PATH: &str = "configs/"; pub(crate) const LOCAL_GENERATED_PATH: &str = ".generated/"; -pub(crate) const LOCAL_DB_PATH: &str = "db/"; -pub(crate) const LOCAL_ARTIFACTS_PATH: &str = "artifacts/"; +pub const LOCAL_DB_PATH: &str = "db/"; +pub const LOCAL_ARTIFACTS_PATH: &str = "artifacts/"; /// Name of apps config file pub const APPS_CONFIG_FILE: &str = "apps.yaml"; diff --git a/zkstack_cli/crates/config/src/ecosystem.rs b/zkstack_cli/crates/config/src/ecosystem.rs index 79cb1c4ea27..510b9e3101a 100644 --- a/zkstack_cli/crates/config/src/ecosystem.rs +++ b/zkstack_cli/crates/config/src/ecosystem.rs @@ -22,6 +22,7 @@ use crate::{ output::{ERC20Tokens, Erc20Token}, }, traits::{FileConfigWithDefaultName, ReadConfig, SaveConfig, ZkStackConfig}, + utils::find_file, ChainConfig, ChainConfigInternal, ContractsConfig, WalletsConfig, }; @@ -282,20 +283,6 @@ pub fn get_default_era_chain_id() -> L2ChainId { L2ChainId::from(ERA_CHAIN_ID) } -// Find file in all parents repository and return necessary path or an empty error if nothing has been found -fn find_file(shell: &Shell, path_buf: PathBuf, file_name: &str) -> Result { - let _dir = shell.push_dir(path_buf); - if shell.path_exists(file_name) { - Ok(shell.current_dir()) - } else { - let current_dir = shell.current_dir(); - let Some(path) = current_dir.parent() else { - return Err(()); - }; - find_file(shell, path.to_path_buf(), file_name) - } -} - pub fn get_link_to_prover(config: &EcosystemConfig) -> PathBuf { let link_to_code = config.link_to_code.clone(); let mut link_to_prover = link_to_code.into_os_string(); diff --git a/zkstack_cli/crates/config/src/lib.rs b/zkstack_cli/crates/config/src/lib.rs index b449aefe3a2..f3001fd55f8 100644 --- a/zkstack_cli/crates/config/src/lib.rs +++ b/zkstack_cli/crates/config/src/lib.rs @@ -22,6 +22,7 @@ mod general; mod genesis; mod manipulations; mod secrets; +mod utils; mod wallet_creation; mod wallets; @@ -34,3 +35,4 @@ pub mod external_node; pub mod forge_interface; pub mod portal; pub mod traits; +pub mod zkstack_config; diff --git a/zkstack_cli/crates/config/src/utils.rs b/zkstack_cli/crates/config/src/utils.rs new file mode 100644 index 00000000000..63cf2cf601f --- /dev/null +++ b/zkstack_cli/crates/config/src/utils.rs @@ -0,0 +1,17 @@ +use std::path::PathBuf; + +use xshell::Shell; + +// Find file in all parents repository and return necessary path or an empty error if nothing has been found +pub fn find_file(shell: &Shell, path_buf: PathBuf, file_name: &str) -> Result { + let _dir = shell.push_dir(path_buf); + if shell.path_exists(file_name) { + Ok(shell.current_dir()) + } else { + let current_dir = shell.current_dir(); + let Some(path) = current_dir.parent() else { + return Err(()); + }; + find_file(shell, path.to_path_buf(), file_name) + } +} diff --git a/zkstack_cli/crates/config/src/zkstack_config.rs b/zkstack_cli/crates/config/src/zkstack_config.rs new file mode 100644 index 00000000000..e2b9585a17f --- /dev/null +++ b/zkstack_cli/crates/config/src/zkstack_config.rs @@ -0,0 +1,55 @@ +use anyhow::Context; +use xshell::Shell; + +use crate::{ChainConfig, ChainConfigInternal, EcosystemConfig}; + +pub enum ZkStackConfig { + EcosystemConfig(EcosystemConfig), + ChainConfig(ChainConfig), +} + +impl ZkStackConfig { + fn from_file(shell: &Shell) -> anyhow::Result { + if let Ok(ecosystem) = EcosystemConfig::from_file(shell) { + Ok(ZkStackConfig::EcosystemConfig(ecosystem)) + } else { + let chain_internal = ChainConfigInternal::from_file(shell)?; + + let l1_network = chain_internal.l1_network.context("L1 Network not found")?; + let link_to_code = chain_internal + .link_to_code + .context("Link to code not found")?; + let artifacts = chain_internal + .artifacts_path + .context("Artifacts path not found")?; + + let chain = ChainConfig { + id: chain_internal.id, + name: chain_internal.name, + chain_id: chain_internal.chain_id, + prover_version: chain_internal.prover_version, + configs: chain_internal.configs, + rocks_db_path: chain_internal.rocks_db_path, + external_node_config_path: chain_internal.external_node_config_path, + l1_network, + l1_batch_commit_data_generator_mode: chain_internal + .l1_batch_commit_data_generator_mode, + base_token: chain_internal.base_token, + wallet_creation: chain_internal.wallet_creation, + legacy_bridge: chain_internal.legacy_bridge, + link_to_code, + artifacts, + shell: shell.clone().into(), + }; + + Ok(ZkStackConfig::ChainConfig(chain)) + } + } + + pub fn load_current_chain(shell: &Shell) -> anyhow::Result { + match ZkStackConfig::from_file(shell)? { + ZkStackConfig::EcosystemConfig(ecosystem) => ecosystem.load_current_chain(), + ZkStackConfig::ChainConfig(chain) => Ok(chain), + } + } +} diff --git a/zkstack_cli/crates/zkstack/build.rs b/zkstack_cli/crates/zkstack/build.rs index 92f34a542b7..17a5c6e6fe2 100644 --- a/zkstack_cli/crates/zkstack/build.rs +++ b/zkstack_cli/crates/zkstack/build.rs @@ -9,7 +9,7 @@ fn main() -> eyre::Result<()> { .write_to_file(outdir.join("consensus_registry_abi.rs"))?; zksync_protobuf_build::Config { - input_root: "src/commands/consensus/proto".into(), + input_root: "src/commands/chain/consensus/proto".into(), proto_root: "zksync/toolbox/consensus".into(), dependencies: vec!["::zksync_protobuf_config::proto".parse().unwrap()], protobuf_crate: "::zksync_protobuf".parse().unwrap(), diff --git a/zkstack_cli/crates/zkstack/src/commands/args/mod.rs b/zkstack_cli/crates/zkstack/src/commands/args/mod.rs index d18b05c910e..1a51d60cd09 100644 --- a/zkstack_cli/crates/zkstack/src/commands/args/mod.rs +++ b/zkstack_cli/crates/zkstack/src/commands/args/mod.rs @@ -1,7 +1,5 @@ pub use containers::*; -pub use run_server::*; pub use update::*; mod containers; -mod run_server; mod update; diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/args/create.rs b/zkstack_cli/crates/zkstack/src/commands/chain/args/create.rs index 5fc46c1b227..507e9c01e1c 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/args/create.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/args/create.rs @@ -8,7 +8,8 @@ use serde::{Deserialize, Serialize}; use slugify_rs::slugify; use strum::{Display, EnumIter, IntoEnumIterator}; use types::{BaseToken, L1BatchCommitmentMode, L1Network, ProverMode, WalletCreation}; -use zksync_basic_types::H160; +use xshell::Shell; +use zksync_basic_types::{L2ChainId, H160}; use crate::{ defaults::L2_CHAIN_ID, @@ -19,12 +20,13 @@ use crate::{ MSG_BASE_TOKEN_PRICE_NOMINATOR_PROMPT, MSG_BASE_TOKEN_SELECTION_PROMPT, MSG_CHAIN_ID_HELP, MSG_CHAIN_ID_PROMPT, MSG_CHAIN_ID_VALIDATOR_ERR, MSG_CHAIN_NAME_PROMPT, MSG_L1_BATCH_COMMIT_DATA_GENERATOR_MODE_PROMPT, MSG_L1_COMMIT_DATA_GENERATOR_MODE_HELP, - MSG_NUMBER_VALIDATOR_GREATHER_THAN_ZERO_ERR, MSG_NUMBER_VALIDATOR_NOT_ZERO_ERR, - MSG_PROVER_MODE_HELP, MSG_PROVER_VERSION_PROMPT, MSG_SET_AS_DEFAULT_HELP, - MSG_SET_AS_DEFAULT_PROMPT, MSG_WALLET_CREATION_HELP, MSG_WALLET_CREATION_PROMPT, - MSG_WALLET_CREATION_VALIDATOR_ERR, MSG_WALLET_PATH_HELP, MSG_WALLET_PATH_INVALID_ERR, - MSG_WALLET_PATH_PROMPT, + MSG_L1_NETWORK_HELP, MSG_L1_NETWORK_PROMPT, MSG_NUMBER_VALIDATOR_GREATHER_THAN_ZERO_ERR, + MSG_NUMBER_VALIDATOR_NOT_ZERO_ERR, MSG_PROVER_MODE_HELP, MSG_PROVER_VERSION_PROMPT, + MSG_SET_AS_DEFAULT_HELP, MSG_SET_AS_DEFAULT_PROMPT, MSG_WALLET_CREATION_HELP, + MSG_WALLET_CREATION_PROMPT, MSG_WALLET_CREATION_VALIDATOR_ERR, MSG_WALLET_PATH_HELP, + MSG_WALLET_PATH_INVALID_ERR, MSG_WALLET_PATH_PROMPT, }, + utils::link_to_code::get_link_to_code, }; // We need to duplicate it for using enum inside the arguments @@ -67,20 +69,28 @@ pub struct ChainCreateArgs { pub(crate) set_as_default: Option, #[clap(long, default_value = "false")] pub(crate) legacy_bridge: bool, + #[clap(long, help = MSG_L1_NETWORK_HELP, value_enum)] + pub l1_network: Option, } impl ChainCreateArgs { pub fn fill_values_with_prompt( self, + shell: &Shell, number_of_chains: u32, - l1_network: &L1Network, + l1_network: Option, possible_erc20: Vec, + chains_path: Option, + link_to_code: Option, + era_chain_id: L2ChainId, ) -> anyhow::Result { let mut chain_name = self .chain_name .unwrap_or_else(|| Prompt::new(MSG_CHAIN_NAME_PROMPT).ask()); chain_name = slugify!(&chain_name, separator = "_"); + let chain_path = chains_path.unwrap_or_default().join(&chain_name); + let chain_id = self .chain_id .map(|v| match v { @@ -93,8 +103,16 @@ impl ChainCreateArgs { .ask() }); + let l1_network = l1_network.unwrap_or_else(|| { + self.l1_network.unwrap_or_else(|| { + PromptSelect::new(MSG_L1_NETWORK_PROMPT, L1Network::iter()).ask() + }) + }); + + let link_to_code = link_to_code.unwrap_or_else(|| get_link_to_code(shell)); + let wallet_creation = if let Some(wallet) = self.wallet_creation { - if wallet == WalletCreation::Localhost && *l1_network != L1Network::Localhost { + if wallet == WalletCreation::Localhost && l1_network != L1Network::Localhost { bail!(MSG_WALLET_CREATION_VALIDATOR_ERR); } else { wallet @@ -104,7 +122,7 @@ impl ChainCreateArgs { MSG_WALLET_CREATION_PROMPT, WalletCreation::iter().filter(|wallet| { // Disable localhost wallets for external networks - if *l1_network == L1Network::Localhost { + if l1_network == L1Network::Localhost { true } else { *wallet != WalletCreation::Localhost @@ -212,6 +230,9 @@ impl ChainCreateArgs { }; let set_as_default = self.set_as_default.unwrap_or_else(|| { + if number_of_chains == 0 { + return true; + } PromptConfirm::new(MSG_SET_AS_DEFAULT_PROMPT) .default(true) .ask() @@ -227,6 +248,11 @@ impl ChainCreateArgs { base_token, set_as_default, legacy_bridge: self.legacy_bridge, + chain_path, + era_chain_id, + number_of_chains, + l1_network, + link_to_code, }) } } @@ -242,6 +268,11 @@ pub struct ChainCreateArgsFinal { pub base_token: BaseToken, pub set_as_default: bool, pub legacy_bridge: bool, + pub chain_path: PathBuf, + pub era_chain_id: L2ChainId, + pub number_of_chains: u32, + pub l1_network: L1Network, + pub link_to_code: String, } #[derive(Debug, Clone, EnumIter, Display, PartialEq, Eq)] diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/args/mod.rs b/zkstack_cli/crates/zkstack/src/commands/chain/args/mod.rs index f2a5f6b8be1..ab4580a5250 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/args/mod.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/args/mod.rs @@ -2,3 +2,4 @@ pub mod build_transactions; pub mod create; pub mod genesis; pub mod init; +pub mod run_server; diff --git a/zkstack_cli/crates/zkstack/src/commands/args/run_server.rs b/zkstack_cli/crates/zkstack/src/commands/chain/args/run_server.rs similarity index 100% rename from zkstack_cli/crates/zkstack/src/commands/args/run_server.rs rename to zkstack_cli/crates/zkstack/src/commands/chain/args/run_server.rs diff --git a/zkstack_cli/crates/zkstack/src/commands/consensus/conv.rs b/zkstack_cli/crates/zkstack/src/commands/chain/consensus/conv.rs similarity index 100% rename from zkstack_cli/crates/zkstack/src/commands/consensus/conv.rs rename to zkstack_cli/crates/zkstack/src/commands/chain/consensus/conv.rs diff --git a/zkstack_cli/crates/zkstack/src/commands/consensus/mod.rs b/zkstack_cli/crates/zkstack/src/commands/chain/consensus/mod.rs similarity index 96% rename from zkstack_cli/crates/zkstack/src/commands/consensus/mod.rs rename to zkstack_cli/crates/zkstack/src/commands/chain/consensus/mod.rs index 1855a5943dc..4894f0b2551 100644 --- a/zkstack_cli/crates/zkstack/src/commands/consensus/mod.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/consensus/mod.rs @@ -3,8 +3,9 @@ use std::{borrow::Borrow, collections::HashMap, path::PathBuf, sync::Arc}; /// Consensus registry contract operations. /// Includes code duplicated from `zksync_node_consensus::registry::abi`. use anyhow::Context as _; +use clap::Parser; use common::{logger, wallets::Wallet}; -use config::EcosystemConfig; +use config::zkstack_config::ZkStackConfig; use conv::*; use ethers::{ abi::Detokenize, @@ -18,7 +19,10 @@ use xshell::Shell; use zksync_consensus_crypto::ByteFmt; use zksync_consensus_roles::{attester, validator}; -use crate::{messages, utils::consensus::parse_attester_committee}; +use crate::{ + messages::{self}, + utils::consensus::parse_attester_committee, +}; mod conv; mod proto; @@ -71,9 +75,9 @@ fn encode_validator_pop(pop: &validator::ProofOfPossession) -> abi::Bls12381Sign } } -#[derive(clap::Args, Debug)] +#[derive(Debug, Clone, Parser, Default)] #[group(required = true, multiple = false)] -pub struct SetAttesterCommitteeCommand { +pub struct SetAttesterCommitteeArgs { /// Sets the attester committee in the consensus registry contract to /// `consensus.genesis_spec.attesters` in general.yaml. #[clap(long)] @@ -86,10 +90,10 @@ pub struct SetAttesterCommitteeCommand { } #[derive(clap::Subcommand, Debug)] -pub enum Command { +pub enum ConsensusCommand { /// Sets the attester committee in the consensus registry contract to /// `consensus.genesis_spec.attesters` in general.yaml. - SetAttesterCommittee(SetAttesterCommitteeCommand), + SetAttesterCommittee(SetAttesterCommitteeArgs), /// Fetches the attester committee from the consensus registry contract. GetAttesterCommittee, } @@ -192,11 +196,7 @@ impl Setup { } fn new(shell: &Shell) -> anyhow::Result { - let ecosystem_config = - EcosystemConfig::from_file(shell).context("EcosystemConfig::from_file()")?; - let chain = ecosystem_config - .load_current_chain() - .context(messages::MSG_CHAIN_NOT_INITIALIZED)?; + let chain = ZkStackConfig::load_current_chain(shell)?; let contracts = chain .get_contracts_config() .context("get_contracts_config()")?; @@ -249,7 +249,7 @@ impl Setup { fn read_attester_committee( &self, - opts: &SetAttesterCommitteeCommand, + opts: &SetAttesterCommitteeArgs, ) -> anyhow::Result { // Fetch the desired state. if let Some(path) = &opts.from_file { @@ -390,7 +390,7 @@ impl Setup { } } -impl Command { +impl ConsensusCommand { pub(crate) async fn run(self, shell: &Shell) -> anyhow::Result<()> { let setup = Setup::new(shell).context("Setup::new()")?; match self { diff --git a/zkstack_cli/crates/zkstack/src/commands/consensus/proto/mod.proto b/zkstack_cli/crates/zkstack/src/commands/chain/consensus/proto/mod.proto similarity index 100% rename from zkstack_cli/crates/zkstack/src/commands/consensus/proto/mod.proto rename to zkstack_cli/crates/zkstack/src/commands/chain/consensus/proto/mod.proto diff --git a/zkstack_cli/crates/zkstack/src/commands/consensus/proto/mod.rs b/zkstack_cli/crates/zkstack/src/commands/chain/consensus/proto/mod.rs similarity index 56% rename from zkstack_cli/crates/zkstack/src/commands/consensus/proto/mod.rs rename to zkstack_cli/crates/zkstack/src/commands/chain/consensus/proto/mod.rs index 61a0a047f0a..1fe69ac251c 100644 --- a/zkstack_cli/crates/zkstack/src/commands/consensus/proto/mod.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/consensus/proto/mod.rs @@ -2,5 +2,5 @@ include!(concat!( env!("OUT_DIR"), - "/src/commands/consensus/proto/gen.rs" + "/src/commands/chain/consensus/proto/gen.rs" )); diff --git a/zkstack_cli/crates/zkstack/src/commands/consensus/tests.rs b/zkstack_cli/crates/zkstack/src/commands/chain/consensus/tests.rs similarity index 100% rename from zkstack_cli/crates/zkstack/src/commands/consensus/tests.rs rename to zkstack_cli/crates/zkstack/src/commands/chain/consensus/tests.rs diff --git a/zkstack_cli/crates/zkstack/src/commands/contract_verifier/args/init.rs b/zkstack_cli/crates/zkstack/src/commands/chain/contract_verifier/args/init.rs similarity index 100% rename from zkstack_cli/crates/zkstack/src/commands/contract_verifier/args/init.rs rename to zkstack_cli/crates/zkstack/src/commands/chain/contract_verifier/args/init.rs diff --git a/zkstack_cli/crates/zkstack/src/commands/contract_verifier/args/mod.rs b/zkstack_cli/crates/zkstack/src/commands/chain/contract_verifier/args/mod.rs similarity index 100% rename from zkstack_cli/crates/zkstack/src/commands/contract_verifier/args/mod.rs rename to zkstack_cli/crates/zkstack/src/commands/chain/contract_verifier/args/mod.rs diff --git a/zkstack_cli/crates/zkstack/src/commands/contract_verifier/args/releases.rs b/zkstack_cli/crates/zkstack/src/commands/chain/contract_verifier/args/releases.rs similarity index 100% rename from zkstack_cli/crates/zkstack/src/commands/contract_verifier/args/releases.rs rename to zkstack_cli/crates/zkstack/src/commands/chain/contract_verifier/args/releases.rs diff --git a/zkstack_cli/crates/zkstack/src/commands/contract_verifier/init.rs b/zkstack_cli/crates/zkstack/src/commands/chain/contract_verifier/init.rs similarity index 92% rename from zkstack_cli/crates/zkstack/src/commands/contract_verifier/init.rs rename to zkstack_cli/crates/zkstack/src/commands/chain/contract_verifier/init.rs index b173ad9bbb7..ffa2bfd470b 100644 --- a/zkstack_cli/crates/zkstack/src/commands/contract_verifier/init.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/contract_verifier/init.rs @@ -1,16 +1,16 @@ use std::path::{Path, PathBuf}; use common::{cmd::Cmd, logger, spinner::Spinner}; -use config::EcosystemConfig; +use config::zkstack_config::ZkStackConfig; use xshell::{cmd, Shell}; 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<()> { +pub(crate) 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 chain = ZkStackConfig::load_current_chain(shell)?; + let link_to_code = chain.link_to_code; download_binaries( shell, diff --git a/zkstack_cli/crates/zkstack/src/commands/contract_verifier/mod.rs b/zkstack_cli/crates/zkstack/src/commands/chain/contract_verifier/mod.rs similarity index 90% rename from zkstack_cli/crates/zkstack/src/commands/contract_verifier/mod.rs rename to zkstack_cli/crates/zkstack/src/commands/chain/contract_verifier/mod.rs index 78bdc5fae7e..3e3d9b266e8 100644 --- a/zkstack_cli/crates/zkstack/src/commands/contract_verifier/mod.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/contract_verifier/mod.rs @@ -2,9 +2,9 @@ use args::init::InitContractVerifierArgs; use clap::Subcommand; use xshell::Shell; -pub mod args; -pub mod init; -pub mod run; +mod args; +mod init; +mod run; #[derive(Subcommand, Debug)] pub enum ContractVerifierCommands { @@ -17,6 +17,6 @@ pub enum ContractVerifierCommands { 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, + ContractVerifierCommands::Init(args) => init::run(shell, args), } } diff --git a/zkstack_cli/crates/zkstack/src/commands/contract_verifier/run.rs b/zkstack_cli/crates/zkstack/src/commands/chain/contract_verifier/run.rs similarity index 69% rename from zkstack_cli/crates/zkstack/src/commands/contract_verifier/run.rs rename to zkstack_cli/crates/zkstack/src/commands/chain/contract_verifier/run.rs index 9913ec817e9..ea3245a2e51 100644 --- a/zkstack_cli/crates/zkstack/src/commands/contract_verifier/run.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/contract_verifier/run.rs @@ -1,17 +1,15 @@ use anyhow::Context; use common::{cmd::Cmd, logger}; -use config::EcosystemConfig; +use config::zkstack_config::ZkStackConfig; use xshell::{cmd, Shell}; use crate::messages::{ - MSG_CHAIN_NOT_FOUND_ERR, MSG_FAILED_TO_RUN_CONTRACT_VERIFIER_ERR, MSG_RUNNING_CONTRACT_VERIFIER, + MSG_CHAIN_NOT_INITIALIZED, 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_current_chain() - .context(MSG_CHAIN_NOT_FOUND_ERR)?; + let chain = ZkStackConfig::load_current_chain(shell).context(MSG_CHAIN_NOT_INITIALIZED)?; let config_path = chain.path_to_general_config(); let secrets_path = chain.path_to_secrets_config(); diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/create.rs b/zkstack_cli/crates/zkstack/src/commands/chain/create.rs index 48a320ec27e..659f5c83797 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/create.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/create.rs @@ -3,8 +3,9 @@ use std::cell::OnceCell; use anyhow::Context; use common::{logger, spinner::Spinner}; use config::{ - create_local_configs_dir, create_wallets, traits::SaveConfigWithBasePath, ChainConfig, - EcosystemConfig, + create_local_configs_dir, create_wallets, get_default_era_chain_id, + traits::SaveConfigWithBasePath, ChainConfig, EcosystemConfig, LOCAL_ARTIFACTS_PATH, + LOCAL_DB_PATH, }; use xshell::Shell; use zksync_basic_types::L2ChainId; @@ -15,24 +16,53 @@ use crate::{ MSG_ARGS_VALIDATOR_ERR, MSG_CHAIN_CREATED, MSG_CREATING_CHAIN, MSG_CREATING_CHAIN_CONFIGURATIONS_SPINNER, MSG_SELECTED_CONFIG, }, + utils::link_to_code::resolve_link_to_code, }; pub fn run(args: ChainCreateArgs, shell: &Shell) -> anyhow::Result<()> { - let mut ecosystem_config = EcosystemConfig::from_file(shell)?; + let mut ecosystem_config = EcosystemConfig::from_file(shell).ok(); create(args, &mut ecosystem_config, shell) } fn create( args: ChainCreateArgs, - ecosystem_config: &mut EcosystemConfig, + ecosystem: &mut Option, shell: &Shell, ) -> anyhow::Result<()> { - let tokens = ecosystem_config.get_erc20_tokens(); + let possible_erc20 = ecosystem + .as_ref() + .map(|ecosystem| ecosystem.get_erc20_tokens()) + .unwrap_or(vec![]); + + let number_of_chains = ecosystem + .as_ref() + .map(|ecosystem| ecosystem.list_of_chains().len() as u32) + .unwrap_or(0); + + let l1_network = ecosystem + .as_ref() + .map(|ecosystem| ecosystem.l1_network.clone()); + + let chains_path = ecosystem.as_ref().map(|ecosystem| ecosystem.chains.clone()); + + let era_chain_id = ecosystem + .as_ref() + .map(|ecosystem| ecosystem.era_chain_id) + .unwrap_or(get_default_era_chain_id()); + + let link_to_code = ecosystem + .as_ref() + .map(|ecosystem| ecosystem.link_to_code.clone().display().to_string()); + let args = args .fill_values_with_prompt( - ecosystem_config.list_of_chains().len() as u32, - &ecosystem_config.l1_network, - tokens, + shell, + number_of_chains, + l1_network, + possible_erc20, + chains_path, + link_to_code, + era_chain_id, ) .context(MSG_ARGS_VALIDATOR_ERR)?; @@ -42,10 +72,12 @@ fn create( let spinner = Spinner::new(MSG_CREATING_CHAIN_CONFIGURATIONS_SPINNER); let name = args.chain_name.clone(); let set_as_default = args.set_as_default; - create_chain_inner(args, ecosystem_config, shell)?; - if set_as_default { - ecosystem_config.default_chain = name; - ecosystem_config.save_with_base_path(shell, ".")?; + create_chain_inner(args, shell)?; + if let Some(ecosystem) = ecosystem { + if set_as_default { + ecosystem.default_chain = name; + ecosystem.save_with_base_path(shell, ".")?; + } } spinner.finish(); @@ -54,34 +86,33 @@ fn create( Ok(()) } -pub(crate) fn create_chain_inner( - args: ChainCreateArgsFinal, - ecosystem_config: &EcosystemConfig, - shell: &Shell, -) -> anyhow::Result<()> { +pub(crate) fn create_chain_inner(args: ChainCreateArgsFinal, shell: &Shell) -> anyhow::Result<()> { if args.legacy_bridge { logger::warn("WARNING!!! You are creating a chain with legacy bridge, use it only for testing compatibility") } let default_chain_name = args.chain_name.clone(); - let chain_path = ecosystem_config.chains.join(&default_chain_name); + let chain_path = args.chain_path; let chain_configs_path = create_local_configs_dir(shell, &chain_path)?; let (chain_id, legacy_bridge) = if args.legacy_bridge { // Legacy bridge is distinguished by using the same chain id as ecosystem - (ecosystem_config.era_chain_id, Some(true)) + (args.era_chain_id, Some(true)) } else { (L2ChainId::from(args.chain_id), None) }; - let internal_id = ecosystem_config.list_of_chains().len() as u32; + let internal_id = args.number_of_chains; + let link_to_code = resolve_link_to_code(shell, chain_path.clone(), args.link_to_code.clone())?; + let rocks_db_path = chain_path.join(LOCAL_DB_PATH); + let artifacts = chain_path.join(LOCAL_ARTIFACTS_PATH); let chain_config = ChainConfig { id: internal_id, name: default_chain_name.clone(), chain_id, prover_version: args.prover_version, - l1_network: ecosystem_config.l1_network, - link_to_code: ecosystem_config.link_to_code.clone(), - rocks_db_path: ecosystem_config.get_chain_rocks_db_path(&default_chain_name), - artifacts: ecosystem_config.get_chain_artifacts_path(&default_chain_name), + l1_network: args.l1_network, + link_to_code: link_to_code.clone(), + rocks_db_path, + artifacts, configs: chain_configs_path.clone(), external_node_config_path: None, l1_batch_commit_data_generator_mode: args.l1_batch_commit_data_generator_mode, @@ -94,7 +125,7 @@ pub(crate) fn create_chain_inner( create_wallets( shell, &chain_config.configs, - &ecosystem_config.link_to_code, + &link_to_code, internal_id, args.wallet_creation, args.wallet_path, diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/deploy_paymaster.rs b/zkstack_cli/crates/zkstack/src/commands/chain/deploy_paymaster.rs index 4a93fcc089f..e2dd32c46e1 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/deploy_paymaster.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/deploy_paymaster.rs @@ -6,7 +6,8 @@ use config::{ script_params::DEPLOY_PAYMASTER_SCRIPT_PARAMS, }, traits::{ReadConfig, SaveConfig, SaveConfigWithBasePath}, - ChainConfig, ContractsConfig, EcosystemConfig, + zkstack_config::ZkStackConfig, + ChainConfig, ContractsConfig, }; use xshell::Shell; @@ -16,10 +17,8 @@ use crate::{ }; pub async fn run(args: ForgeScriptArgs, shell: &Shell) -> anyhow::Result<()> { - let ecosystem_config = EcosystemConfig::from_file(shell)?; - let chain_config = ecosystem_config - .load_current_chain() - .context(MSG_CHAIN_NOT_INITIALIZED)?; + let chain_config = + ZkStackConfig::load_current_chain(shell).context(MSG_CHAIN_NOT_INITIALIZED)?; let mut contracts = chain_config.get_contracts_config()?; deploy_paymaster(shell, &chain_config, &mut contracts, args, None, true).await?; contracts.save_with_base_path(shell, chain_config.configs) diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/genesis/database.rs b/zkstack_cli/crates/zkstack/src/commands/chain/genesis/database.rs index edf480946be..22ba6e1c355 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/genesis/database.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/genesis/database.rs @@ -8,7 +8,7 @@ use common::{ }; use config::{ override_config, set_file_artifacts, set_rocks_db_config, set_server_database, - traits::SaveConfigWithBasePath, ChainConfig, EcosystemConfig, FileArtifacts, + traits::SaveConfigWithBasePath, zkstack_config::ZkStackConfig, ChainConfig, FileArtifacts, }; use types::ProverMode; use xshell::Shell; @@ -21,18 +21,14 @@ use crate::{ SERVER_MIGRATIONS, }, messages::{ - MSG_CHAIN_NOT_INITIALIZED, MSG_FAILED_TO_DROP_SERVER_DATABASE_ERR, - MSG_GENESIS_DATABASES_INITIALIZED, MSG_INITIALIZING_SERVER_DATABASE, - MSG_RECREATE_ROCKS_DB_ERRROR, + MSG_FAILED_TO_DROP_SERVER_DATABASE_ERR, MSG_GENESIS_DATABASES_INITIALIZED, + MSG_INITIALIZING_SERVER_DATABASE, MSG_RECREATE_ROCKS_DB_ERRROR, }, utils::rocks_db::{recreate_rocksdb_dirs, RocksDBDirOption}, }; pub async fn run(args: GenesisArgs, shell: &Shell) -> anyhow::Result<()> { - let ecosystem_config = EcosystemConfig::from_file(shell)?; - let chain_config = ecosystem_config - .load_current_chain() - .context(MSG_CHAIN_NOT_INITIALIZED)?; + let chain_config = ZkStackConfig::load_current_chain(shell)?; let mut secrets = chain_config.get_secrets_config()?; let args = args.fill_values_with_secrets(&chain_config)?; diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/genesis/mod.rs b/zkstack_cli/crates/zkstack/src/commands/chain/genesis/mod.rs index c1cc03174ae..388c8a239fa 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/genesis/mod.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/genesis/mod.rs @@ -1,7 +1,6 @@ -use anyhow::Context; use clap::{command, Parser, Subcommand}; use common::{logger, spinner::Spinner}; -use config::{ChainConfig, EcosystemConfig}; +use config::{zkstack_config::ZkStackConfig, ChainConfig}; use xshell::Shell; use crate::{ @@ -10,8 +9,8 @@ use crate::{ genesis::{self, database::initialize_server_database, server::run_server_genesis}, }, messages::{ - MSG_CHAIN_NOT_INITIALIZED, MSG_GENESIS_COMPLETED, MSG_INITIALIZING_DATABASES_SPINNER, - MSG_SELECTED_CONFIG, MSG_STARTING_GENESIS, MSG_STARTING_GENESIS_SPINNER, + MSG_GENESIS_COMPLETED, MSG_INITIALIZING_DATABASES_SPINNER, MSG_SELECTED_CONFIG, + MSG_STARTING_GENESIS, MSG_STARTING_GENESIS_SPINNER, }, }; @@ -46,10 +45,7 @@ pub(crate) async fn run(args: GenesisCommand, shell: &Shell) -> anyhow::Result<( } pub async fn run_genesis(args: GenesisArgs, shell: &Shell) -> anyhow::Result<()> { - let ecosystem_config = EcosystemConfig::from_file(shell)?; - let chain_config = ecosystem_config - .load_current_chain() - .context(MSG_CHAIN_NOT_INITIALIZED)?; + let chain_config = ZkStackConfig::load_current_chain(shell)?; let args = args.fill_values_with_prompt(&chain_config); genesis(args, shell, &chain_config).await?; diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/genesis/server.rs b/zkstack_cli/crates/zkstack/src/commands/chain/genesis/server.rs index 50a74b7ea9e..c1e6e4e0d5a 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/genesis/server.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/genesis/server.rs @@ -5,21 +5,17 @@ use common::{ spinner::Spinner, }; use config::{ - traits::FileConfigWithDefaultName, ChainConfig, ContractsConfig, EcosystemConfig, + traits::FileConfigWithDefaultName, zkstack_config::ZkStackConfig, ChainConfig, ContractsConfig, GeneralConfig, GenesisConfig, SecretsConfig, WalletsConfig, }; use xshell::Shell; use crate::messages::{ - MSG_CHAIN_NOT_INITIALIZED, MSG_FAILED_TO_RUN_SERVER_ERR, MSG_GENESIS_COMPLETED, - MSG_STARTING_GENESIS_SPINNER, + MSG_FAILED_TO_RUN_SERVER_ERR, MSG_GENESIS_COMPLETED, MSG_STARTING_GENESIS_SPINNER, }; pub async fn run(shell: &Shell) -> anyhow::Result<()> { - let ecosystem_config = EcosystemConfig::from_file(shell)?; - let chain_config = ecosystem_config - .load_current_chain() - .context(MSG_CHAIN_NOT_INITIALIZED)?; + let chain_config = ZkStackConfig::load_current_chain(shell)?; let spinner = Spinner::new(MSG_STARTING_GENESIS_SPINNER); run_server_genesis(&chain_config, shell)?; diff --git a/zkstack_cli/crates/zkstack/src/commands/chain/mod.rs b/zkstack_cli/crates/zkstack/src/commands/chain/mod.rs index c9a47616486..60129f850e0 100644 --- a/zkstack_cli/crates/zkstack/src/commands/chain/mod.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/mod.rs @@ -1,7 +1,9 @@ use ::common::forge::ForgeScriptArgs; -use args::build_transactions::BuildTransactionsArgs; pub(crate) use args::create::ChainCreateArgsFinal; +use args::{build_transactions::BuildTransactionsArgs, run_server::RunServerArgs}; use clap::{command, Subcommand}; +use consensus::ConsensusCommand; +use contract_verifier::ContractVerifierCommands; pub(crate) use create::create_chain_inner; use xshell::Shell; @@ -14,12 +16,15 @@ mod accept_chain_ownership; pub(crate) mod args; mod build_transactions; mod common; +mod consensus; +pub mod contract_verifier; mod create; pub mod deploy_l2_contracts; pub mod deploy_paymaster; pub mod genesis; pub mod init; pub mod register_chain; +mod server; mod set_token_multiplier_setter; mod setup_legacy_bridge; @@ -51,7 +56,6 @@ pub enum ChainCommands { #[command(alias = "bridge")] InitializeBridges(ForgeScriptArgs), /// Deploy L2 consensus registry - #[command(alias = "consensus")] DeployConsensusRegistry(ForgeScriptArgs), /// Deploy L2 multicall3 #[command(alias = "multicall3")] @@ -64,10 +68,17 @@ pub enum ChainCommands { DeployPaymaster(ForgeScriptArgs), /// Update Token Multiplier Setter address on L1 UpdateTokenMultiplierSetter(ForgeScriptArgs), + /// Run server + Server(RunServerArgs), + /// Run contract verifier + #[command(subcommand)] + ContractVerifier(ContractVerifierCommands), + #[command(subcommand)] + Consensus(ConsensusCommand), } -pub(crate) async fn run(shell: &Shell, args: ChainCommands) -> anyhow::Result<()> { - match args { +pub(crate) async fn run(shell: &Shell, cmd: ChainCommands) -> anyhow::Result<()> { + match cmd { ChainCommands::Create(args) => create::run(args, shell), ChainCommands::Init(args) => init::run(*args, shell).await, ChainCommands::BuildTransactions(args) => build_transactions::run(args, shell).await, @@ -93,5 +104,8 @@ pub(crate) async fn run(shell: &Shell, args: ChainCommands) -> anyhow::Result<() ChainCommands::UpdateTokenMultiplierSetter(args) => { set_token_multiplier_setter::run(args, shell).await } + ChainCommands::Server(args) => server::run(shell, args), + ChainCommands::ContractVerifier(args) => contract_verifier::run(shell, args).await, + ChainCommands::Consensus(cmd) => cmd.run(shell).await, } } diff --git a/zkstack_cli/crates/zkstack/src/commands/server.rs b/zkstack_cli/crates/zkstack/src/commands/chain/server.rs similarity index 76% rename from zkstack_cli/crates/zkstack/src/commands/server.rs rename to zkstack_cli/crates/zkstack/src/commands/chain/server.rs index be7a676a825..d01d00a1b7f 100644 --- a/zkstack_cli/crates/zkstack/src/commands/server.rs +++ b/zkstack_cli/crates/zkstack/src/commands/chain/server.rs @@ -4,22 +4,16 @@ use common::{ server::{Server, ServerMode}, }; use config::{ - traits::FileConfigWithDefaultName, ChainConfig, ContractsConfig, EcosystemConfig, + traits::FileConfigWithDefaultName, zkstack_config::ZkStackConfig, ChainConfig, ContractsConfig, GeneralConfig, GenesisConfig, SecretsConfig, WalletsConfig, }; use xshell::Shell; -use crate::{ - commands::args::RunServerArgs, - messages::{MSG_CHAIN_NOT_INITIALIZED, MSG_FAILED_TO_RUN_SERVER_ERR, MSG_STARTING_SERVER}, -}; +use super::args::run_server::RunServerArgs; +use crate::messages::{MSG_FAILED_TO_RUN_SERVER_ERR, MSG_STARTING_SERVER}; pub fn run(shell: &Shell, args: RunServerArgs) -> anyhow::Result<()> { - let ecosystem_config = EcosystemConfig::from_file(shell)?; - - let chain_config = ecosystem_config - .load_current_chain() - .context(MSG_CHAIN_NOT_INITIALIZED)?; + let chain_config = ZkStackConfig::load_current_chain(shell)?; logger::info(MSG_STARTING_SERVER); diff --git a/zkstack_cli/crates/zkstack/src/commands/ecosystem/args/create.rs b/zkstack_cli/crates/zkstack/src/commands/ecosystem/args/create.rs index 2e5c50f4538..1272cda83a6 100644 --- a/zkstack_cli/crates/zkstack/src/commands/ecosystem/args/create.rs +++ b/zkstack_cli/crates/zkstack/src/commands/ecosystem/args/create.rs @@ -1,23 +1,21 @@ -use std::path::{Path, PathBuf}; +use std::path::PathBuf; -use anyhow::bail; use clap::Parser; -use common::{cmd::Cmd, logger, Prompt, PromptConfirm, PromptSelect}; +use common::{Prompt, PromptConfirm, PromptSelect}; +use config::get_default_era_chain_id; use serde::{Deserialize, Serialize}; use slugify_rs::slugify; -use strum::{EnumIter, IntoEnumIterator}; +use strum::IntoEnumIterator; use types::{L1Network, WalletCreation}; -use xshell::{cmd, Shell}; +use xshell::Shell; use crate::{ commands::chain::{args::create::ChainCreateArgs, ChainCreateArgsFinal}, messages::{ - msg_path_to_zksync_does_not_exist_err, MSG_CONFIRM_STILL_USE_FOLDER, MSG_ECOSYSTEM_NAME_PROMPT, MSG_L1_NETWORK_HELP, MSG_L1_NETWORK_PROMPT, - MSG_LINK_TO_CODE_HELP, MSG_LINK_TO_CODE_PROMPT, MSG_LINK_TO_CODE_SELECTION_CLONE, - MSG_LINK_TO_CODE_SELECTION_PATH, MSG_NOT_MAIN_REPO_OR_FORK_ERR, - MSG_REPOSITORY_ORIGIN_PROMPT, MSG_START_CONTAINERS_HELP, MSG_START_CONTAINERS_PROMPT, + MSG_LINK_TO_CODE_HELP, MSG_START_CONTAINERS_HELP, MSG_START_CONTAINERS_PROMPT, }, + utils::link_to_code::get_link_to_code, }; #[derive(Debug, Serialize, Deserialize, Parser)] @@ -47,23 +45,7 @@ impl EcosystemCreateArgs { .unwrap_or_else(|| Prompt::new(MSG_ECOSYSTEM_NAME_PROMPT).ask()); ecosystem_name = slugify!(&ecosystem_name, separator = "_"); - let link_to_code = self.link_to_code.unwrap_or_else(|| { - let link_to_code_selection = - PromptSelect::new(MSG_REPOSITORY_ORIGIN_PROMPT, LinkToCodeSelection::iter()).ask(); - match link_to_code_selection { - LinkToCodeSelection::Clone => "".to_string(), - LinkToCodeSelection::Path => { - let mut path: String = Prompt::new(MSG_LINK_TO_CODE_PROMPT).ask(); - if let Err(err) = check_link_to_code(shell, &path) { - logger::warn(err); - if !PromptConfirm::new(MSG_CONFIRM_STILL_USE_FOLDER).ask() { - path = pick_new_link_to_code(shell); - } - } - path - } - } - }); + let link_to_code = self.link_to_code.unwrap_or_else(|| get_link_to_code(shell)); let l1_network = self .l1_network @@ -71,7 +53,19 @@ impl EcosystemCreateArgs { // Make the only chain as a default one self.chain.set_as_default = Some(true); - let chain = self.chain.fill_values_with_prompt(0, &l1_network, vec![])?; + let chains_path = PathBuf::from(ecosystem_name.clone()).join("chains"); + + let era_chain_id = get_default_era_chain_id(); + + let chain = self.chain.fill_values_with_prompt( + shell, + 0, + Some(l1_network), + vec![], + Some(chains_path), + Some(link_to_code.clone()), + era_chain_id, + )?; let start_containers = self.start_containers.unwrap_or_else(|| { PromptConfirm::new(MSG_START_CONTAINERS_PROMPT) @@ -107,55 +101,3 @@ impl EcosystemCreateArgsFinal { self.chain_args.clone() } } - -#[derive(Debug, Clone, EnumIter, PartialEq, Eq)] -enum LinkToCodeSelection { - Clone, - Path, -} - -impl std::fmt::Display for LinkToCodeSelection { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - LinkToCodeSelection::Clone => write!(f, "{MSG_LINK_TO_CODE_SELECTION_CLONE}"), - LinkToCodeSelection::Path => write!(f, "{MSG_LINK_TO_CODE_SELECTION_PATH}"), - } - } -} - -fn check_link_to_code(shell: &Shell, path: &str) -> anyhow::Result<()> { - let path = Path::new(path); - if !shell.path_exists(path) { - bail!(msg_path_to_zksync_does_not_exist_err( - path.to_str().unwrap() - )); - } - - let _guard = shell.push_dir(path); - let out = String::from_utf8( - Cmd::new(cmd!(shell, "git remote -v")) - .run_with_output()? - .stdout, - )?; - - if !out.contains("matter-labs/zksync-era") { - bail!(MSG_NOT_MAIN_REPO_OR_FORK_ERR); - } - - Ok(()) -} - -fn pick_new_link_to_code(shell: &Shell) -> String { - let link_to_code: String = Prompt::new(MSG_LINK_TO_CODE_PROMPT).ask(); - match check_link_to_code(shell, &link_to_code) { - Ok(_) => link_to_code, - Err(err) => { - logger::warn(err); - if !PromptConfirm::new(MSG_CONFIRM_STILL_USE_FOLDER).ask() { - pick_new_link_to_code(shell) - } else { - link_to_code - } - } - } -} diff --git a/zkstack_cli/crates/zkstack/src/commands/ecosystem/create.rs b/zkstack_cli/crates/zkstack/src/commands/ecosystem/create.rs index 356b5322980..15c0f3e58fa 100644 --- a/zkstack_cli/crates/zkstack/src/commands/ecosystem/create.rs +++ b/zkstack_cli/crates/zkstack/src/commands/ecosystem/create.rs @@ -1,11 +1,8 @@ -use std::{path::PathBuf, str::FromStr}; - use anyhow::{bail, Context}; -use common::{git, logger, spinner::Spinner}; +use common::{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::Shell; @@ -22,11 +19,12 @@ use crate::{ }, }, messages::{ - msg_created_ecosystem, MSG_ARGS_VALIDATOR_ERR, 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, + msg_created_ecosystem, MSG_ARGS_VALIDATOR_ERR, 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, }, + utils::link_to_code::resolve_link_to_code, }; pub fn run(args: EcosystemCreateArgs, shell: &Shell) -> anyhow::Result<()> { @@ -55,21 +53,7 @@ fn create(args: EcosystemCreateArgs, shell: &Shell) -> anyhow::Result<()> { let configs_path = create_local_configs_dir(shell, ".")?; - let link_to_code = if args.link_to_code.is_empty() { - let spinner = Spinner::new(MSG_CLONING_ERA_REPO_SPINNER); - 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)?; - git::submodule_update(shell, path.clone())?; - path - }; + let link_to_code = resolve_link_to_code(shell, shell.current_dir(), args.link_to_code.clone())?; let spinner = Spinner::new(MSG_CREATING_INITIAL_CONFIGURATIONS_SPINNER); let chain_config = args.chain_config(); @@ -107,7 +91,7 @@ fn create(args: EcosystemCreateArgs, shell: &Shell) -> anyhow::Result<()> { spinner.finish(); let spinner = Spinner::new(MSG_CREATING_DEFAULT_CHAIN_SPINNER); - create_chain_inner(chain_config, &ecosystem_config, shell)?; + create_chain_inner(chain_config, shell)?; spinner.finish(); if args.start_containers { diff --git a/zkstack_cli/crates/zkstack/src/commands/mod.rs b/zkstack_cli/crates/zkstack/src/commands/mod.rs index c46400cc865..ac751ddcf91 100644 --- a/zkstack_cli/crates/zkstack/src/commands/mod.rs +++ b/zkstack_cli/crates/zkstack/src/commands/mod.rs @@ -1,13 +1,10 @@ pub mod args; pub mod chain; -pub mod consensus; pub mod containers; -pub mod contract_verifier; pub mod dev; pub mod ecosystem; pub mod explorer; pub mod external_node; pub mod portal; pub mod prover; -pub mod server; pub mod update; diff --git a/zkstack_cli/crates/zkstack/src/main.rs b/zkstack_cli/crates/zkstack/src/main.rs index 987de555ecf..e45c5a3afe8 100644 --- a/zkstack_cli/crates/zkstack/src/main.rs +++ b/zkstack_cli/crates/zkstack/src/main.rs @@ -1,7 +1,6 @@ use clap::{command, Parser, Subcommand}; use commands::{ args::{ContainersArgs, UpdateArgs}, - contract_verifier::ContractVerifierCommands, dev::DevCommands, }; use common::{ @@ -15,8 +14,8 @@ use config::EcosystemConfig; use xshell::Shell; use crate::commands::{ - args::RunServerArgs, chain::ChainCommands, consensus, ecosystem::EcosystemCommands, - explorer::ExplorerCommands, external_node::ExternalNodeCommands, prover::ProverCommands, + chain::ChainCommands, ecosystem::EcosystemCommands, explorer::ExplorerCommands, + external_node::ExternalNodeCommands, prover::ProverCommands, }; pub mod accept_ownership; @@ -53,25 +52,18 @@ pub enum InceptionSubcommands { /// Prover related commands #[command(subcommand, alias = "p")] Prover(ProverCommands), - /// Run server - Server(RunServerArgs), /// External Node related commands #[command(subcommand, alias = "en")] ExternalNode(ExternalNodeCommands), /// Run containers for local development #[command(alias = "up")] Containers(ContainersArgs), - /// Run contract verifier - #[command(subcommand)] - ContractVerifier(ContractVerifierCommands), /// Run dapp-portal Portal, /// Run block-explorer #[command(subcommand)] Explorer(ExplorerCommands), /// Update ZKsync - #[command(subcommand)] - Consensus(consensus::Command), #[command(alias = "u")] Update(UpdateArgs), #[command(hide = true)] @@ -129,16 +121,11 @@ async fn run_subcommand(inception_args: Inception, shell: &Shell) -> anyhow::Res InceptionSubcommands::Chain(args) => commands::chain::run(shell, *args).await?, InceptionSubcommands::Dev(args) => commands::dev::run(shell, args).await?, InceptionSubcommands::Prover(args) => commands::prover::run(shell, args).await?, - InceptionSubcommands::Server(args) => commands::server::run(shell, args)?, InceptionSubcommands::Containers(args) => commands::containers::run(shell, args)?, InceptionSubcommands::ExternalNode(args) => { commands::external_node::run(shell, args).await? } - InceptionSubcommands::ContractVerifier(args) => { - commands::contract_verifier::run(shell, args).await? - } InceptionSubcommands::Explorer(args) => commands::explorer::run(shell, args).await?, - InceptionSubcommands::Consensus(cmd) => cmd.run(shell).await?, InceptionSubcommands::Portal => commands::portal::run(shell).await?, InceptionSubcommands::Update(args) => commands::update::run(shell, args).await?, InceptionSubcommands::Markdown => { diff --git a/zkstack_cli/crates/zkstack/src/utils/link_to_code.rs b/zkstack_cli/crates/zkstack/src/utils/link_to_code.rs new file mode 100644 index 00000000000..0ed916f646c --- /dev/null +++ b/zkstack_cli/crates/zkstack/src/utils/link_to_code.rs @@ -0,0 +1,103 @@ +use std::{ + path::{Path, PathBuf}, + str::FromStr, +}; + +use anyhow::bail; +use common::{cmd::Cmd, git, logger, spinner::Spinner, Prompt, PromptConfirm, PromptSelect}; +use config::ZKSYNC_ERA_GIT_REPO; +use strum::{EnumIter, IntoEnumIterator}; +use xshell::{cmd, Shell}; + +use crate::messages::{ + msg_path_to_zksync_does_not_exist_err, MSG_CLONING_ERA_REPO_SPINNER, + MSG_CONFIRM_STILL_USE_FOLDER, MSG_LINK_TO_CODE_PROMPT, MSG_LINK_TO_CODE_SELECTION_CLONE, + MSG_LINK_TO_CODE_SELECTION_PATH, MSG_NOT_MAIN_REPO_OR_FORK_ERR, MSG_REPOSITORY_ORIGIN_PROMPT, +}; + +#[derive(Debug, Clone, EnumIter, PartialEq, Eq)] +enum LinkToCodeSelection { + Clone, + Path, +} + +impl std::fmt::Display for LinkToCodeSelection { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + LinkToCodeSelection::Clone => write!(f, "{MSG_LINK_TO_CODE_SELECTION_CLONE}"), + LinkToCodeSelection::Path => write!(f, "{MSG_LINK_TO_CODE_SELECTION_PATH}"), + } + } +} + +fn check_link_to_code(shell: &Shell, path: &str) -> anyhow::Result<()> { + let path = Path::new(path); + if !shell.path_exists(path) { + bail!(msg_path_to_zksync_does_not_exist_err( + path.to_str().unwrap() + )); + } + + let _guard = shell.push_dir(path); + let out = String::from_utf8( + Cmd::new(cmd!(shell, "git remote -v")) + .run_with_output()? + .stdout, + )?; + + if !out.contains("matter-labs/zksync-era") { + bail!(MSG_NOT_MAIN_REPO_OR_FORK_ERR); + } + + Ok(()) +} + +fn pick_new_link_to_code(shell: &Shell) -> String { + let link_to_code: String = Prompt::new(MSG_LINK_TO_CODE_PROMPT).ask(); + match check_link_to_code(shell, &link_to_code) { + Ok(_) => link_to_code, + Err(err) => { + logger::warn(err); + if !PromptConfirm::new(MSG_CONFIRM_STILL_USE_FOLDER).ask() { + pick_new_link_to_code(shell) + } else { + link_to_code + } + } + } +} + +pub fn get_link_to_code(shell: &Shell) -> String { + let link_to_code_selection = + PromptSelect::new(MSG_REPOSITORY_ORIGIN_PROMPT, LinkToCodeSelection::iter()).ask(); + match link_to_code_selection { + LinkToCodeSelection::Clone => "".to_string(), + LinkToCodeSelection::Path => { + let mut path: String = Prompt::new(MSG_LINK_TO_CODE_PROMPT).ask(); + if let Err(err) = check_link_to_code(shell, &path) { + logger::warn(err); + if !PromptConfirm::new(MSG_CONFIRM_STILL_USE_FOLDER).ask() { + path = pick_new_link_to_code(shell); + } + } + path + } + } +} + +pub fn resolve_link_to_code( + shell: &Shell, + base_path: PathBuf, + link_to_code: String, +) -> anyhow::Result { + if link_to_code.is_empty() { + let spinner = Spinner::new(MSG_CLONING_ERA_REPO_SPINNER); + let link_to_code = git::clone(shell, base_path, ZKSYNC_ERA_GIT_REPO, "zksync-era")?; + spinner.finish(); + Ok(link_to_code) + } else { + let path = PathBuf::from_str(&link_to_code)?; + git::submodule_update(shell, path.clone())?; + Ok(path) + } +} diff --git a/zkstack_cli/crates/zkstack/src/utils/mod.rs b/zkstack_cli/crates/zkstack/src/utils/mod.rs index cf7a7ef4818..a8bdc00d73f 100644 --- a/zkstack_cli/crates/zkstack/src/utils/mod.rs +++ b/zkstack_cli/crates/zkstack/src/utils/mod.rs @@ -1,4 +1,5 @@ pub mod consensus; pub mod forge; +pub mod link_to_code; pub mod ports; pub mod rocks_db;