diff --git a/zk_toolbox/Cargo.lock b/zk_toolbox/Cargo.lock index 2492caf89780..1469b183152b 100644 --- a/zk_toolbox/Cargo.lock +++ b/zk_toolbox/Cargo.lock @@ -530,13 +530,31 @@ dependencies = [ "serde_json", "serde_yaml", "sqlx", - "strum 0.26.2", "strum_macros 0.26.2", "toml", "url", "xshell", ] +[[package]] +name = "config" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap", + "common", + "ethers", + "rand", + "serde", + "serde_json", + "strum 0.26.2", + "strum_macros 0.26.2", + "thiserror", + "types", + "url", + "xshell", +] + [[package]] name = "console" version = "0.15.8" @@ -3921,6 +3939,17 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "types" +version = "0.1.0" +dependencies = [ + "clap", + "ethers", + "serde", + "strum 0.26.2", + "strum_macros 0.26.2", +] + [[package]] name = "uint" version = "0.9.5" @@ -4500,6 +4529,7 @@ dependencies = [ "clap", "cliclack", "common", + "config", "console", "ethers", "human-panic", @@ -4511,6 +4541,7 @@ dependencies = [ "thiserror", "tokio", "toml", + "types", "url", "xshell", ] diff --git a/zk_toolbox/Cargo.toml b/zk_toolbox/Cargo.toml index f2ade7a48294..539c656292a4 100644 --- a/zk_toolbox/Cargo.toml +++ b/zk_toolbox/Cargo.toml @@ -1,5 +1,8 @@ [workspace] -members = ["crates/common", +members = [ + "crates/common", + "crates/config", + "crates/types", "crates/zk_inception", "crates/zk_supervisor", ] @@ -20,6 +23,8 @@ keywords = ["zk", "cryptography", "blockchain", "ZKStack", "zkSync"] [workspace.dependencies] # Local dependencies common = { path = "crates/common" } +config = { path = "crates/config" } +types = { path = "crates/types" } # External dependencies anyhow = "1.0.82" @@ -29,6 +34,7 @@ console = "0.15.8" ethers = "2.0" human-panic = "2.0" once_cell = "1.19.0" +rand = "0.8.5" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde_yaml = "0.9" diff --git a/zk_toolbox/crates/common/Cargo.toml b/zk_toolbox/crates/common/Cargo.toml index 588254e445f8..efdde1cdfc18 100644 --- a/zk_toolbox/crates/common/Cargo.toml +++ b/zk_toolbox/crates/common/Cargo.toml @@ -21,9 +21,8 @@ serde.workspace = true serde_json.workspace = true serde_yaml.workspace = true sqlx.workspace = true -strum.workspace = true strum_macros.workspace = true toml.workspace = true url.workspace = true xshell.workspace = true -futures.workspace = true \ No newline at end of file +futures.workspace = true diff --git a/zk_toolbox/crates/common/src/config.rs b/zk_toolbox/crates/common/src/config.rs index 9f3adc2e83d3..2cad7b361029 100644 --- a/zk_toolbox/crates/common/src/config.rs +++ b/zk_toolbox/crates/common/src/config.rs @@ -3,7 +3,9 @@ use once_cell::sync::OnceCell; static CONFIG: OnceCell = OnceCell::new(); pub fn init_global_config(config: GlobalConfig) { - CONFIG.set(config).unwrap(); + CONFIG + .set(config) + .expect("GlobalConfig already initialized"); } pub fn global_config() -> &'static GlobalConfig { diff --git a/zk_toolbox/crates/common/src/ethereum.rs b/zk_toolbox/crates/common/src/ethereum.rs index 6e9c24488c5e..451bc311145f 100644 --- a/zk_toolbox/crates/common/src/ethereum.rs +++ b/zk_toolbox/crates/common/src/ethereum.rs @@ -1,13 +1,11 @@ use std::{ops::Add, time::Duration}; -use ethers::prelude::Signer; use ethers::{ core::k256::ecdsa::SigningKey, middleware::MiddlewareBuilder, - prelude::{Http, LocalWallet, Provider}, - prelude::{SignerMiddleware, H256}, + prelude::{Http, LocalWallet, Provider, Signer, SignerMiddleware}, providers::Middleware, - types::{Address, TransactionRequest}, + types::{Address, TransactionRequest, H256}, }; use crate::wallets::Wallet; diff --git a/zk_toolbox/crates/common/src/files.rs b/zk_toolbox/crates/common/src/files.rs index c29f79aaa202..8db8eb7f33c3 100644 --- a/zk_toolbox/crates/common/src/files.rs +++ b/zk_toolbox/crates/common/src/files.rs @@ -1,8 +1,35 @@ use std::path::Path; -use serde::Serialize; +use serde::{de::DeserializeOwned, Serialize}; use xshell::Shell; +pub fn read_yaml_file(shell: &Shell, file_path: impl AsRef) -> anyhow::Result +where + T: DeserializeOwned, +{ + let content = shell.read_file(file_path)?; + let yaml = serde_yaml::from_str(&content)?; + Ok(yaml) +} + +pub fn read_toml_file(shell: &Shell, file_path: impl AsRef) -> anyhow::Result +where + T: DeserializeOwned, +{ + let content = shell.read_file(file_path)?; + let toml = toml::from_str(&content)?; + Ok(toml) +} + +pub fn read_json_file(shell: &Shell, file_path: impl AsRef) -> anyhow::Result +where + T: DeserializeOwned, +{ + let content = shell.read_file(file_path)?; + let json = serde_json::from_str(&content)?; + Ok(json) +} + pub fn save_yaml_file( shell: &Shell, file_path: impl AsRef, diff --git a/zk_toolbox/crates/common/src/forge.rs b/zk_toolbox/crates/common/src/forge.rs index 4335765e330c..3ae46a8034a8 100644 --- a/zk_toolbox/crates/common/src/forge.rs +++ b/zk_toolbox/crates/common/src/forge.rs @@ -1,17 +1,20 @@ -use std::path::{Path, PathBuf}; -use std::str::FromStr; +use std::{ + path::{Path, PathBuf}, + str::FromStr, +}; use clap::{Parser, ValueEnum}; -use ethers::abi::Address; -use ethers::middleware::Middleware; -use ethers::prelude::{LocalWallet, Signer, U256}; -use ethers::{abi::AbiEncode, types::H256}; +use ethers::{ + middleware::Middleware, + prelude::{LocalWallet, Signer}, + types::{Address, H256, U256}, + utils::hex::ToHex, +}; use serde::{Deserialize, Serialize}; use strum_macros::Display; use xshell::{cmd, Shell}; -use crate::cmd::Cmd; -use crate::ethereum::create_ethers_client; +use crate::{cmd::Cmd, ethereum::create_ethers_client}; /// Forge is a wrapper around the forge binary. pub struct Forge { @@ -123,7 +126,7 @@ impl ForgeScript { self.private_key().and_then(|a| { LocalWallet::from_bytes(a.as_bytes()) .ok() - .map(|a| a.address()) + .map(|a| Address::from_slice(a.address().as_bytes())) }) } diff --git a/zk_toolbox/crates/common/src/slugify.rs b/zk_toolbox/crates/common/src/slugify.rs index a934a56b5527..5e9940efb8e2 100644 --- a/zk_toolbox/crates/common/src/slugify.rs +++ b/zk_toolbox/crates/common/src/slugify.rs @@ -1,3 +1,3 @@ pub fn slugify(data: &str) -> String { - data.trim().replace(" ", "-") + data.trim().replace(' ', "-") } diff --git a/zk_toolbox/crates/common/src/wallets.rs b/zk_toolbox/crates/common/src/wallets.rs index 1349f31ebebe..ed5e11b3261a 100644 --- a/zk_toolbox/crates/common/src/wallets.rs +++ b/zk_toolbox/crates/common/src/wallets.rs @@ -1,23 +1,23 @@ use ethers::{ core::rand::Rng, signers::{coins_bip39::English, LocalWallet, MnemonicBuilder, Signer}, - types::{H160, H256}, + types::{Address, H256}, }; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Wallet { - pub address: H160, + pub address: Address, pub private_key: Option, } impl Wallet { pub fn random(rng: &mut impl Rng) -> Self { - let private_key = H256(rng.gen()); + let private_key = H256::random_using(rng); let local_wallet = LocalWallet::from_bytes(private_key.as_bytes()).unwrap(); Self { - address: local_wallet.address(), + address: Address::from_slice(local_wallet.address().as_bytes()), private_key: Some(private_key), } } @@ -25,7 +25,7 @@ impl Wallet { pub fn new_with_key(private_key: H256) -> Self { let local_wallet = LocalWallet::from_bytes(private_key.as_bytes()).unwrap(); Self { - address: local_wallet.address(), + address: Address::from_slice(local_wallet.address().as_bytes()), private_key: Some(private_key), } } @@ -41,7 +41,7 @@ impl Wallet { pub fn empty() -> Self { Self { - address: H160::zero(), + address: Address::zero(), private_key: Some(H256::zero()), } } @@ -57,7 +57,7 @@ fn test_load_localhost_wallets() { .unwrap(); assert_eq!( wallet.address, - H160::from_slice( + Address::from_slice( ðers::utils::hex::decode("0xa61464658AfeAf65CccaaFD3a512b69A83B77618").unwrap() ) ); diff --git a/zk_toolbox/crates/config/Cargo.toml b/zk_toolbox/crates/config/Cargo.toml new file mode 100644 index 000000000000..936cf57498f5 --- /dev/null +++ b/zk_toolbox/crates/config/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "config" +version.workspace = true +edition.workspace = true +homepage.workspace = true +license.workspace = true +authors.workspace = true +exclude.workspace = true +repository.workspace = true +description.workspace = true +keywords.workspace = true + +[dependencies] +anyhow.workspace = true +clap.workspace = true +common.workspace = true +ethers.workspace = true +rand.workspace = true +serde.workspace = true +serde_json.workspace = true +strum.workspace = true +strum_macros.workspace = true +thiserror.workspace = true +types.workspace = true +url.workspace = true +xshell.workspace = true diff --git a/zk_toolbox/crates/zk_inception/src/configs/chain.rs b/zk_toolbox/crates/config/src/chain.rs similarity index 79% rename from zk_toolbox/crates/zk_inception/src/configs/chain.rs rename to zk_toolbox/crates/config/src/chain.rs index 08ecc583801f..e685b0966b44 100644 --- a/zk_toolbox/crates/zk_inception/src/configs/chain.rs +++ b/zk_toolbox/crates/config/src/chain.rs @@ -4,13 +4,18 @@ use std::{ }; use serde::{Deserialize, Serialize, Serializer}; +use types::{ + BaseToken, ChainId, L1BatchCommitDataGeneratorMode, L1Network, ProverMode, WalletCreation, +}; use xshell::Shell; use crate::{ - configs::{ContractsConfig, GenesisConfig, ReadConfig, SaveConfig, Secrets, WalletsConfig}, - consts::{CONTRACTS_FILE, GENESIS_FILE, L1_CONTRACTS_FOUNDRY, SECRETS_FILE, WALLETS_FILE}, - types::{BaseToken, ChainId, L1BatchCommitDataGeneratorMode, L1Network, ProverMode}, - wallets::{create_localhost_wallets, WalletCreation}, + consts::{ + CONFIG_NAME, CONTRACTS_FILE, GENESIS_FILE, L1_CONTRACTS_FOUNDRY, SECRETS_FILE, WALLETS_FILE, + }, + create_localhost_wallets, + traits::{FileConfigWithDefaultName, ReadConfig, SaveConfig, SaveConfigWithBasePath}, + ContractsConfig, GenesisConfig, SecretsConfig, WalletsConfig, }; /// Chain configuration file. This file is created in the chain @@ -82,8 +87,8 @@ impl ChainConfig { ContractsConfig::read(self.get_shell(), self.configs.join(CONTRACTS_FILE)) } - pub fn get_secrets_config(&self) -> anyhow::Result { - Secrets::read(self.get_shell(), self.configs.join(SECRETS_FILE)) + pub fn get_secrets_config(&self) -> anyhow::Result { + SecretsConfig::read(self.get_shell(), self.configs.join(SECRETS_FILE)) } pub fn path_to_foundry(&self) -> PathBuf { @@ -95,6 +100,11 @@ impl ChainConfig { config.save(shell, path) } + pub fn save_with_base_path(&self, shell: &Shell, path: impl AsRef) -> anyhow::Result<()> { + let config = self.get_internal(); + config.save_with_base_path(shell, path) + } + fn get_internal(&self) -> ChainConfigInternal { ChainConfigInternal { id: self.id, @@ -110,5 +120,6 @@ impl ChainConfig { } } -impl ReadConfig for ChainConfigInternal {} -impl SaveConfig for ChainConfigInternal {} +impl FileConfigWithDefaultName for ChainConfigInternal { + const FILE_NAME: &'static str = CONFIG_NAME; +} diff --git a/zk_toolbox/crates/config/src/consts.rs b/zk_toolbox/crates/config/src/consts.rs new file mode 100644 index 000000000000..9082a17abb24 --- /dev/null +++ b/zk_toolbox/crates/config/src/consts.rs @@ -0,0 +1,39 @@ +use types::ChainId; + +/// Name of the main configuration file +pub(crate) const CONFIG_NAME: &str = "ZkStack.yaml"; +/// Name of the wallets file +pub(crate) const WALLETS_FILE: &str = "wallets.yaml"; +/// Name of the secrets config file +pub(crate) const SECRETS_FILE: &str = "secrets.yaml"; +/// Name of the general config file +pub(crate) const GENERAL_FILE: &str = "general.yaml"; +/// Name of the genesis config file +pub(crate) const GENESIS_FILE: &str = "genesis.yaml"; + +pub(crate) const ERC20_CONFIGS_FILE: &str = "erc20.yaml"; +/// Name of the initial deployments config file +pub(crate) const INITIAL_DEPLOYMENT_FILE: &str = "initial_deployments.yaml"; +/// Name of the erc20 deployments config file +pub(crate) const ERC20_DEPLOYMENT_FILE: &str = "erc20_deployments.yaml"; +/// Name of the contracts file +pub(crate) const CONTRACTS_FILE: &str = "contracts.yaml"; +/// Main repository for the zkSync project +pub const ZKSYNC_ERA_GIT_REPO: &str = "https://github.com/matter-labs/zksync-era"; +/// Name of the docker-compose file inside zksync repository +pub const DOCKER_COMPOSE_FILE: &str = "docker-compose.yml"; +/// Path to the config file with mnemonic for localhost wallets +pub(crate) const CONFIGS_PATH: &str = "etc/env/file_based"; +pub(crate) const LOCAL_CONFIGS_PATH: &str = "configs/"; +pub(crate) const LOCAL_DB_PATH: &str = "db/"; + +/// Path to ecosystem contacts +pub(crate) const ECOSYSTEM_PATH: &str = "etc/ecosystem"; + +/// Path to l1 contracts foundry folder inside zksync-era +pub(crate) const L1_CONTRACTS_FOUNDRY: &str = "contracts/l1-contracts-foundry"; + +pub(crate) const ERA_CHAIN_ID: ChainId = ChainId(270); + +pub(crate) const TEST_CONFIG_PATH: &str = "etc/test_config/constant/eth.json"; +pub(crate) const BASE_PATH: &str = "m/44'/60'/0'"; diff --git a/zk_toolbox/crates/zk_inception/src/configs/contracts.rs b/zk_toolbox/crates/config/src/contracts.rs similarity index 91% rename from zk_toolbox/crates/zk_inception/src/configs/contracts.rs rename to zk_toolbox/crates/config/src/contracts.rs index c5302ae21298..b86b9b0f2958 100644 --- a/zk_toolbox/crates/zk_inception/src/configs/contracts.rs +++ b/zk_toolbox/crates/config/src/contracts.rs @@ -1,8 +1,10 @@ -use ethers::{addressbook::Address, types::H256}; +use ethers::types::{Address, H256}; use serde::{Deserialize, Serialize}; -use crate::configs::{ - forge_interface::deploy_ecosystem::output::DeployL1Output, ReadConfig, SaveConfig, +use crate::{ + consts::CONTRACTS_FILE, + forge_interface::deploy_ecosystem::output::DeployL1Output, + traits::{FileConfig, FileConfigWithDefaultName}, }; #[derive(Debug, Deserialize, Serialize, Clone, Default)] @@ -64,8 +66,9 @@ impl ContractsConfig { } } -impl ReadConfig for ContractsConfig {} -impl SaveConfig for ContractsConfig {} +impl FileConfigWithDefaultName for ContractsConfig { + const FILE_NAME: &'static str = CONTRACTS_FILE; +} #[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Default)] pub struct EcosystemContracts { @@ -76,8 +79,7 @@ pub struct EcosystemContracts { pub diamond_cut_data: String, } -impl ReadConfig for EcosystemContracts {} -impl SaveConfig for EcosystemContracts {} +impl FileConfig for EcosystemContracts {} #[derive(Debug, Serialize, Deserialize, Clone, Default)] pub struct BridgesContracts { diff --git a/zk_toolbox/crates/zk_inception/src/configs/ecosystem.rs b/zk_toolbox/crates/config/src/ecosystem.rs similarity index 84% rename from zk_toolbox/crates/zk_inception/src/configs/ecosystem.rs rename to zk_toolbox/crates/config/src/ecosystem.rs index 66e90f22f99b..a76e6a5858a5 100644 --- a/zk_toolbox/crates/zk_inception/src/configs/ecosystem.rs +++ b/zk_toolbox/crates/config/src/ecosystem.rs @@ -2,21 +2,19 @@ use std::{cell::OnceCell, path::PathBuf}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use thiserror::Error; +use types::{ChainId, L1Network, ProverMode, WalletCreation}; use xshell::Shell; use crate::{ - configs::{ - forge_interface::deploy_ecosystem::input::{ - Erc20DeploymentConfig, InitialDeploymentConfig, - }, - ChainConfig, ChainConfigInternal, ContractsConfig, ReadConfig, SaveConfig, WalletsConfig, - }, consts::{ - CONFIG_NAME, CONTRACTS_FILE, ERC20_DEPLOYMENT_FILE, INITIAL_DEPLOYMENT_FILE, - L1_CONTRACTS_FOUNDRY, WALLETS_FILE, + CONFIGS_PATH, CONFIG_NAME, CONTRACTS_FILE, ECOSYSTEM_PATH, ERA_CHAIN_ID, + ERC20_DEPLOYMENT_FILE, INITIAL_DEPLOYMENT_FILE, L1_CONTRACTS_FOUNDRY, LOCAL_DB_PATH, + WALLETS_FILE, }, - types::{ChainId, L1Network, ProverMode}, - wallets::{create_localhost_wallets, WalletCreation}, + create_localhost_wallets, + forge_interface::deploy_ecosystem::input::{Erc20DeploymentConfig, InitialDeploymentConfig}, + traits::{FileConfigWithDefaultName, ReadConfig, SaveConfig}, + ChainConfig, ChainConfigInternal, ContractsConfig, WalletsConfig, }; /// Ecosystem configuration file. This file is created in the chain @@ -80,8 +78,9 @@ impl<'de> Deserialize<'de> for EcosystemConfig { } } -impl ReadConfig for EcosystemConfig {} -impl SaveConfig for EcosystemConfig {} +impl FileConfigWithDefaultName for EcosystemConfig { + const FILE_NAME: &'static str = CONFIG_NAME; +} impl EcosystemConfig { fn get_shell(&self) -> &Shell { @@ -171,6 +170,19 @@ impl EcosystemConfig { .collect() } + pub fn get_default_configs_path(&self) -> PathBuf { + self.link_to_code.join(CONFIGS_PATH) + } + + /// Path to the predefined ecosystem configs + pub fn get_preexisting_configs_path(&self) -> PathBuf { + self.link_to_code.join(ECOSYSTEM_PATH) + } + + pub fn get_chain_rocks_db_path(&self, chain_name: &str) -> PathBuf { + self.chains.join(chain_name).join(LOCAL_DB_PATH) + } + fn get_internal(&self) -> EcosystemConfigInternal { EcosystemConfigInternal { name: self.name.clone(), @@ -194,3 +206,7 @@ pub enum EcosystemConfigFromFileError { #[error("Invalid ecosystem configuration")] InvalidConfig { source: anyhow::Error }, } + +pub fn get_default_era_chain_id() -> ChainId { + ERA_CHAIN_ID +} diff --git a/zk_toolbox/crates/config/src/file_config.rs b/zk_toolbox/crates/config/src/file_config.rs new file mode 100644 index 000000000000..ec3a733227f6 --- /dev/null +++ b/zk_toolbox/crates/config/src/file_config.rs @@ -0,0 +1,12 @@ +use std::path::{Path, PathBuf}; + +use xshell::Shell; + +use crate::consts::LOCAL_CONFIGS_PATH; + +pub fn create_local_configs_dir( + shell: &Shell, + base_path: impl AsRef, +) -> xshell::Result { + shell.create_dir(base_path.as_ref().join(LOCAL_CONFIGS_PATH)) +} diff --git a/zk_toolbox/crates/zk_inception/src/configs/forge_interface/accept_ownership/mod.rs b/zk_toolbox/crates/config/src/forge_interface/accept_ownership/mod.rs similarity index 52% rename from zk_toolbox/crates/zk_inception/src/configs/forge_interface/accept_ownership/mod.rs rename to zk_toolbox/crates/config/src/forge_interface/accept_ownership/mod.rs index cd56d6ae0fb8..58b5aa1f9d49 100644 --- a/zk_toolbox/crates/zk_inception/src/configs/forge_interface/accept_ownership/mod.rs +++ b/zk_toolbox/crates/config/src/forge_interface/accept_ownership/mod.rs @@ -1,10 +1,9 @@ -use ethers::prelude::Address; +use ethers::types::Address; use serde::{Deserialize, Serialize}; -use crate::configs::{ReadConfig, SaveConfig}; +use crate::traits::FileConfig; -impl ReadConfig for AcceptOwnershipInput {} -impl SaveConfig for AcceptOwnershipInput {} +impl FileConfig for AcceptOwnershipInput {} #[derive(Debug, Deserialize, Serialize, Clone)] pub struct AcceptOwnershipInput { diff --git a/zk_toolbox/crates/zk_inception/src/configs/forge_interface/deploy_ecosystem/input.rs b/zk_toolbox/crates/config/src/forge_interface/deploy_ecosystem/input.rs similarity index 92% rename from zk_toolbox/crates/zk_inception/src/configs/forge_interface/deploy_ecosystem/input.rs rename to zk_toolbox/crates/config/src/forge_interface/deploy_ecosystem/input.rs index 12b7b1633f14..87556d36795f 100644 --- a/zk_toolbox/crates/zk_inception/src/configs/forge_interface/deploy_ecosystem/input.rs +++ b/zk_toolbox/crates/config/src/forge_interface/deploy_ecosystem/input.rs @@ -1,18 +1,14 @@ use std::{collections::HashMap, str::FromStr}; -use ethers::{ - addressbook::Address, - core::{rand, rand::Rng}, - prelude::H256, -}; +use ethers::types::{Address, H256}; +use rand::Rng; use serde::{Deserialize, Serialize}; +use types::ChainId; use crate::{ - configs::{ - ContractsConfig, GenesisConfig, ReadConfig, SaveConfig, SaveConfigWithComment, - WalletsConfig, - }, - types::ChainId, + consts::INITIAL_DEPLOYMENT_FILE, + traits::{FileConfig, FileConfigWithDefaultName}, + ContractsConfig, GenesisConfig, WalletsConfig, }; #[derive(Debug, Deserialize, Serialize, Clone)] @@ -58,18 +54,18 @@ impl Default for InitialDeploymentConfig { } } -impl ReadConfig for InitialDeploymentConfig {} -impl SaveConfig for InitialDeploymentConfig {} -impl SaveConfigWithComment for InitialDeploymentConfig {} +impl FileConfigWithDefaultName for InitialDeploymentConfig { + const FILE_NAME: &'static str = INITIAL_DEPLOYMENT_FILE; +} #[derive(Debug, Deserialize, Serialize, Clone)] pub struct Erc20DeploymentConfig { pub tokens: Vec, } -impl ReadConfig for Erc20DeploymentConfig {} -impl SaveConfig for Erc20DeploymentConfig {} -impl SaveConfigWithComment for Erc20DeploymentConfig {} +impl FileConfigWithDefaultName for Erc20DeploymentConfig { + const FILE_NAME: &'static str = INITIAL_DEPLOYMENT_FILE; +} impl Default for Erc20DeploymentConfig { fn default() -> Self { @@ -112,8 +108,7 @@ pub struct DeployL1Config { pub tokens: TokensDeployL1Config, } -impl ReadConfig for DeployL1Config {} -impl SaveConfig for DeployL1Config {} +impl FileConfig for DeployL1Config {} impl DeployL1Config { pub fn new( @@ -206,8 +201,7 @@ pub struct DeployErc20Config { pub tokens: HashMap, } -impl ReadConfig for DeployErc20Config {} -impl SaveConfig for DeployErc20Config {} +impl FileConfig for DeployErc20Config {} impl DeployErc20Config { pub fn new( diff --git a/zk_toolbox/crates/zk_inception/src/configs/forge_interface/deploy_ecosystem/mod.rs b/zk_toolbox/crates/config/src/forge_interface/deploy_ecosystem/mod.rs similarity index 100% rename from zk_toolbox/crates/zk_inception/src/configs/forge_interface/deploy_ecosystem/mod.rs rename to zk_toolbox/crates/config/src/forge_interface/deploy_ecosystem/mod.rs diff --git a/zk_toolbox/crates/zk_inception/src/configs/forge_interface/deploy_ecosystem/output.rs b/zk_toolbox/crates/config/src/forge_interface/deploy_ecosystem/output.rs similarity index 90% rename from zk_toolbox/crates/zk_inception/src/configs/forge_interface/deploy_ecosystem/output.rs rename to zk_toolbox/crates/config/src/forge_interface/deploy_ecosystem/output.rs index 6b4a117488ef..1200bf7eab0d 100644 --- a/zk_toolbox/crates/zk_inception/src/configs/forge_interface/deploy_ecosystem/output.rs +++ b/zk_toolbox/crates/config/src/forge_interface/deploy_ecosystem/output.rs @@ -1,9 +1,12 @@ use std::collections::HashMap; -use ethers::{addressbook::Address, prelude::H256}; +use ethers::types::{Address, H256}; use serde::{Deserialize, Serialize}; -use crate::configs::{ReadConfig, SaveConfig}; +use crate::{ + consts::ERC20_CONFIGS_FILE, + traits::{FileConfig, FileConfigWithDefaultName}, +}; #[derive(Debug, Deserialize, Serialize, Clone)] pub struct DeployL1Output { @@ -18,8 +21,7 @@ pub struct DeployL1Output { pub deployed_addresses: DeployL1DeployedAddressesOutput, } -impl ReadConfig for DeployL1Output {} -impl SaveConfig for DeployL1Output {} +impl FileConfig for DeployL1Output {} #[derive(Debug, Deserialize, Serialize, Clone)] pub struct DeployL1ContractsConfigOutput { @@ -86,10 +88,11 @@ pub struct TokenDeployErc20Output { pub mint: u64, } -impl ReadConfig for DeployErc20Output {} -impl SaveConfig for DeployErc20Output {} - #[derive(Debug, Deserialize, Serialize, Clone)] pub struct DeployErc20Output { pub tokens: HashMap, } + +impl FileConfigWithDefaultName for DeployErc20Output { + const FILE_NAME: &'static str = ERC20_CONFIGS_FILE; +} diff --git a/zk_toolbox/crates/zk_inception/src/configs/forge_interface/initialize_bridges/input.rs b/zk_toolbox/crates/config/src/forge_interface/initialize_bridges/input.rs similarity index 81% rename from zk_toolbox/crates/zk_inception/src/configs/forge_interface/initialize_bridges/input.rs rename to zk_toolbox/crates/config/src/forge_interface/initialize_bridges/input.rs index 2bbe46fd2c92..e884c0a3a39e 100644 --- a/zk_toolbox/crates/zk_inception/src/configs/forge_interface/initialize_bridges/input.rs +++ b/zk_toolbox/crates/config/src/forge_interface/initialize_bridges/input.rs @@ -1,13 +1,10 @@ -use ethers::addressbook::Address; +use ethers::types::Address; use serde::{Deserialize, Serialize}; +use types::ChainId; -use crate::{ - configs::{ChainConfig, ReadConfig, SaveConfig}, - types::ChainId, -}; +use crate::{traits::FileConfig, ChainConfig}; -impl ReadConfig for InitializeBridgeInput {} -impl SaveConfig for InitializeBridgeInput {} +impl FileConfig for InitializeBridgeInput {} #[derive(Debug, Clone, Serialize, Deserialize)] pub struct InitializeBridgeInput { diff --git a/zk_toolbox/crates/zk_inception/src/configs/forge_interface/initialize_bridges/mod.rs b/zk_toolbox/crates/config/src/forge_interface/initialize_bridges/mod.rs similarity index 100% rename from zk_toolbox/crates/zk_inception/src/configs/forge_interface/initialize_bridges/mod.rs rename to zk_toolbox/crates/config/src/forge_interface/initialize_bridges/mod.rs diff --git a/zk_toolbox/crates/zk_inception/src/configs/forge_interface/initialize_bridges/output.rs b/zk_toolbox/crates/config/src/forge_interface/initialize_bridges/output.rs similarity index 65% rename from zk_toolbox/crates/zk_inception/src/configs/forge_interface/initialize_bridges/output.rs rename to zk_toolbox/crates/config/src/forge_interface/initialize_bridges/output.rs index bf6cf41dfa7a..d03474a6a089 100644 --- a/zk_toolbox/crates/zk_inception/src/configs/forge_interface/initialize_bridges/output.rs +++ b/zk_toolbox/crates/config/src/forge_interface/initialize_bridges/output.rs @@ -1,9 +1,9 @@ -use ethers::addressbook::Address; +use ethers::types::Address; use serde::{Deserialize, Serialize}; -use crate::configs::ReadConfig; +use crate::traits::FileConfig; -impl ReadConfig for InitializeBridgeOutput {} +impl FileConfig for InitializeBridgeOutput {} #[derive(Debug, Clone, Serialize, Deserialize)] pub struct InitializeBridgeOutput { diff --git a/zk_toolbox/crates/zk_inception/src/configs/forge_interface/mod.rs b/zk_toolbox/crates/config/src/forge_interface/mod.rs similarity index 84% rename from zk_toolbox/crates/zk_inception/src/configs/forge_interface/mod.rs rename to zk_toolbox/crates/config/src/forge_interface/mod.rs index 3e7619560d1d..bcf21b7fb087 100644 --- a/zk_toolbox/crates/zk_inception/src/configs/forge_interface/mod.rs +++ b/zk_toolbox/crates/config/src/forge_interface/mod.rs @@ -3,3 +3,4 @@ pub mod deploy_ecosystem; pub mod initialize_bridges; pub mod paymaster; pub mod register_chain; +pub mod script_params; diff --git a/zk_toolbox/crates/zk_inception/src/configs/forge_interface/paymaster/mod.rs b/zk_toolbox/crates/config/src/forge_interface/paymaster/mod.rs similarity index 70% rename from zk_toolbox/crates/zk_inception/src/configs/forge_interface/paymaster/mod.rs rename to zk_toolbox/crates/config/src/forge_interface/paymaster/mod.rs index a15a007522aa..e634f1eb3dab 100644 --- a/zk_toolbox/crates/zk_inception/src/configs/forge_interface/paymaster/mod.rs +++ b/zk_toolbox/crates/config/src/forge_interface/paymaster/mod.rs @@ -1,10 +1,8 @@ -use ethers::addressbook::Address; +use ethers::types::Address; use serde::{Deserialize, Serialize}; +use types::ChainId; -use crate::{ - configs::{ChainConfig, ReadConfig, SaveConfig}, - types::ChainId, -}; +use crate::{traits::FileConfig, ChainConfig}; #[derive(Debug, Serialize, Deserialize, Clone)] pub struct DeployPaymasterInput { @@ -23,13 +21,11 @@ impl DeployPaymasterInput { }) } } -impl SaveConfig for DeployPaymasterInput {} -impl ReadConfig for DeployPaymasterInput {} +impl FileConfig for DeployPaymasterInput {} #[derive(Debug, Serialize, Deserialize, Clone)] pub struct DeployPaymasterOutput { pub paymaster: Address, } -impl SaveConfig for DeployPaymasterOutput {} -impl ReadConfig for DeployPaymasterOutput {} +impl FileConfig for DeployPaymasterOutput {} diff --git a/zk_toolbox/crates/zk_inception/src/configs/forge_interface/register_chain/input.rs b/zk_toolbox/crates/config/src/forge_interface/register_chain/input.rs similarity index 91% rename from zk_toolbox/crates/zk_inception/src/configs/forge_interface/register_chain/input.rs rename to zk_toolbox/crates/config/src/forge_interface/register_chain/input.rs index bf7e52771680..3849aa341e2b 100644 --- a/zk_toolbox/crates/zk_inception/src/configs/forge_interface/register_chain/input.rs +++ b/zk_toolbox/crates/config/src/forge_interface/register_chain/input.rs @@ -1,13 +1,9 @@ -use ethers::{ - addressbook::Address, - core::{rand, rand::Rng}, -}; +use ethers::types::Address; +use rand::Rng; use serde::{Deserialize, Serialize}; +use types::{ChainId, L1BatchCommitDataGeneratorMode}; -use crate::{ - configs::{ChainConfig, ContractsConfig, ReadConfig, SaveConfig}, - types::{ChainId, L1BatchCommitDataGeneratorMode}, -}; +use crate::{traits::FileConfig, ChainConfig, ContractsConfig}; #[derive(Debug, Deserialize, Serialize, Clone)] struct Bridgehub { @@ -52,9 +48,7 @@ pub struct ChainL1Config { pub governance_min_delay: u64, } -impl ReadConfig for RegisterChainL1Config {} - -impl SaveConfig for RegisterChainL1Config {} +impl FileConfig for RegisterChainL1Config {} impl RegisterChainL1Config { pub fn new(chain_config: &ChainConfig, contracts: &ContractsConfig) -> anyhow::Result { diff --git a/zk_toolbox/crates/zk_inception/src/configs/forge_interface/register_chain/mod.rs b/zk_toolbox/crates/config/src/forge_interface/register_chain/mod.rs similarity index 100% rename from zk_toolbox/crates/zk_inception/src/configs/forge_interface/register_chain/mod.rs rename to zk_toolbox/crates/config/src/forge_interface/register_chain/mod.rs diff --git a/zk_toolbox/crates/zk_inception/src/configs/forge_interface/register_chain/output.rs b/zk_toolbox/crates/config/src/forge_interface/register_chain/output.rs similarity index 53% rename from zk_toolbox/crates/zk_inception/src/configs/forge_interface/register_chain/output.rs rename to zk_toolbox/crates/config/src/forge_interface/register_chain/output.rs index 4e97af0254b0..7d105b578b5b 100644 --- a/zk_toolbox/crates/zk_inception/src/configs/forge_interface/register_chain/output.rs +++ b/zk_toolbox/crates/config/src/forge_interface/register_chain/output.rs @@ -1,7 +1,7 @@ -use ethers::addressbook::Address; +use ethers::types::Address; use serde::{Deserialize, Serialize}; -use crate::configs::{ReadConfig, SaveConfig}; +use crate::traits::FileConfig; #[derive(Debug, Deserialize, Serialize, Clone)] pub struct RegisterChainOutput { @@ -9,5 +9,4 @@ pub struct RegisterChainOutput { pub governance_addr: Address, } -impl ReadConfig for RegisterChainOutput {} -impl SaveConfig for RegisterChainOutput {} +impl FileConfig for RegisterChainOutput {} diff --git a/zk_toolbox/crates/config/src/forge_interface/script_params.rs b/zk_toolbox/crates/config/src/forge_interface/script_params.rs new file mode 100644 index 000000000000..a01a15be2a01 --- /dev/null +++ b/zk_toolbox/crates/config/src/forge_interface/script_params.rs @@ -0,0 +1,63 @@ +use std::path::{Path, PathBuf}; + +use crate::consts::L1_CONTRACTS_FOUNDRY; + +#[derive(PartialEq, Debug, Clone)] +pub struct ForgeScriptParams { + input: &'static str, + output: &'static str, + script_path: &'static str, +} + +impl ForgeScriptParams { + // Path to the input file for forge script + pub fn input(&self, link_to_code: &Path) -> PathBuf { + link_to_code.join(L1_CONTRACTS_FOUNDRY).join(self.input) + } + + // Path to the output file for forge script + pub fn output(&self, link_to_code: &Path) -> PathBuf { + link_to_code.join(L1_CONTRACTS_FOUNDRY).join(self.output) + } + + // Path to the script + pub fn script(&self) -> PathBuf { + PathBuf::from(self.script_path) + } +} + +pub const DEPLOY_ECOSYSTEM_SCRIPT_PARAMS: ForgeScriptParams = ForgeScriptParams { + input: "script-config/config-deploy-l1.toml", + output: "script-out/output-deploy-l1.toml", + script_path: "script/DeployL1.s.sol", +}; + +pub const INITIALIZE_BRIDGES_SCRIPT_PARAMS: ForgeScriptParams = ForgeScriptParams { + input: "script-config/config-initialize-shared-bridges.toml", + output: "script-out/output-initialize-shared-bridges.toml", + script_path: "script/InitializeSharedBridgeOnL2.sol", +}; + +pub const REGISTER_CHAIN_SCRIPT_PARAMS: ForgeScriptParams = ForgeScriptParams { + input: "script-config/register-hyperchain.toml", + output: "script-out/output-register-hyperchain.toml", + script_path: "script/RegisterHyperchain.s.sol", +}; + +pub const DEPLOY_ERC20_SCRIPT_PARAMS: ForgeScriptParams = ForgeScriptParams { + input: "script-config/config-deploy-erc20.toml", + output: "script-out/output-deploy-erc20.toml", + script_path: "script/DeployErc20.s.sol", +}; + +pub const DEPLOY_PAYMASTER_SCRIPT_PARAMS: ForgeScriptParams = ForgeScriptParams { + input: "script-config/config-deploy-paymaster.toml", + output: "script-out/output-deploy-paymaster.toml", + script_path: "script/DeployPaymaster.s.sol", +}; + +pub const ACCEPT_GOVERNANCE_SCRIPT_PARAMS: ForgeScriptParams = ForgeScriptParams { + input: "script-config/config-accept-admin.toml", + output: "script-out/output-accept-admin.toml", + script_path: "script/AcceptAdmin.s.sol", +}; diff --git a/zk_toolbox/crates/zk_inception/src/configs/general.rs b/zk_toolbox/crates/config/src/general.rs similarity index 54% rename from zk_toolbox/crates/zk_inception/src/configs/general.rs rename to zk_toolbox/crates/config/src/general.rs index 5acb6762e9c6..058f23bf1b5d 100644 --- a/zk_toolbox/crates/zk_inception/src/configs/general.rs +++ b/zk_toolbox/crates/config/src/general.rs @@ -1,69 +1,47 @@ use std::path::PathBuf; -use ethers::types::{Address, H256}; use serde::{Deserialize, Serialize}; -use crate::{ - configs::{ReadConfig, SaveConfig}, - types::{ChainId, L1BatchCommitDataGeneratorMode}, -}; +use crate::{consts::GENERAL_FILE, traits::FileConfigWithDefaultName}; #[derive(Debug, Deserialize, Serialize, Clone)] -pub struct GenesisConfig { - pub l2_chain_id: ChainId, - pub l1_chain_id: u32, - pub l1_batch_commit_data_generator_mode: Option, - pub bootloader_hash: H256, - pub default_aa_hash: H256, - pub fee_account: Address, - pub genesis_batch_commitment: H256, - pub genesis_rollup_leaf_index: u32, - pub genesis_root: H256, - pub genesis_protocol_version: u64, +pub struct GeneralConfig { + pub db: RocksDBConfig, + pub eth: EthConfig, #[serde(flatten)] pub other: serde_json::Value, } -impl ReadConfig for GenesisConfig {} -impl SaveConfig for GenesisConfig {} - -#[derive(Debug, Deserialize, Serialize, Clone)] -pub struct EthConfig { - pub sender: EthSender, - #[serde(flatten)] - pub other: serde_json::Value, +impl FileConfigWithDefaultName for GeneralConfig { + const FILE_NAME: &'static str = GENERAL_FILE; } #[derive(Debug, Deserialize, Serialize, Clone)] -pub struct EthSender { - pub proof_sending_mode: String, - pub pubdata_sending_mode: String, +pub struct RocksDBConfig { + pub state_keeper_db_path: PathBuf, + pub merkle_tree: MerkleTreeDB, #[serde(flatten)] pub other: serde_json::Value, } #[derive(Debug, Deserialize, Serialize, Clone)] -pub struct GeneralConfig { - pub db: RocksDBConfig, - pub eth: EthConfig, +pub struct MerkleTreeDB { + pub path: PathBuf, #[serde(flatten)] pub other: serde_json::Value, } #[derive(Debug, Deserialize, Serialize, Clone)] -pub struct RocksDBConfig { - pub state_keeper_db_path: PathBuf, - pub merkle_tree: MerkleTreeDB, +pub struct EthConfig { + pub sender: EthSender, #[serde(flatten)] pub other: serde_json::Value, } #[derive(Debug, Deserialize, Serialize, Clone)] -pub struct MerkleTreeDB { - pub path: PathBuf, +pub struct EthSender { + pub proof_sending_mode: String, + pub pubdata_sending_mode: String, #[serde(flatten)] pub other: serde_json::Value, } - -impl ReadConfig for GeneralConfig {} -impl SaveConfig for GeneralConfig {} diff --git a/zk_toolbox/crates/config/src/genesis.rs b/zk_toolbox/crates/config/src/genesis.rs new file mode 100644 index 000000000000..16f44a45c2e7 --- /dev/null +++ b/zk_toolbox/crates/config/src/genesis.rs @@ -0,0 +1,25 @@ +use ethers::types::{Address, H256}; +use serde::{Deserialize, Serialize}; +use types::{ChainId, L1BatchCommitDataGeneratorMode}; + +use crate::{consts::GENESIS_FILE, traits::FileConfigWithDefaultName}; + +#[derive(Debug, Deserialize, Serialize, Clone)] +pub struct GenesisConfig { + pub l2_chain_id: ChainId, + pub l1_chain_id: u32, + pub l1_batch_commit_data_generator_mode: Option, + pub bootloader_hash: H256, + pub default_aa_hash: H256, + pub fee_account: Address, + pub genesis_batch_commitment: H256, + pub genesis_rollup_leaf_index: u32, + pub genesis_root: H256, + pub genesis_protocol_version: u64, + #[serde(flatten)] + pub other: serde_json::Value, +} + +impl FileConfigWithDefaultName for GenesisConfig { + const FILE_NAME: &'static str = GENESIS_FILE; +} diff --git a/zk_toolbox/crates/zk_inception/src/configs/mod.rs b/zk_toolbox/crates/config/src/lib.rs similarity index 53% rename from zk_toolbox/crates/zk_inception/src/configs/mod.rs rename to zk_toolbox/crates/config/src/lib.rs index 329eeb5c1f46..8e40da7bf6bd 100644 --- a/zk_toolbox/crates/zk_inception/src/configs/mod.rs +++ b/zk_toolbox/crates/config/src/lib.rs @@ -1,18 +1,26 @@ mod chain; -pub mod contracts; +mod consts; +mod contracts; mod ecosystem; -pub mod forge_interface; +mod file_config; mod general; +mod genesis; mod manipulations; mod secrets; -mod traits; +mod wallet_creation; mod wallets; +pub mod forge_interface; +pub mod traits; + pub use chain::*; +pub use consts::{DOCKER_COMPOSE_FILE, ZKSYNC_ERA_GIT_REPO}; pub use contracts::*; pub use ecosystem::*; +pub use file_config::*; pub use general::*; +pub use genesis::*; pub use manipulations::*; pub use secrets::*; -pub use traits::*; +pub use wallet_creation::*; pub use wallets::*; diff --git a/zk_toolbox/crates/config/src/manipulations.rs b/zk_toolbox/crates/config/src/manipulations.rs new file mode 100644 index 000000000000..f0497a5ba671 --- /dev/null +++ b/zk_toolbox/crates/config/src/manipulations.rs @@ -0,0 +1,18 @@ +use std::path::Path; + +use xshell::Shell; + +use crate::consts::{CONFIGS_PATH, WALLETS_FILE}; + +pub fn copy_configs(shell: &Shell, link_to_code: &Path, target_path: &Path) -> anyhow::Result<()> { + let original_configs = link_to_code.join(CONFIGS_PATH); + for file in shell.read_dir(original_configs)? { + if let Some(name) = file.file_name() { + // Do not copy wallets file + if name != WALLETS_FILE { + shell.copy_file(file, target_path)?; + } + } + } + Ok(()) +} diff --git a/zk_toolbox/crates/zk_inception/src/configs/secrets.rs b/zk_toolbox/crates/config/src/secrets.rs similarity index 80% rename from zk_toolbox/crates/zk_inception/src/configs/secrets.rs rename to zk_toolbox/crates/config/src/secrets.rs index e95dd05df6a2..829d903adb66 100644 --- a/zk_toolbox/crates/zk_inception/src/configs/secrets.rs +++ b/zk_toolbox/crates/config/src/secrets.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use url::Url; -use crate::configs::{ReadConfig, SaveConfig}; +use crate::{consts::SECRETS_FILE, traits::FileConfigWithDefaultName}; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct DatabaseSecrets { @@ -13,19 +13,23 @@ pub struct DatabaseSecrets { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct L1Secret { - pub(crate) l1_rpc_url: String, + pub l1_rpc_url: String, #[serde(flatten)] pub other: serde_json::Value, } #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct Secrets { +pub struct SecretsConfig { pub database: DatabaseSecrets, - pub(crate) l1: L1Secret, + pub l1: L1Secret, #[serde(flatten)] pub other: serde_json::Value, } +impl FileConfigWithDefaultName for SecretsConfig { + const FILE_NAME: &'static str = SECRETS_FILE; +} + #[derive(Debug, Serialize)] pub struct DatabaseConfig { pub base_url: Url, @@ -50,6 +54,3 @@ pub struct DatabasesConfig { pub server: DatabaseConfig, pub prover: DatabaseConfig, } - -impl ReadConfig for Secrets {} -impl SaveConfig for Secrets {} diff --git a/zk_toolbox/crates/config/src/traits.rs b/zk_toolbox/crates/config/src/traits.rs new file mode 100644 index 000000000000..85c73e99f99b --- /dev/null +++ b/zk_toolbox/crates/config/src/traits.rs @@ -0,0 +1,131 @@ +use std::path::{Path, PathBuf}; + +use anyhow::{bail, Context}; +use common::files::{ + read_json_file, read_toml_file, read_yaml_file, save_json_file, save_toml_file, save_yaml_file, +}; +use serde::{de::DeserializeOwned, Serialize}; +use xshell::Shell; + +pub trait FileConfig {} + +pub trait FileConfigWithDefaultName { + const FILE_NAME: &'static str; + + fn get_path_with_base_path(base_path: impl AsRef) -> PathBuf { + base_path.as_ref().join(Self::FILE_NAME) + } +} + +impl FileConfig for T where T: FileConfigWithDefaultName {} +impl ReadConfig for T where T: FileConfig + Clone + DeserializeOwned {} +impl SaveConfig for T where T: FileConfig + Serialize {} +impl SaveConfigWithComment for T where T: FileConfig + Serialize {} +impl ReadConfigWithBasePath for T where T: FileConfigWithDefaultName + Clone + DeserializeOwned {} +impl SaveConfigWithBasePath for T where T: FileConfigWithDefaultName + Serialize {} +impl SaveConfigWithCommentAndBasePath for T where T: FileConfigWithDefaultName + Serialize {} + +/// Reads a config file from a given path, correctly parsing file extension. +/// Supported file extensions are: `yaml`, `yml`, `toml`, `json`. +pub trait ReadConfig: DeserializeOwned + Clone { + fn read(shell: &Shell, path: impl AsRef) -> anyhow::Result { + let error_context = || format!("Failed to parse config file {:?}.", path.as_ref()); + + match path.as_ref().extension().and_then(|ext| ext.to_str()) { + Some("yaml") | Some("yml") => read_yaml_file(shell, &path).with_context(error_context), + Some("toml") => read_toml_file(shell, &path).with_context(error_context), + Some("json") => read_json_file(shell, &path).with_context(error_context), + _ => bail!(format!( + "Unsupported file extension for config file {:?}.", + path.as_ref() + )), + } + } +} + +/// Reads a config file from a base path, correctly parsing file extension. +/// Supported file extensions are: `yaml`, `yml`, `toml`, `json`. +pub trait ReadConfigWithBasePath: ReadConfig + FileConfigWithDefaultName { + fn read_with_base_path(shell: &Shell, base_path: impl AsRef) -> anyhow::Result { + ::read(shell, base_path.as_ref().join(Self::FILE_NAME)) + } +} + +/// Saves a config file to a given path, correctly parsing file extension. +/// Supported file extensions are: `yaml`, `yml`, `toml`, `json`. +pub trait SaveConfig: Serialize + Sized { + fn save(&self, shell: &Shell, path: impl AsRef) -> anyhow::Result<()> { + save_with_comment(shell, path, self, "") + } +} + +/// Saves a config file from a base path, correctly parsing file extension. +/// Supported file extensions are: `yaml`, `yml`, `toml`, `json`. +pub trait SaveConfigWithBasePath: SaveConfig + FileConfigWithDefaultName { + fn save_with_base_path( + &self, + shell: &Shell, + base_path: impl AsRef, + ) -> anyhow::Result<()> { + ::save(self, shell, base_path.as_ref().join(Self::FILE_NAME)) + } +} + +/// Saves a config file to a given path, correctly parsing file extension. +/// Supported file extensions are: `yaml`, `yml`, `toml`. +pub trait SaveConfigWithComment: Serialize + Sized { + fn save_with_comment( + &self, + shell: &Shell, + path: impl AsRef, + comment: &str, + ) -> anyhow::Result<()> { + let comment_char = match path.as_ref().extension().and_then(|ext| ext.to_str()) { + Some("yaml") | Some("yml") | Some("toml") => "#", + _ => bail!("Unsupported file extension for config file."), + }; + let comment_lines = comment + .lines() + .map(|line| format!("{comment_char} {line}")) + .chain(std::iter::once("".to_string())) // Add a newline after the comment + .collect::>() + .join("\n"); + + save_with_comment(shell, path, self, comment_lines) + } +} + +/// Saves a config file from a base path, correctly parsing file extension. +/// Supported file extensions are: `yaml`, `yml`, `toml`. +pub trait SaveConfigWithCommentAndBasePath: + SaveConfigWithComment + FileConfigWithDefaultName +{ + fn save_with_comment_and_base_path( + &self, + shell: &Shell, + base_path: impl AsRef, + comment: &str, + ) -> anyhow::Result<()> { + ::save_with_comment( + self, + shell, + base_path.as_ref().join(Self::FILE_NAME), + comment, + ) + } +} + +fn save_with_comment( + shell: &Shell, + path: impl AsRef, + data: impl Serialize, + comment: impl ToString, +) -> anyhow::Result<()> { + match path.as_ref().extension().and_then(|ext| ext.to_str()) { + Some("yaml") | Some("yml") => save_yaml_file(shell, path, data, comment)?, + Some("toml") => save_toml_file(shell, path, data, comment)?, + Some("json") => save_json_file(shell, path, data)?, + _ => bail!("Unsupported file extension for config file."), + } + Ok(()) +} diff --git a/zk_toolbox/crates/zk_inception/src/wallets/create.rs b/zk_toolbox/crates/config/src/wallet_creation.rs similarity index 89% rename from zk_toolbox/crates/zk_inception/src/wallets/create.rs rename to zk_toolbox/crates/config/src/wallet_creation.rs index d395206c1804..249d1662a933 100644 --- a/zk_toolbox/crates/zk_inception/src/wallets/create.rs +++ b/zk_toolbox/crates/config/src/wallet_creation.rs @@ -1,18 +1,19 @@ use std::path::{Path, PathBuf}; use common::wallets::Wallet; -use ethers::core::rand::thread_rng; +use rand::thread_rng; +use types::WalletCreation; use xshell::Shell; use crate::{ - configs::{EthMnemonicConfig, ReadConfig, SaveConfig, WalletsConfig}, consts::{BASE_PATH, TEST_CONFIG_PATH}, - wallets::WalletCreation, + traits::{ReadConfig, SaveConfigWithBasePath}, + EthMnemonicConfig, WalletsConfig, }; pub fn create_wallets( shell: &Shell, - dst_wallet_path: &Path, + base_path: &Path, link_to_code: &Path, id: u32, wallet_creation: WalletCreation, @@ -34,7 +35,7 @@ pub fn create_wallets( } }; - wallets.save(shell, dst_wallet_path)?; + wallets.save_with_base_path(shell, base_path)?; Ok(()) } diff --git a/zk_toolbox/crates/zk_inception/src/configs/wallets.rs b/zk_toolbox/crates/config/src/wallets.rs similarity index 82% rename from zk_toolbox/crates/zk_inception/src/configs/wallets.rs rename to zk_toolbox/crates/config/src/wallets.rs index fc0b43fcbc01..91958195c232 100644 --- a/zk_toolbox/crates/zk_inception/src/configs/wallets.rs +++ b/zk_toolbox/crates/config/src/wallets.rs @@ -1,9 +1,11 @@ -use ethers::{core::rand::Rng, types::H256}; +use common::wallets::Wallet; +use ethers::types::H256; +use rand::Rng; use serde::{Deserialize, Serialize}; use crate::{ - configs::{ReadConfig, SaveConfig}, - wallets::Wallet, + consts::WALLETS_FILE, + traits::{FileConfig, FileConfigWithDefaultName}, }; #[derive(Debug, Clone, Serialize, Deserialize)] @@ -46,8 +48,9 @@ impl WalletsConfig { } } -impl ReadConfig for WalletsConfig {} -impl SaveConfig for WalletsConfig {} +impl FileConfigWithDefaultName for WalletsConfig { + const FILE_NAME: &'static str = WALLETS_FILE; +} /// ETH config from zkync repository #[derive(Debug, Serialize, Deserialize, Clone)] @@ -57,4 +60,4 @@ pub(crate) struct EthMnemonicConfig { pub(crate) base_path: String, } -impl ReadConfig for EthMnemonicConfig {} +impl FileConfig for EthMnemonicConfig {} diff --git a/zk_toolbox/crates/types/Cargo.toml b/zk_toolbox/crates/types/Cargo.toml new file mode 100644 index 000000000000..2c7ceedd1f08 --- /dev/null +++ b/zk_toolbox/crates/types/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "types" +version.workspace = true +edition.workspace = true +homepage.workspace = true +license.workspace = true +authors.workspace = true +exclude.workspace = true +repository.workspace = true +description.workspace = true +keywords.workspace = true + +[dependencies] +clap.workspace = true +ethers.workspace = true +serde.workspace = true +strum.workspace = true +strum_macros.workspace = true diff --git a/zk_toolbox/crates/types/src/base_token.rs b/zk_toolbox/crates/types/src/base_token.rs new file mode 100644 index 000000000000..f3b01185da63 --- /dev/null +++ b/zk_toolbox/crates/types/src/base_token.rs @@ -0,0 +1,20 @@ +use ethers::types::Address; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Serialize, Deserialize, Clone)] +pub struct BaseToken { + pub address: Address, + pub nominator: u64, + pub denominator: u64, +} + +impl BaseToken { + #[must_use] + pub fn eth() -> Self { + Self { + nominator: 1, + denominator: 1, + address: Address::from_low_u64_be(1), + } + } +} diff --git a/zk_toolbox/crates/types/src/chain_id.rs b/zk_toolbox/crates/types/src/chain_id.rs new file mode 100644 index 000000000000..258175d3fde5 --- /dev/null +++ b/zk_toolbox/crates/types/src/chain_id.rs @@ -0,0 +1,18 @@ +use std::fmt::Display; + +use serde::{Deserialize, Serialize}; + +#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] +pub struct ChainId(pub u32); + +impl Display for ChainId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} + +impl From for ChainId { + fn from(value: u32) -> Self { + Self(value) + } +} diff --git a/zk_toolbox/crates/types/src/l1_batch_commit_data_generator_mode.rs b/zk_toolbox/crates/types/src/l1_batch_commit_data_generator_mode.rs new file mode 100644 index 000000000000..cdb8f5919c2d --- /dev/null +++ b/zk_toolbox/crates/types/src/l1_batch_commit_data_generator_mode.rs @@ -0,0 +1,22 @@ +use clap::ValueEnum; +use serde::{Deserialize, Serialize}; +use strum_macros::EnumIter; + +#[derive( + Debug, + Serialize, + Deserialize, + Clone, + Copy, + ValueEnum, + EnumIter, + strum_macros::Display, + Default, + PartialEq, + Eq, +)] +pub enum L1BatchCommitDataGeneratorMode { + #[default] + Rollup, + Validium, +} diff --git a/zk_toolbox/crates/types/src/l1_network.rs b/zk_toolbox/crates/types/src/l1_network.rs new file mode 100644 index 000000000000..f7367673f6c8 --- /dev/null +++ b/zk_toolbox/crates/types/src/l1_network.rs @@ -0,0 +1,36 @@ +use clap::ValueEnum; +use serde::{Deserialize, Serialize}; +use strum_macros::EnumIter; + +#[derive( + Copy, + Clone, + Debug, + Default, + PartialEq, + Eq, + PartialOrd, + Ord, + Serialize, + Deserialize, + ValueEnum, + EnumIter, + strum_macros::Display, +)] +pub enum L1Network { + #[default] + Localhost, + Sepolia, + Mainnet, +} + +impl L1Network { + #[must_use] + pub fn chain_id(&self) -> u32 { + match self { + L1Network::Localhost => 9, + L1Network::Sepolia => 11_155_111, + L1Network::Mainnet => 1, + } + } +} diff --git a/zk_toolbox/crates/types/src/lib.rs b/zk_toolbox/crates/types/src/lib.rs new file mode 100644 index 000000000000..a973f8bfc918 --- /dev/null +++ b/zk_toolbox/crates/types/src/lib.rs @@ -0,0 +1,13 @@ +mod base_token; +mod chain_id; +mod l1_batch_commit_data_generator_mode; +mod l1_network; +mod prover_mode; +mod wallet_creation; + +pub use base_token::*; +pub use chain_id::*; +pub use l1_batch_commit_data_generator_mode::*; +pub use l1_network::*; +pub use prover_mode::*; +pub use wallet_creation::*; diff --git a/zk_toolbox/crates/types/src/prover_mode.rs b/zk_toolbox/crates/types/src/prover_mode.rs new file mode 100644 index 000000000000..d9b4fb965e8c --- /dev/null +++ b/zk_toolbox/crates/types/src/prover_mode.rs @@ -0,0 +1,21 @@ +use clap::ValueEnum; +use serde::{Deserialize, Serialize}; +use strum_macros::EnumIter; + +#[derive( + Debug, + Serialize, + Deserialize, + Clone, + Copy, + ValueEnum, + EnumIter, + strum_macros::Display, + PartialEq, + Eq, +)] +pub enum ProverMode { + NoProofs, + Gpu, + Cpu, +} diff --git a/zk_toolbox/crates/zk_inception/src/wallets/config.rs b/zk_toolbox/crates/types/src/wallet_creation.rs similarity index 100% rename from zk_toolbox/crates/zk_inception/src/wallets/config.rs rename to zk_toolbox/crates/types/src/wallet_creation.rs diff --git a/zk_toolbox/crates/zk_inception/Cargo.toml b/zk_toolbox/crates/zk_inception/Cargo.toml index 5ae3dd20e64b..8123746f1abf 100644 --- a/zk_toolbox/crates/zk_inception/Cargo.toml +++ b/zk_toolbox/crates/zk_inception/Cargo.toml @@ -14,6 +14,7 @@ keywords.workspace = true anyhow.workspace = true clap.workspace = true cliclack.workspace = true +config.workspace = true console.workspace = true human-panic.workspace = true serde_yaml.workspace = true @@ -23,6 +24,7 @@ xshell.workspace = true ethers.workspace = true common.workspace = true tokio.workspace = true +types.workspace = true strum_macros.workspace = true strum.workspace = true toml.workspace = true diff --git a/zk_toolbox/crates/zk_inception/src/accept_ownership.rs b/zk_toolbox/crates/zk_inception/src/accept_ownership.rs index 8c331dd63e05..eb56a5f5325e 100644 --- a/zk_toolbox/crates/zk_inception/src/accept_ownership.rs +++ b/zk_toolbox/crates/zk_inception/src/accept_ownership.rs @@ -2,17 +2,18 @@ use common::{ forge::{Forge, ForgeScript, ForgeScriptArgs}, spinner::Spinner, }; -use ethers::{abi::Address, types::H256}; use xshell::Shell; use crate::forge_utils::check_the_balance; -use crate::{ - configs::{ - forge_interface::accept_ownership::AcceptOwnershipInput, EcosystemConfig, SaveConfig, +use crate::forge_utils::fill_forge_private_key; +use config::{ + forge_interface::{ + accept_ownership::AcceptOwnershipInput, script_params::ACCEPT_GOVERNANCE_SCRIPT_PARAMS, }, - consts::ACCEPT_GOVERNANCE, - forge_utils::fill_forge_private_key, + traits::SaveConfig, + EcosystemConfig, }; +use ethers::types::{Address, H256}; pub async fn accept_admin( shell: &Shell, @@ -25,7 +26,10 @@ pub async fn accept_admin( ) -> anyhow::Result<()> { let foundry_contracts_path = ecosystem_config.path_to_foundry(); let forge = Forge::new(&foundry_contracts_path) - .script(&ACCEPT_GOVERNANCE.script(), forge_args.clone()) + .script( + &ACCEPT_GOVERNANCE_SCRIPT_PARAMS.script(), + forge_args.clone(), + ) .with_ffi() .with_rpc_url(l1_rpc_url) .with_broadcast() @@ -52,7 +56,10 @@ pub async fn accept_owner( ) -> anyhow::Result<()> { let foundry_contracts_path = ecosystem_config.path_to_foundry(); let forge = Forge::new(&foundry_contracts_path) - .script(&ACCEPT_GOVERNANCE.script(), forge_args.clone()) + .script( + &ACCEPT_GOVERNANCE_SCRIPT_PARAMS.script(), + forge_args.clone(), + ) .with_ffi() .with_rpc_url(l1_rpc_url) .with_broadcast() @@ -82,7 +89,7 @@ async fn accept_ownership( }; input.save( shell, - ACCEPT_GOVERNANCE.input(&ecosystem_config.link_to_code), + ACCEPT_GOVERNANCE_SCRIPT_PARAMS.input(&ecosystem_config.link_to_code), )?; forge = fill_forge_private_key(forge, governor)?; diff --git a/zk_toolbox/crates/zk_inception/src/commands/chain/args/create.rs b/zk_toolbox/crates/zk_inception/src/commands/chain/args/create.rs index 6afb46cbfb60..1ad375749672 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/chain/args/create.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/chain/args/create.rs @@ -2,16 +2,13 @@ use std::{path::PathBuf, str::FromStr}; use clap::Parser; use common::{slugify, Prompt, PromptConfirm, PromptSelect}; -use ethers::types::H160; use serde::{Deserialize, Serialize}; use strum::IntoEnumIterator; use strum_macros::{Display, EnumIter}; -use crate::{ - defaults::L2_CHAIN_ID, - types::{BaseToken, L1BatchCommitDataGeneratorMode, ProverMode}, - wallets::WalletCreation, -}; +use crate::defaults::L2_CHAIN_ID; +use ethers::types::Address; +use types::{BaseToken, L1BatchCommitDataGeneratorMode, ProverMode, WalletCreation}; #[derive(Debug, Serialize, Deserialize, Parser)] pub struct ChainCreateArgs { @@ -93,7 +90,7 @@ impl ChainCreateArgs { } Ok(()) }; - let address: H160 = Prompt::new("What is the base token address?").ask(); + let address: Address = Prompt::new("What is the base token address?").ask(); let nominator = Prompt::new("What is the base token price nominator?") .validate_with(number_validator) .ask(); diff --git a/zk_toolbox/crates/zk_inception/src/commands/chain/args/genesis.rs b/zk_toolbox/crates/zk_inception/src/commands/chain/args/genesis.rs index b24956c70c12..d34592360ae3 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/chain/args/genesis.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/chain/args/genesis.rs @@ -3,10 +3,8 @@ use common::{slugify, Prompt}; use serde::{Deserialize, Serialize}; use url::Url; -use crate::{ - configs::{ChainConfig, DatabaseConfig, DatabasesConfig}, - defaults::{generate_db_names, DBNames, DATABASE_PROVER_URL, DATABASE_SERVER_URL}, -}; +use crate::defaults::{generate_db_names, DBNames, DATABASE_PROVER_URL, DATABASE_SERVER_URL}; +use config::{ChainConfig, DatabaseConfig, DatabasesConfig}; #[derive(Debug, Clone, Serialize, Deserialize, Parser, Default)] pub struct GenesisArgs { diff --git a/zk_toolbox/crates/zk_inception/src/commands/chain/args/init.rs b/zk_toolbox/crates/zk_inception/src/commands/chain/args/init.rs index aaa6fb2f0ffa..9b6862b6070a 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/chain/args/init.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/chain/args/init.rs @@ -1,13 +1,14 @@ use clap::Parser; use common::forge::ForgeScriptArgs; use common::Prompt; +use config::ChainConfig; use serde::{Deserialize, Serialize}; +use types::L1Network; use url::Url; use super::genesis::GenesisArgsFinal; +use crate::commands::chain::args::genesis::GenesisArgs; use crate::defaults::LOCAL_RPC_URL; -use crate::types::L1Network; -use crate::{commands::chain::args::genesis::GenesisArgs, configs::ChainConfig}; #[derive(Debug, Clone, Serialize, Deserialize, Parser)] pub struct InitArgs { diff --git a/zk_toolbox/crates/zk_inception/src/commands/chain/create.rs b/zk_toolbox/crates/zk_inception/src/commands/chain/create.rs index 2be7044d64b8..f00b166c0e5b 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/chain/create.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/chain/create.rs @@ -3,13 +3,12 @@ use std::cell::OnceCell; use common::{logger, spinner::Spinner}; use xshell::Shell; -use crate::{ - commands::chain::args::create::{ChainCreateArgs, ChainCreateArgsFinal}, - configs::{ChainConfig, EcosystemConfig, SaveConfig}, - consts::{CONFIG_NAME, LOCAL_CONFIGS_PATH, LOCAL_DB_PATH, WALLETS_FILE}, - types::ChainId, - wallets::create_wallets, +use crate::commands::chain::args::create::{ChainCreateArgs, ChainCreateArgsFinal}; +use config::{ + create_local_configs_dir, create_wallets, traits::SaveConfigWithBasePath, ChainConfig, + EcosystemConfig, }; +use types::ChainId; pub fn run(args: ChainCreateArgs, shell: &Shell) -> anyhow::Result<()> { let mut ecosystem_config = EcosystemConfig::from_file(shell)?; @@ -32,7 +31,7 @@ fn create( create_chain_inner(args, ecosystem_config, shell)?; if set_as_default { ecosystem_config.default_chain = name; - ecosystem_config.save(shell, CONFIG_NAME)?; + ecosystem_config.save_with_base_path(shell, ".")?; } spinner.finish(); @@ -48,8 +47,7 @@ pub(crate) fn create_chain_inner( ) -> anyhow::Result<()> { let default_chain_name = args.chain_name.clone(); let chain_path = ecosystem_config.chains.join(&default_chain_name); - let chain_configs_path = shell.create_dir(chain_path.join(LOCAL_CONFIGS_PATH))?; - let chain_db_path = chain_path.join(LOCAL_DB_PATH); + let chain_configs_path = create_local_configs_dir(shell, &chain_path)?; let chain_id = ecosystem_config.list_of_chains().len() as u32; let chain_config = ChainConfig { @@ -59,7 +57,7 @@ pub(crate) fn create_chain_inner( prover_version: args.prover_version, l1_network: ecosystem_config.l1_network, link_to_code: ecosystem_config.link_to_code.clone(), - rocks_db_path: chain_db_path, + rocks_db_path: ecosystem_config.get_chain_rocks_db_path(&default_chain_name), configs: chain_configs_path.clone(), l1_batch_commit_data_generator_mode: args.l1_batch_commit_data_generator_mode, base_token: args.base_token, @@ -69,13 +67,13 @@ pub(crate) fn create_chain_inner( create_wallets( shell, - &chain_config.configs.join(WALLETS_FILE), + &chain_config.configs, &ecosystem_config.link_to_code, chain_id, args.wallet_creation, args.wallet_path, )?; - chain_config.save(shell, chain_path.join(CONFIG_NAME))?; + chain_config.save_with_base_path(shell, chain_path)?; Ok(()) } diff --git a/zk_toolbox/crates/zk_inception/src/commands/chain/deploy_paymaster.rs b/zk_toolbox/crates/zk_inception/src/commands/chain/deploy_paymaster.rs index 177b27cb2ff5..ee97dc18b599 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/chain/deploy_paymaster.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/chain/deploy_paymaster.rs @@ -6,14 +6,15 @@ use common::{ }; use xshell::Shell; -use crate::forge_utils::check_the_balance; -use crate::{ - configs::{ - forge_interface::paymaster::{DeployPaymasterInput, DeployPaymasterOutput}, - update_paymaster, ChainConfig, EcosystemConfig, ReadConfig, SaveConfig, +use crate::forge_utils::fill_forge_private_key; +use crate::{config_manipulations::update_paymaster, forge_utils::check_the_balance}; +use config::{ + forge_interface::{ + paymaster::{DeployPaymasterInput, DeployPaymasterOutput}, + script_params::DEPLOY_PAYMASTER_SCRIPT_PARAMS, }, - consts::DEPLOY_PAYMASTER, - forge_utils::fill_forge_private_key, + traits::{ReadConfig, SaveConfig}, + ChainConfig, EcosystemConfig, }; pub async fn run(args: ForgeScriptArgs, shell: &Shell) -> anyhow::Result<()> { @@ -32,11 +33,14 @@ pub async fn deploy_paymaster( ) -> anyhow::Result<()> { let input = DeployPaymasterInput::new(chain_config)?; let foundry_contracts_path = chain_config.path_to_foundry(); - input.save(shell, DEPLOY_PAYMASTER.input(&chain_config.link_to_code))?; + input.save( + shell, + DEPLOY_PAYMASTER_SCRIPT_PARAMS.input(&chain_config.link_to_code), + )?; let secrets = chain_config.get_secrets_config()?; let mut forge = Forge::new(&foundry_contracts_path) - .script(&DEPLOY_PAYMASTER.script(), forge_args.clone()) + .script(&DEPLOY_PAYMASTER_SCRIPT_PARAMS.script(), forge_args.clone()) .with_ffi() .with_rpc_url(secrets.l1.l1_rpc_url.clone()) .with_broadcast(); @@ -51,8 +55,10 @@ pub async fn deploy_paymaster( forge.run(shell)?; spinner.finish(); - let output = - DeployPaymasterOutput::read(shell, DEPLOY_PAYMASTER.output(&chain_config.link_to_code))?; + let output = DeployPaymasterOutput::read( + shell, + DEPLOY_PAYMASTER_SCRIPT_PARAMS.output(&chain_config.link_to_code), + )?; update_paymaster(shell, chain_config, &output)?; Ok(()) diff --git a/zk_toolbox/crates/zk_inception/src/commands/chain/genesis.rs b/zk_toolbox/crates/zk_inception/src/commands/chain/genesis.rs index 4fe2f0bbb118..a1c357f1f868 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/chain/genesis.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/chain/genesis.rs @@ -12,12 +12,10 @@ use xshell::Shell; use super::args::genesis::GenesisArgsFinal; use crate::{ commands::chain::args::genesis::GenesisArgs, - configs::{ - update_database_secrets, update_general_config, ChainConfig, DatabasesConfig, - EcosystemConfig, - }, + config_manipulations::{update_database_secrets, update_general_config}, server::{RunServer, ServerMode}, }; +use config::{ChainConfig, DatabasesConfig, EcosystemConfig}; const SERVER_MIGRATIONS: &str = "core/lib/dal/migrations"; const PROVER_MIGRATIONS: &str = "prover/prover_dal/migrations"; 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 80776ab277df..ae45e52dcb05 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/chain/init.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/chain/init.rs @@ -8,24 +8,24 @@ use common::{ use xshell::Shell; use super::args::init::InitArgsFinal; -use crate::configs::update_l1_rpc_url_secret; -use crate::forge_utils::check_the_balance; use crate::{ accept_ownership::accept_admin, commands::chain::{ args::init::InitArgs, deploy_paymaster, genesis::genesis, initialize_bridges, }, - configs::{ - copy_configs, - forge_interface::register_chain::{ - input::RegisterChainL1Config, output::RegisterChainOutput, - }, - update_genesis, update_l1_contracts, ChainConfig, ContractsConfig, EcosystemConfig, - ReadConfig, SaveConfig, - }, - consts::{CONTRACTS_FILE, REGISTER_CHAIN}, + config_manipulations::{update_l1_contracts, update_l1_rpc_url_secret}, forge_utils::fill_forge_private_key, }; +use crate::{config_manipulations::update_genesis, forge_utils::check_the_balance}; +use config::{ + copy_configs, + forge_interface::{ + register_chain::{input::RegisterChainL1Config, output::RegisterChainOutput}, + script_params::REGISTER_CHAIN_SCRIPT_PARAMS, + }, + traits::{ReadConfig, ReadConfigWithBasePath, SaveConfig, SaveConfigWithBasePath}, + ChainConfig, ContractsConfig, EcosystemConfig, +}; pub(crate) async fn run(args: InitArgs, shell: &Shell) -> anyhow::Result<()> { let chain_name = global_config().chain_name.clone(); @@ -53,10 +53,10 @@ pub async fn init( update_genesis(shell, chain_config)?; update_l1_rpc_url_secret(shell, chain_config, init_args.l1_rpc_url.clone())?; let mut contracts_config = - ContractsConfig::read(shell, ecosystem_config.config.join(CONTRACTS_FILE))?; + ContractsConfig::read_with_base_path(shell, &ecosystem_config.config)?; contracts_config.l1.base_token_addr = chain_config.base_token.address; // Copy ecosystem contracts - contracts_config.save(shell, chain_config.configs.join(CONTRACTS_FILE))?; + contracts_config.save_with_base_path(shell, &chain_config.configs)?; let spinner = Spinner::new("Registering chain..."); contracts_config = register_chain( @@ -108,7 +108,7 @@ async fn register_chain( chain_config: &ChainConfig, l1_rpc_url: String, ) -> anyhow::Result { - let deploy_config_path = REGISTER_CHAIN.input(&config.link_to_code); + let deploy_config_path = REGISTER_CHAIN_SCRIPT_PARAMS.input(&config.link_to_code); let contracts = config .get_contracts_config() @@ -117,7 +117,7 @@ async fn register_chain( deploy_config.save(shell, deploy_config_path)?; let mut forge = Forge::new(&config.path_to_foundry()) - .script(®ISTER_CHAIN.script(), forge_args.clone()) + .script(®ISTER_CHAIN_SCRIPT_PARAMS.script(), forge_args.clone()) .with_ffi() .with_rpc_url(l1_rpc_url) .with_broadcast(); @@ -126,7 +126,9 @@ async fn register_chain( check_the_balance(&forge).await?; forge.run(shell)?; - let register_chain_output = - RegisterChainOutput::read(shell, REGISTER_CHAIN.output(&chain_config.link_to_code))?; + let register_chain_output = RegisterChainOutput::read( + shell, + REGISTER_CHAIN_SCRIPT_PARAMS.output(&chain_config.link_to_code), + )?; update_l1_contracts(shell, chain_config, ®ister_chain_output) } diff --git a/zk_toolbox/crates/zk_inception/src/commands/chain/initialize_bridges.rs b/zk_toolbox/crates/zk_inception/src/commands/chain/initialize_bridges.rs index ebeacc1c15af..f11ac68414ca 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/chain/initialize_bridges.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/chain/initialize_bridges.rs @@ -1,6 +1,5 @@ use std::path::Path; -use anyhow::Context; use common::{ cmd::Cmd, config::global_config, @@ -9,16 +8,16 @@ use common::{ }; use xshell::{cmd, Shell}; -use crate::forge_utils::check_the_balance; -use crate::{ - configs::{ - forge_interface::initialize_bridges::{ - input::InitializeBridgeInput, output::InitializeBridgeOutput, - }, - update_l2_shared_bridge, ChainConfig, EcosystemConfig, ReadConfig, SaveConfig, +use crate::forge_utils::fill_forge_private_key; +use crate::{config_manipulations::update_l2_shared_bridge, forge_utils::check_the_balance}; +use anyhow::Context; +use config::{ + forge_interface::{ + initialize_bridges::{input::InitializeBridgeInput, output::InitializeBridgeOutput}, + script_params::INITIALIZE_BRIDGES_SCRIPT_PARAMS, }, - consts::INITIALIZE_BRIDGES, - forge_utils::fill_forge_private_key, + traits::{ReadConfig, SaveConfig}, + ChainConfig, EcosystemConfig, }; pub async fn run(args: ForgeScriptArgs, shell: &Shell) -> anyhow::Result<()> { @@ -45,10 +44,16 @@ pub async fn initialize_bridges( let input = InitializeBridgeInput::new(chain_config, ecosystem_config.era_chain_id)?; let foundry_contracts_path = chain_config.path_to_foundry(); let secrets = chain_config.get_secrets_config()?; - input.save(shell, INITIALIZE_BRIDGES.input(&chain_config.link_to_code))?; + input.save( + shell, + INITIALIZE_BRIDGES_SCRIPT_PARAMS.input(&chain_config.link_to_code), + )?; let mut forge = Forge::new(&foundry_contracts_path) - .script(&INITIALIZE_BRIDGES.script(), forge_args.clone()) + .script( + &INITIALIZE_BRIDGES_SCRIPT_PARAMS.script(), + forge_args.clone(), + ) .with_ffi() .with_rpc_url(secrets.l1.l1_rpc_url.clone()) .with_broadcast(); @@ -61,8 +66,10 @@ pub async fn initialize_bridges( check_the_balance(&forge).await?; forge.run(shell)?; - let output = - InitializeBridgeOutput::read(shell, INITIALIZE_BRIDGES.output(&chain_config.link_to_code))?; + let output = InitializeBridgeOutput::read( + shell, + INITIALIZE_BRIDGES_SCRIPT_PARAMS.output(&chain_config.link_to_code), + )?; update_l2_shared_bridge(shell, chain_config, &output)?; Ok(()) diff --git a/zk_toolbox/crates/zk_inception/src/commands/containers.rs b/zk_toolbox/crates/zk_inception/src/commands/containers.rs index 82bb2b48520e..db9293710828 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/containers.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/containers.rs @@ -3,7 +3,7 @@ use common::{docker, logger, spinner::Spinner}; use std::path::PathBuf; use xshell::Shell; -use crate::{configs::EcosystemConfig, consts::DOCKER_COMPOSE_FILE}; +use config::{EcosystemConfig, DOCKER_COMPOSE_FILE}; pub fn run(shell: &Shell) -> anyhow::Result<()> { let ecosystem = diff --git a/zk_toolbox/crates/zk_inception/src/commands/ecosystem/args/create.rs b/zk_toolbox/crates/zk_inception/src/commands/ecosystem/args/create.rs index 259050bce049..2008ff1e63c5 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/ecosystem/args/create.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/ecosystem/args/create.rs @@ -5,12 +5,9 @@ use common::{slugify, Prompt, PromptConfirm, PromptSelect}; use serde::{Deserialize, Serialize}; use strum::IntoEnumIterator; use strum_macros::{Display, EnumIter}; +use types::{L1Network, WalletCreation}; -use crate::{ - commands::chain::{args::create::ChainCreateArgs, ChainCreateArgsFinal}, - types::L1Network, - wallets::WalletCreation, -}; +use crate::commands::chain::{args::create::ChainCreateArgs, ChainCreateArgsFinal}; #[derive(Debug, Serialize, Deserialize, Parser)] pub struct EcosystemCreateArgs { diff --git a/zk_toolbox/crates/zk_inception/src/commands/ecosystem/args/init.rs b/zk_toolbox/crates/zk_inception/src/commands/ecosystem/args/init.rs index e1bda4736ac8..ac1db3a52259 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/ecosystem/args/init.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/ecosystem/args/init.rs @@ -3,11 +3,11 @@ use std::path::PathBuf; use clap::Parser; use common::{forge::ForgeScriptArgs, Prompt, PromptConfirm}; use serde::{Deserialize, Serialize}; +use types::L1Network; use url::Url; use crate::commands::chain::args::genesis::GenesisArgs; use crate::defaults::LOCAL_RPC_URL; -use crate::types::L1Network; #[derive(Debug, Clone, Serialize, Deserialize, Parser)] pub struct EcosystemArgs { diff --git a/zk_toolbox/crates/zk_inception/src/commands/ecosystem/change_default.rs b/zk_toolbox/crates/zk_inception/src/commands/ecosystem/change_default.rs index 2541e8af88ea..1dd3bcdee6ba 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/ecosystem/change_default.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/ecosystem/change_default.rs @@ -1,11 +1,8 @@ use common::PromptSelect; use xshell::Shell; -use crate::{ - commands::ecosystem::args::change_default::ChangeDefaultChain, - configs::{EcosystemConfig, SaveConfig}, - consts::CONFIG_NAME, -}; +use crate::commands::ecosystem::args::change_default::ChangeDefaultChain; +use config::{traits::SaveConfigWithBasePath, EcosystemConfig}; pub fn run(args: ChangeDefaultChain, shell: &Shell) -> anyhow::Result<()> { let mut ecosystem_config = EcosystemConfig::from_file(shell)?; @@ -25,5 +22,5 @@ pub fn run(args: ChangeDefaultChain, shell: &Shell) -> anyhow::Result<()> { ); } ecosystem_config.default_chain = chain_name; - ecosystem_config.save(shell, CONFIG_NAME) + ecosystem_config.save_with_base_path(shell, ".") } 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 d3548a154607..7bce12a5a40e 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/ecosystem/create.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/ecosystem/create.rs @@ -5,18 +5,18 @@ use anyhow::bail; use common::{cmd::Cmd, logger, spinner::Spinner}; use xshell::{cmd, Shell}; -use crate::{ - commands::{ - chain::create_chain_inner, - containers::{initialize_docker, start_containers}, - ecosystem::{ - args::create::EcosystemCreateArgs, - create_configs::{create_erc20_deployment_config, create_initial_deployments_config}, - }, +use crate::commands::{ + chain::create_chain_inner, + containers::{initialize_docker, start_containers}, + ecosystem::{ + args::create::EcosystemCreateArgs, + create_configs::{create_erc20_deployment_config, create_initial_deployments_config}, }, - configs::{EcosystemConfig, EcosystemConfigFromFileError, SaveConfig}, - consts::{CONFIG_NAME, ERA_CHAIN_ID, LOCAL_CONFIGS_PATH, WALLETS_FILE, ZKSYNC_ERA_GIT_REPO}, - wallets::create_wallets, +}; +use config::traits::SaveConfigWithBasePath; +use config::{ + create_local_configs_dir, create_wallets, get_default_era_chain_id, EcosystemConfig, + EcosystemConfigFromFileError, ZKSYNC_ERA_GIT_REPO, }; pub fn run(args: EcosystemCreateArgs, shell: &Shell) -> anyhow::Result<()> { @@ -41,7 +41,7 @@ fn create(args: EcosystemCreateArgs, shell: &Shell) -> anyhow::Result<()> { shell.create_dir(ecosystem_name)?; shell.change_dir(ecosystem_name); - let configs_path = shell.create_dir(LOCAL_CONFIGS_PATH)?; + let configs_path = create_local_configs_dir(shell, ".")?; let link_to_code = if args.link_to_code.is_empty() { let spinner = Spinner::new("Cloning zksync-era repository..."); @@ -68,8 +68,8 @@ fn create(args: EcosystemCreateArgs, shell: &Shell) -> anyhow::Result<()> { link_to_code: link_to_code.clone(), chains: chains_path.clone(), config: configs_path, + era_chain_id: get_default_era_chain_id(), default_chain: default_chain_name.clone(), - era_chain_id: ERA_CHAIN_ID, prover_version: chain_config.prover_version, wallet_creation: args.wallet_creation, shell: shell.clone().into(), @@ -78,13 +78,13 @@ fn create(args: EcosystemCreateArgs, shell: &Shell) -> anyhow::Result<()> { // Use 0 id for ecosystem wallets create_wallets( shell, - &ecosystem_config.config.join(WALLETS_FILE), + &ecosystem_config.config, &ecosystem_config.link_to_code, 0, args.wallet_creation, args.wallet_path, )?; - ecosystem_config.save(shell, CONFIG_NAME)?; + ecosystem_config.save_with_base_path(shell, ".")?; spinner.finish(); let spinner = Spinner::new("Creating default chain..."); diff --git a/zk_toolbox/crates/zk_inception/src/commands/ecosystem/create_configs.rs b/zk_toolbox/crates/zk_inception/src/commands/ecosystem/create_configs.rs index e99da136b916..b7bae096e18d 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/ecosystem/create_configs.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/ecosystem/create_configs.rs @@ -1,23 +1,17 @@ use std::path::Path; -use xshell::Shell; - -use crate::{ - configs::{ - forge_interface::deploy_ecosystem::input::{ - Erc20DeploymentConfig, InitialDeploymentConfig, - }, - SaveConfigWithComment, - }, - consts::{ERC20_DEPLOYMENT_FILE, INITIAL_DEPLOYMENT_FILE}, +use config::{ + forge_interface::deploy_ecosystem::input::{Erc20DeploymentConfig, InitialDeploymentConfig}, + traits::SaveConfigWithCommentAndBasePath, }; +use xshell::Shell; pub fn create_initial_deployments_config( shell: &Shell, ecosystem_configs_path: &Path, ) -> anyhow::Result { let config = InitialDeploymentConfig::default(); - config.save_with_comment(shell, ecosystem_configs_path.join(INITIAL_DEPLOYMENT_FILE), "ATTENTION: This file contains sensible placeholders. Please check them and update with the desired values.")?; + config.save_with_comment_and_base_path(shell, ecosystem_configs_path, "ATTENTION: This file contains sensible placeholders. Please check them and update with the desired values.")?; Ok(config) } @@ -26,9 +20,9 @@ pub fn create_erc20_deployment_config( ecosystem_configs_path: &Path, ) -> anyhow::Result { let config = Erc20DeploymentConfig::default(); - config.save_with_comment( + config.save_with_comment_and_base_path( shell, - ecosystem_configs_path.join(ERC20_DEPLOYMENT_FILE), + ecosystem_configs_path, "ATTENTION: This file should be filled with the desired ERC20 tokens to deploy.", )?; Ok(config) 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 451acfbf0968..28213dab1d58 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/ecosystem/init.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/ecosystem/init.rs @@ -15,7 +15,6 @@ use common::{ use xshell::{cmd, Shell}; use super::args::init::{EcosystemArgsFinal, EcosystemInitArgs, EcosystemInitArgsFinal}; -use crate::forge_utils::check_the_balance; use crate::{ accept_ownership::accept_owner, commands::{ @@ -24,23 +23,26 @@ use crate::{ create_erc20_deployment_config, create_initial_deployments_config, }, }, - configs::{ - forge_interface::deploy_ecosystem::{ + forge_utils::fill_forge_private_key, +}; +use crate::{consts::AMOUNT_FOR_DISTRIBUTION_TO_WALLETS, forge_utils::check_the_balance}; +use config::{ + forge_interface::{ + deploy_ecosystem::{ input::{ DeployErc20Config, DeployL1Config, Erc20DeploymentConfig, InitialDeploymentConfig, }, output::{DeployErc20Output, DeployL1Output}, }, - ChainConfig, ContractsConfig, EcosystemConfig, GenesisConfig, ReadConfig, SaveConfig, + script_params::{DEPLOY_ECOSYSTEM_SCRIPT_PARAMS, DEPLOY_ERC20_SCRIPT_PARAMS}, }, - consts::{ - AMOUNT_FOR_DISTRIBUTION_TO_WALLETS, CONFIGS_PATH, CONTRACTS_FILE, DEPLOY_ECOSYSTEM, - DEPLOY_ERC20, ECOSYSTEM_PATH, ERC20_CONFIGS_FILE, GENESIS_FILE, + traits::{ + FileConfigWithDefaultName, ReadConfig, ReadConfigWithBasePath, SaveConfig, + SaveConfigWithBasePath, }, - forge_utils::fill_forge_private_key, - types::{L1Network, ProverMode}, - wallets::WalletCreation, + ChainConfig, ContractsConfig, EcosystemConfig, GenesisConfig, }; +use types::{L1Network, ProverMode, WalletCreation}; pub async fn run(args: EcosystemInitArgs, shell: &Shell) -> anyhow::Result<()> { let ecosystem_config = EcosystemConfig::from_file(shell)?; @@ -176,7 +178,7 @@ async fn init( initial_deployment_config, ) .await?; - contracts.save(shell, ecosystem_config.config.clone().join(CONTRACTS_FILE))?; + contracts.save_with_base_path(shell, &ecosystem_config.config)?; Ok(contracts) } @@ -188,12 +190,12 @@ async fn deploy_erc20( forge_args: ForgeScriptArgs, l1_rpc_url: String, ) -> anyhow::Result { - let deploy_config_path = DEPLOY_ERC20.input(&ecosystem_config.link_to_code); + let deploy_config_path = DEPLOY_ERC20_SCRIPT_PARAMS.input(&ecosystem_config.link_to_code); DeployErc20Config::new(erc20_deployment_config, contracts_config) .save(shell, deploy_config_path)?; let mut forge = Forge::new(&ecosystem_config.path_to_foundry()) - .script(&DEPLOY_ERC20.script(), forge_args.clone()) + .script(&DEPLOY_ERC20_SCRIPT_PARAMS.script(), forge_args.clone()) .with_ffi() .with_rpc_url(l1_rpc_url) .with_broadcast(); @@ -208,9 +210,11 @@ async fn deploy_erc20( forge.run(shell)?; spinner.finish(); - let result = - DeployErc20Output::read(shell, DEPLOY_ERC20.output(&ecosystem_config.link_to_code))?; - result.save(shell, ecosystem_config.config.join(ERC20_CONFIGS_FILE))?; + let result = DeployErc20Output::read( + shell, + DEPLOY_ERC20_SCRIPT_PARAMS.output(&ecosystem_config.link_to_code), + )?; + result.save_with_base_path(shell, &ecosystem_config.config)?; Ok(result) } @@ -254,14 +258,11 @@ async fn deploy_ecosystem( let ecosystem_contracts_path = ecosystem_contracts_path.unwrap_or_else(|| match ecosystem_config.l1_network { - L1Network::Localhost => ecosystem_config.config.join(CONTRACTS_FILE), - L1Network::Sepolia => ecosystem_config - .link_to_code - .join(ECOSYSTEM_PATH) - .join(ecosystem_config.l1_network.to_string().to_lowercase()), - L1Network::Mainnet => ecosystem_config - .link_to_code - .join(ECOSYSTEM_PATH) + L1Network::Localhost => { + ContractsConfig::get_path_with_base_path(&ecosystem_config.config) + } + L1Network::Sepolia | L1Network::Mainnet => ecosystem_config + .get_preexisting_configs_path() .join(ecosystem_config.l1_network.to_string().to_lowercase()), }); @@ -275,13 +276,11 @@ async fn deploy_ecosystem_inner( initial_deployment_config: &InitialDeploymentConfig, l1_rpc_url: String, ) -> anyhow::Result { - let deploy_config_path = DEPLOY_ECOSYSTEM.input(&config.link_to_code); + let deploy_config_path = DEPLOY_ECOSYSTEM_SCRIPT_PARAMS.input(&config.link_to_code); - let default_genesis_config = GenesisConfig::read( - shell, - config.link_to_code.join(CONFIGS_PATH).join(GENESIS_FILE), - ) - .context("Context")?; + let default_genesis_config = + GenesisConfig::read_with_base_path(shell, config.get_default_configs_path()) + .context("Context")?; let wallets_config = config.get_wallets()?; // For deploying ecosystem we only need genesis batch params @@ -295,7 +294,7 @@ async fn deploy_ecosystem_inner( deploy_config.save(shell, deploy_config_path)?; let mut forge = Forge::new(&config.path_to_foundry()) - .script(&DEPLOY_ECOSYSTEM.script(), forge_args.clone()) + .script(&DEPLOY_ECOSYSTEM_SCRIPT_PARAMS.script(), forge_args.clone()) .with_ffi() .with_rpc_url(l1_rpc_url.clone()) .with_broadcast(); @@ -312,7 +311,10 @@ async fn deploy_ecosystem_inner( forge.run(shell)?; spinner.finish(); - let script_output = DeployL1Output::read(shell, DEPLOY_ECOSYSTEM.output(&config.link_to_code))?; + let script_output = DeployL1Output::read( + shell, + DEPLOY_ECOSYSTEM_SCRIPT_PARAMS.output(&config.link_to_code), + )?; let mut contracts_config = ContractsConfig::default(); contracts_config.update_from_l1_output(&script_output); accept_owner( diff --git a/zk_toolbox/crates/zk_inception/src/commands/server.rs b/zk_toolbox/crates/zk_inception/src/commands/server.rs index a46b42c17050..608ca0a6fc02 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/server.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/server.rs @@ -4,9 +4,9 @@ use xshell::Shell; use crate::{ commands::args::RunServerArgs, - configs::{ChainConfig, EcosystemConfig}, server::{RunServer, ServerMode}, }; +use config::{ChainConfig, EcosystemConfig}; pub fn run(shell: &Shell, args: RunServerArgs) -> anyhow::Result<()> { let ecosystem_config = EcosystemConfig::from_file(shell)?; diff --git a/zk_toolbox/crates/zk_inception/src/config_manipulations.rs b/zk_toolbox/crates/zk_inception/src/config_manipulations.rs new file mode 100644 index 000000000000..03eb85403e52 --- /dev/null +++ b/zk_toolbox/crates/zk_inception/src/config_manipulations.rs @@ -0,0 +1,93 @@ +use xshell::Shell; + +use crate::defaults::{ROCKS_DB_STATE_KEEPER, ROCKS_DB_TREE}; +use config::{ + forge_interface::{ + initialize_bridges::output::InitializeBridgeOutput, paymaster::DeployPaymasterOutput, + register_chain::output::RegisterChainOutput, + }, + traits::{ReadConfigWithBasePath, SaveConfigWithBasePath}, + ChainConfig, ContractsConfig, DatabasesConfig, GeneralConfig, GenesisConfig, SecretsConfig, +}; +use types::ProverMode; + +pub(crate) fn update_genesis(shell: &Shell, config: &ChainConfig) -> anyhow::Result<()> { + let mut genesis = GenesisConfig::read_with_base_path(shell, &config.configs)?; + + genesis.l2_chain_id = config.chain_id; + genesis.l1_chain_id = config.l1_network.chain_id(); + genesis.l1_batch_commit_data_generator_mode = Some(config.l1_batch_commit_data_generator_mode); + + genesis.save_with_base_path(shell, &config.configs)?; + Ok(()) +} + +pub(crate) fn update_database_secrets( + shell: &Shell, + config: &ChainConfig, + db_config: &DatabasesConfig, +) -> anyhow::Result<()> { + let mut secrets = SecretsConfig::read_with_base_path(shell, &config.configs)?; + secrets.database.server_url = db_config.server.full_url(); + secrets.database.prover_url = db_config.prover.full_url(); + secrets.save_with_base_path(shell, &config.configs)?; + Ok(()) +} + +pub(crate) fn update_l1_rpc_url_secret( + shell: &Shell, + config: &ChainConfig, + l1_rpc_url: String, +) -> anyhow::Result<()> { + let mut secrets = SecretsConfig::read_with_base_path(shell, &config.configs)?; + secrets.l1.l1_rpc_url = l1_rpc_url; + secrets.save_with_base_path(shell, &config.configs)?; + Ok(()) +} + +pub(crate) fn update_general_config(shell: &Shell, config: &ChainConfig) -> anyhow::Result<()> { + let mut general = GeneralConfig::read_with_base_path(shell, &config.configs)?; + general.db.state_keeper_db_path = + shell.create_dir(config.rocks_db_path.join(ROCKS_DB_STATE_KEEPER))?; + general.db.merkle_tree.path = shell.create_dir(config.rocks_db_path.join(ROCKS_DB_TREE))?; + if config.prover_version != ProverMode::NoProofs { + general.eth.sender.proof_sending_mode = "ONLY_REAL_PROOFS".to_string(); + } + general.save_with_base_path(shell, &config.configs)?; + Ok(()) +} + +pub fn update_l1_contracts( + shell: &Shell, + config: &ChainConfig, + register_chain_output: &RegisterChainOutput, +) -> anyhow::Result { + let mut contracts_config = ContractsConfig::read_with_base_path(shell, &config.configs)?; + contracts_config.l1.diamond_proxy_addr = register_chain_output.diamond_proxy_addr; + contracts_config.l1.governance_addr = register_chain_output.governance_addr; + contracts_config.save_with_base_path(shell, &config.configs)?; + Ok(contracts_config) +} + +pub fn update_l2_shared_bridge( + shell: &Shell, + config: &ChainConfig, + initialize_bridges_output: &InitializeBridgeOutput, +) -> anyhow::Result<()> { + let mut contracts_config = ContractsConfig::read_with_base_path(shell, &config.configs)?; + contracts_config.bridges.shared.l2_address = + Some(initialize_bridges_output.l2_shared_bridge_proxy); + contracts_config.save_with_base_path(shell, &config.configs)?; + Ok(()) +} + +pub fn update_paymaster( + shell: &Shell, + config: &ChainConfig, + paymaster_output: &DeployPaymasterOutput, +) -> anyhow::Result<()> { + let mut contracts_config = ContractsConfig::read_with_base_path(shell, &config.configs)?; + contracts_config.l2.testnet_paymaster_addr = paymaster_output.paymaster; + contracts_config.save_with_base_path(shell, &config.configs)?; + Ok(()) +} diff --git a/zk_toolbox/crates/zk_inception/src/configs/manipulations.rs b/zk_toolbox/crates/zk_inception/src/configs/manipulations.rs deleted file mode 100644 index e8522a0446d9..000000000000 --- a/zk_toolbox/crates/zk_inception/src/configs/manipulations.rs +++ /dev/null @@ -1,124 +0,0 @@ -use std::path::Path; - -use xshell::Shell; - -use crate::{ - configs::{ - chain::ChainConfig, - contracts::ContractsConfig, - forge_interface::{ - initialize_bridges::output::InitializeBridgeOutput, paymaster::DeployPaymasterOutput, - register_chain::output::RegisterChainOutput, - }, - DatabasesConfig, GeneralConfig, GenesisConfig, ReadConfig, SaveConfig, Secrets, - }, - consts::{ - CONFIGS_PATH, CONTRACTS_FILE, GENERAL_FILE, GENESIS_FILE, SECRETS_FILE, WALLETS_FILE, - }, - defaults::{ROCKS_DB_STATE_KEEPER, ROCKS_DB_TREE}, - types::ProverMode, -}; - -pub(crate) fn copy_configs( - shell: &Shell, - link_to_code: &Path, - chain_config_path: &Path, -) -> anyhow::Result<()> { - let original_configs = link_to_code.join(CONFIGS_PATH); - for file in shell.read_dir(original_configs)? { - if let Some(name) = file.file_name() { - // Do not copy wallets file - if name != WALLETS_FILE { - shell.copy_file(file, chain_config_path)?; - } - } - } - Ok(()) -} - -pub(crate) fn update_genesis(shell: &Shell, config: &ChainConfig) -> anyhow::Result<()> { - let path = config.configs.join(GENESIS_FILE); - let mut genesis = GenesisConfig::read(shell, &path)?; - - genesis.l2_chain_id = config.chain_id; - genesis.l1_chain_id = config.l1_network.chain_id(); - genesis.l1_batch_commit_data_generator_mode = Some(config.l1_batch_commit_data_generator_mode); - - genesis.save(shell, &path)?; - Ok(()) -} - -pub(crate) fn update_database_secrets( - shell: &Shell, - config: &ChainConfig, - db_config: &DatabasesConfig, -) -> anyhow::Result<()> { - let path = config.configs.join(SECRETS_FILE); - let mut secrets = Secrets::read(shell, &path)?; - secrets.database.server_url = db_config.server.full_url(); - secrets.database.prover_url = db_config.prover.full_url(); - secrets.save(shell, path)?; - Ok(()) -} - -pub(crate) fn update_l1_rpc_url_secret( - shell: &Shell, - config: &ChainConfig, - l1_rpc_url: String, -) -> anyhow::Result<()> { - let path = config.configs.join(SECRETS_FILE); - let mut secrets = Secrets::read(shell, &path)?; - secrets.l1.l1_rpc_url = l1_rpc_url; - secrets.save(shell, path)?; - Ok(()) -} -pub(crate) fn update_general_config(shell: &Shell, config: &ChainConfig) -> anyhow::Result<()> { - let path = config.configs.join(GENERAL_FILE); - let mut general = GeneralConfig::read(shell, &path)?; - general.db.state_keeper_db_path = - shell.create_dir(config.rocks_db_path.join(ROCKS_DB_STATE_KEEPER))?; - general.db.merkle_tree.path = shell.create_dir(config.rocks_db_path.join(ROCKS_DB_TREE))?; - if config.prover_version != ProverMode::NoProofs { - general.eth.sender.proof_sending_mode = "ONLY_REAL_PROOFS".to_string(); - } - general.save(shell, path)?; - Ok(()) -} - -pub fn update_l1_contracts( - shell: &Shell, - config: &ChainConfig, - register_chain_output: &RegisterChainOutput, -) -> anyhow::Result { - let contracts_config_path = config.configs.join(CONTRACTS_FILE); - let mut contracts_config = ContractsConfig::read(shell, &contracts_config_path)?; - contracts_config.l1.diamond_proxy_addr = register_chain_output.diamond_proxy_addr; - contracts_config.l1.governance_addr = register_chain_output.governance_addr; - contracts_config.save(shell, &contracts_config_path)?; - Ok(contracts_config) -} - -pub fn update_l2_shared_bridge( - shell: &Shell, - config: &ChainConfig, - initialize_bridges_output: &InitializeBridgeOutput, -) -> anyhow::Result<()> { - let contracts_config_path = config.configs.join(CONTRACTS_FILE); - let mut contracts_config = ContractsConfig::read(shell, &contracts_config_path)?; - contracts_config.bridges.shared.l2_address = - Some(initialize_bridges_output.l2_shared_bridge_proxy); - contracts_config.save(shell, &contracts_config_path)?; - Ok(()) -} - -pub fn update_paymaster( - shell: &Shell, - config: &ChainConfig, - paymaster_output: &DeployPaymasterOutput, -) -> anyhow::Result<()> { - let contracts_config_path = config.configs.join(CONTRACTS_FILE); - let mut contracts_config = ContractsConfig::read(shell, &contracts_config_path)?; - contracts_config.l2.testnet_paymaster_addr = paymaster_output.paymaster; - contracts_config.save(shell, &contracts_config_path)?; - Ok(()) -} diff --git a/zk_toolbox/crates/zk_inception/src/configs/traits.rs b/zk_toolbox/crates/zk_inception/src/configs/traits.rs deleted file mode 100644 index 29e9fe6c22af..000000000000 --- a/zk_toolbox/crates/zk_inception/src/configs/traits.rs +++ /dev/null @@ -1,77 +0,0 @@ -use std::path::Path; - -use anyhow::{bail, Context}; -use common::files::{save_json_file, save_toml_file, save_yaml_file}; -use serde::{de::DeserializeOwned, Serialize}; -use xshell::Shell; - -/// Reads a config file from a given path, correctly parsing file extension. -/// Supported file extensions are: `yaml`, `yml`, `toml`, `json`. -pub trait ReadConfig: DeserializeOwned + Clone { - fn read(shell: &Shell, path: impl AsRef) -> anyhow::Result { - let file = shell.read_file(&path).with_context(|| { - format!( - "Failed to open config file. Please check if the file exists: {:?}", - path.as_ref() - ) - })?; - let error_context = || format!("Failed to parse config file {:?}.", path.as_ref()); - - match path.as_ref().extension().and_then(|ext| ext.to_str()) { - Some("yaml") | Some("yml") => serde_yaml::from_str(&file).with_context(error_context), - Some("toml") => toml::from_str(&file).with_context(error_context), - Some("json") => serde_json::from_str(&file).with_context(error_context), - _ => bail!(format!( - "Unsupported file extension for config file {:?}.", - path.as_ref() - )), - } - } -} - -/// Saves a config file to a given path, correctly parsing file extension. -/// Supported file extensions are: `yaml`, `yml`, `toml`, `json`. -pub trait SaveConfig: Serialize + Sized { - fn save(&self, shell: &Shell, path: impl AsRef) -> anyhow::Result<()> { - save_with_comment(shell, path, self, "") - } -} - -/// Saves a config file to a given path, correctly parsing file extension. -/// Supported file extensions are: `yaml`, `yml`, `toml`. -pub trait SaveConfigWithComment: Serialize + Sized { - fn save_with_comment( - &self, - shell: &Shell, - path: impl AsRef, - comment: &str, - ) -> anyhow::Result<()> { - let comment_char = match path.as_ref().extension().and_then(|ext| ext.to_str()) { - Some("yaml") | Some("yml") | Some("toml") => "#", - _ => bail!("Unsupported file extension for config file."), - }; - let comment_lines = comment - .lines() - .map(|line| format!("{comment_char} {line}")) - .chain(std::iter::once("".to_string())) // Add a newline after the comment - .collect::>() - .join("\n"); - - save_with_comment(shell, path, self, comment_lines) - } -} - -fn save_with_comment( - shell: &Shell, - path: impl AsRef, - data: impl Serialize, - comment: impl ToString, -) -> anyhow::Result<()> { - match path.as_ref().extension().and_then(|ext| ext.to_str()) { - Some("yaml") | Some("yml") => save_yaml_file(shell, path, data, comment)?, - Some("toml") => save_toml_file(shell, path, data, comment)?, - Some("json") => save_json_file(shell, path, data)?, - _ => bail!("Unsupported file extension for config file."), - } - Ok(()) -} diff --git a/zk_toolbox/crates/zk_inception/src/consts.rs b/zk_toolbox/crates/zk_inception/src/consts.rs index 8993981c4c98..a59024d09b40 100644 --- a/zk_toolbox/crates/zk_inception/src/consts.rs +++ b/zk_toolbox/crates/zk_inception/src/consts.rs @@ -1,105 +1,3 @@ -use std::path::{Path, PathBuf}; +pub const AMOUNT_FOR_DISTRIBUTION_TO_WALLETS: u128 = 1000000000000000000000; -use crate::types::ChainId; - -/// Name of the main configuration file -pub(super) const CONFIG_NAME: &str = "ZkStack.yaml"; -/// Name of the wallets file -pub(super) const WALLETS_FILE: &str = "wallets.yaml"; -/// Name of the secrets config file -pub(super) const SECRETS_FILE: &str = "secrets.yaml"; -/// Name of the general config file -pub(super) const GENERAL_FILE: &str = "general.yaml"; -/// Name of the genesis config file -pub(super) const GENESIS_FILE: &str = "genesis.yaml"; - -pub(super) const ERC20_CONFIGS_FILE: &str = "erc20.yaml"; -/// Name of the initial deployments config file -pub(super) const INITIAL_DEPLOYMENT_FILE: &str = "initial_deployments.yaml"; -/// Name of the erc20 deployments config file -pub(super) const ERC20_DEPLOYMENT_FILE: &str = "erc20_deployments.yaml"; -/// Name of the contracts file -pub(super) const CONTRACTS_FILE: &str = "contracts.yaml"; -/// Main repository for the zkSync project -pub(super) const ZKSYNC_ERA_GIT_REPO: &str = "https://github.com/matter-labs/zksync-era"; -/// Name of the docker-compose file inside zksync repository -pub(super) const DOCKER_COMPOSE_FILE: &str = "docker-compose.yml"; -/// Path to the config file with mnemonic for localhost wallets -pub(super) const CONFIGS_PATH: &str = "etc/env/file_based"; -pub(super) const LOCAL_CONFIGS_PATH: &str = "configs/"; -pub(super) const LOCAL_DB_PATH: &str = "db/"; - -/// Path to ecosystem contacts -pub(super) const ECOSYSTEM_PATH: &str = "etc/ecosystem"; - -/// Path to l1 contracts foundry folder inside zksync-era -pub(super) const L1_CONTRACTS_FOUNDRY: &str = "contracts/l1-contracts-foundry"; -/// Path to DeployL1.s.sol script inside zksync-era relative to `L1_CONTRACTS_FOUNDRY` - -pub(super) const ERA_CHAIN_ID: ChainId = ChainId(270); - -pub(super) const TEST_CONFIG_PATH: &str = "etc/test_config/constant/eth.json"; -pub(super) const BASE_PATH: &str = "m/44'/60'/0'"; -pub(super) const AMOUNT_FOR_DISTRIBUTION_TO_WALLETS: u128 = 1000000000000000000000; - -pub(super) const MINIMUM_BALANCE_FOR_WALLET: u128 = 5000000000000000000; - -#[derive(PartialEq, Debug, Clone)] -pub struct ForgeScriptParams { - input: &'static str, - output: &'static str, - script_path: &'static str, -} - -impl ForgeScriptParams { - // Path to the input file for forge script - pub fn input(&self, link_to_code: &Path) -> PathBuf { - link_to_code.join(L1_CONTRACTS_FOUNDRY).join(self.input) - } - - // Path to the output file for forge script - pub fn output(&self, link_to_code: &Path) -> PathBuf { - link_to_code.join(L1_CONTRACTS_FOUNDRY).join(self.output) - } - - // Path to the script - pub fn script(&self) -> PathBuf { - PathBuf::from(self.script_path) - } -} - -pub const DEPLOY_ECOSYSTEM: ForgeScriptParams = ForgeScriptParams { - input: "script-config/config-deploy-l1.toml", - output: "script-out/output-deploy-l1.toml", - script_path: "script/DeployL1.s.sol", -}; - -pub const INITIALIZE_BRIDGES: ForgeScriptParams = ForgeScriptParams { - input: "script-config/config-initialize-shared-bridges.toml", - output: "script-out/output-initialize-shared-bridges.toml", - script_path: "script/InitializeSharedBridgeOnL2.sol", -}; - -pub const REGISTER_CHAIN: ForgeScriptParams = ForgeScriptParams { - input: "script-config/register-hyperchain.toml", - output: "script-out/output-register-hyperchain.toml", - script_path: "script/RegisterHyperchain.s.sol", -}; - -pub const DEPLOY_ERC20: ForgeScriptParams = ForgeScriptParams { - input: "script-config/config-deploy-erc20.toml", - output: "script-out/output-deploy-erc20.toml", - script_path: "script/DeployErc20.s.sol", -}; - -pub const DEPLOY_PAYMASTER: ForgeScriptParams = ForgeScriptParams { - input: "script-config/config-deploy-paymaster.toml", - output: "script-out/output-deploy-paymaster.toml", - script_path: "script/DeployPaymaster.s.sol", -}; - -pub const ACCEPT_GOVERNANCE: ForgeScriptParams = ForgeScriptParams { - input: "script-config/config-accept-admin.toml", - output: "script-out/output-accept-admin.toml", - script_path: "script/AcceptAdmin.s.sol", -}; +pub const MINIMUM_BALANCE_FOR_WALLET: u128 = 5000000000000000000; diff --git a/zk_toolbox/crates/zk_inception/src/defaults.rs b/zk_toolbox/crates/zk_inception/src/defaults.rs index 4ac90a54fc37..4b768abe907d 100644 --- a/zk_toolbox/crates/zk_inception/src/defaults.rs +++ b/zk_toolbox/crates/zk_inception/src/defaults.rs @@ -1,4 +1,4 @@ -use crate::configs::ChainConfig; +use config::ChainConfig; pub const DATABASE_SERVER_URL: &str = "postgres://postgres:notsecurepassword@localhost:5432"; pub const DATABASE_PROVER_URL: &str = "postgres://postgres:notsecurepassword@localhost:5432"; @@ -15,6 +15,7 @@ pub struct DBNames { pub server_name: String, pub prover_name: String, } + pub fn generate_db_names(config: &ChainConfig) -> DBNames { DBNames { server_name: format!( diff --git a/zk_toolbox/crates/zk_inception/src/forge_utils.rs b/zk_toolbox/crates/zk_inception/src/forge_utils.rs index 5ee7564ddf74..29929ddab917 100644 --- a/zk_toolbox/crates/zk_inception/src/forge_utils.rs +++ b/zk_toolbox/crates/zk_inception/src/forge_utils.rs @@ -1,7 +1,7 @@ use crate::consts::MINIMUM_BALANCE_FOR_WALLET; use anyhow::anyhow; use common::forge::ForgeScript; -use ethers::types::H256; +use ethers::types::{H256, U256}; pub fn fill_forge_private_key( mut forge: ForgeScript, @@ -20,7 +20,7 @@ pub async fn check_the_balance(forge: &ForgeScript) -> anyhow::Result<()> { }; while !forge - .check_the_balance(MINIMUM_BALANCE_FOR_WALLET.into()) + .check_the_balance(U256::from(MINIMUM_BALANCE_FOR_WALLET)) .await? { if common::PromptConfirm::new(format!("Address {address:?} doesn't have enough money to deploy contracts do you want to continue?")).ask() { diff --git a/zk_toolbox/crates/zk_inception/src/main.rs b/zk_toolbox/crates/zk_inception/src/main.rs index e4996b4893cf..73054e42f6d2 100644 --- a/zk_toolbox/crates/zk_inception/src/main.rs +++ b/zk_toolbox/crates/zk_inception/src/main.rs @@ -6,20 +6,16 @@ use common::{ }; use xshell::Shell; -use crate::{ - commands::{args::RunServerArgs, chain::ChainCommands, ecosystem::EcosystemCommands}, - configs::EcosystemConfig, -}; +use crate::commands::{args::RunServerArgs, chain::ChainCommands, ecosystem::EcosystemCommands}; +use config::EcosystemConfig; pub mod accept_ownership; mod commands; -mod configs; +mod config_manipulations; mod consts; mod defaults; pub mod forge_utils; pub mod server; -mod types; -mod wallets; #[derive(Parser, Debug)] #[command(version, about)] diff --git a/zk_toolbox/crates/zk_inception/src/server.rs b/zk_toolbox/crates/zk_inception/src/server.rs index a2cc48677af6..a7e6f465e1ce 100644 --- a/zk_toolbox/crates/zk_inception/src/server.rs +++ b/zk_toolbox/crates/zk_inception/src/server.rs @@ -2,12 +2,11 @@ use std::path::PathBuf; use anyhow::Context; use common::cmd::Cmd; -use xshell::{cmd, Shell}; - -use crate::{ - configs::ChainConfig, - consts::{CONTRACTS_FILE, GENERAL_FILE, GENESIS_FILE, SECRETS_FILE, WALLETS_FILE}, +use config::{ + traits::FileConfigWithDefaultName, ChainConfig, ContractsConfig, GeneralConfig, GenesisConfig, + SecretsConfig, WalletsConfig, }; +use xshell::{cmd, Shell}; pub struct RunServer { components: Option>, @@ -26,11 +25,11 @@ pub enum ServerMode { impl RunServer { pub fn new(components: Option>, chain_config: &ChainConfig) -> Self { - let wallets = chain_config.configs.join(WALLETS_FILE); - let general_config = chain_config.configs.join(GENERAL_FILE); - let genesis = chain_config.configs.join(GENESIS_FILE); - let contracts = chain_config.configs.join(CONTRACTS_FILE); - let secrets = chain_config.configs.join(SECRETS_FILE); + let wallets = WalletsConfig::get_path_with_base_path(&chain_config.configs); + let general_config = GeneralConfig::get_path_with_base_path(&chain_config.configs); + let genesis = GenesisConfig::get_path_with_base_path(&chain_config.configs); + let contracts = ContractsConfig::get_path_with_base_path(&chain_config.configs); + let secrets = SecretsConfig::get_path_with_base_path(&chain_config.configs); Self { components, diff --git a/zk_toolbox/crates/zk_inception/src/types.rs b/zk_toolbox/crates/zk_inception/src/types.rs deleted file mode 100644 index 75c10c804927..000000000000 --- a/zk_toolbox/crates/zk_inception/src/types.rs +++ /dev/null @@ -1,108 +0,0 @@ -use std::{fmt::Display, str::FromStr}; - -use clap::ValueEnum; -use ethers::types::Address; -use serde::{Deserialize, Serialize}; -use strum_macros::EnumIter; - -#[derive( - Debug, - Serialize, - Deserialize, - Clone, - Copy, - ValueEnum, - EnumIter, - strum_macros::Display, - Default, - PartialEq, - Eq, -)] -pub enum L1BatchCommitDataGeneratorMode { - #[default] - Rollup, - Validium, -} - -#[derive( - Debug, - Serialize, - Deserialize, - Clone, - Copy, - ValueEnum, - EnumIter, - strum_macros::Display, - PartialEq, - Eq, -)] -pub enum ProverMode { - NoProofs, - Gpu, - Cpu, -} - -#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] -pub struct ChainId(pub u32); - -impl Display for ChainId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.0) - } -} - -impl From for ChainId { - fn from(value: u32) -> Self { - Self(value) - } -} - -#[derive( - Copy, - Clone, - Debug, - Default, - PartialEq, - Eq, - PartialOrd, - Ord, - Serialize, - Deserialize, - ValueEnum, - EnumIter, - strum_macros::Display, -)] -pub enum L1Network { - #[default] - Localhost, - Sepolia, - Mainnet, -} - -impl L1Network { - pub fn chain_id(&self) -> u32 { - match self { - L1Network::Localhost => 9, - L1Network::Sepolia => 11155111, - L1Network::Mainnet => 1, - } - } -} - -#[derive(Debug, Serialize, Deserialize, Clone)] - -pub struct BaseToken { - pub address: Address, - pub nominator: u64, - pub denominator: u64, -} - -impl BaseToken { - pub fn eth() -> Self { - Self { - nominator: 1, - denominator: 1, - address: Address::from_str("0x0000000000000000000000000000000000000001").unwrap(), - } - } -} diff --git a/zk_toolbox/crates/zk_inception/src/wallets/mod.rs b/zk_toolbox/crates/zk_inception/src/wallets/mod.rs deleted file mode 100644 index eec0d6b0a297..000000000000 --- a/zk_toolbox/crates/zk_inception/src/wallets/mod.rs +++ /dev/null @@ -1,6 +0,0 @@ -mod config; -mod create; - -pub use common::wallets::Wallet; -pub use config::WalletCreation; -pub use create::{create_localhost_wallets, create_wallets};