Skip to content

Commit

Permalink
feat(zk_toolbox): Add subcommands and flags for chain registration (#…
Browse files Browse the repository at this point in the history
…2946)

## What ❔
Added subcommands:
`zki chain init configs` - just creates configs with an intention to run
chain initialization manually via subcommands
`zki chain register-chain` - runs steps from `RegisterHyperchain.s.sol`
`zki chain accept-chain-ownership` - accepts ownership for
`DiamondProxy`
`zki chain genesis database` - initializes database only, performs
migration (uses values from args or `secrets.yaml`)
`zki chain genesis server` - runs server --genesis

Added flags:
`zki ecosystem init --ecosystem-only` - runs `init` only for ecosystem
(skips `init` for chain)

Other changes:
* Fixed issue with `--wallet_path` value ignored
* Nullify database names if `zki ecosystem init` is used for multiple
chains
* Zeroify some addresses in `contracts.yaml` when copying from ecosystem
during init

## Why ❔
These changes allow us to run the chain registration process for
externally hosted chains.
Not ideal yet, but the process goes like this:
L1 side:
* Init ecosystem: `zki ecosystem create && zki ecosystem init
--ecosystem-only && zki chain init configs`
* Fill in wallets
* Register chain: `zki chain register-chain`
* Deploy L2 contracts: `zki chain deploy-l2-contracts`
* Share `contracts.yaml`

L2 side:
* Init ecosystem: `zki ecosystem create && zki ecosystem init
--ecosystem-only && zki chain init configs`
* Fill in wallets
* Copy `contracts.yaml`
* Accept ownership: `zki chain accept-chain-ownership`
* Initialize databases: `zki chain genesis database`
* Run server genesis: `zki chain genesis server`

## Checklist
- [x] PR title corresponds to the body of PR (we generate changelog
entries from PRs).
- [ ] Tests for the changes have been added / updated.
- [x] Documentation comments have been added / updated.
- [x] Code has been formatted via `zk fmt` and `zk lint`.
  • Loading branch information
sanekmelnikov authored Oct 2, 2024
1 parent 8d24eb5 commit 057705e
Show file tree
Hide file tree
Showing 19 changed files with 732 additions and 319 deletions.
31 changes: 3 additions & 28 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -9816,7 +9816,7 @@ string-length@^4.0.1:
char-regex "^1.0.2"
strip-ansi "^6.0.0"

"string-width-cjs@npm:string-width@^4.2.0":
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
Expand All @@ -9833,15 +9833,6 @@ string-width@^2.1.0, string-width@^2.1.1:
is-fullwidth-code-point "^2.0.0"
strip-ansi "^4.0.0"

string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"

string-width@^5.0.1, string-width@^5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794"
Expand Down Expand Up @@ -9908,7 +9899,7 @@ string_decoder@~1.1.1:
dependencies:
safe-buffer "~5.1.0"

"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
Expand All @@ -9929,13 +9920,6 @@ strip-ansi@^5.1.0:
dependencies:
ansi-regex "^4.1.0"

strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
ansi-regex "^5.0.1"

strip-ansi@^7.0.1:
version "7.1.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45"
Expand Down Expand Up @@ -10781,16 +10765,7 @@ workerpool@6.2.1:
resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343"
integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==

"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"

wrap-ansi@^7.0.0:
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use anyhow::Context;
use common::{forge::ForgeScriptArgs, logger, spinner::Spinner};
use config::EcosystemConfig;
use xshell::Shell;

use crate::{
accept_ownership::accept_admin,
messages::{
MSG_ACCEPTING_ADMIN_SPINNER, MSG_CHAIN_NOT_INITIALIZED, MSG_CHAIN_OWNERSHIP_TRANSFERRED,
MSG_L1_SECRETS_MUST_BE_PRESENTED,
},
};

pub async fn run(args: ForgeScriptArgs, shell: &Shell) -> anyhow::Result<()> {
let ecosystem_config = EcosystemConfig::from_file(shell)?;
let chain_config = ecosystem_config
.load_current_chain()
.context(MSG_CHAIN_NOT_INITIALIZED)?;
let contracts = chain_config.get_contracts_config()?;
let secrets = chain_config.get_secrets_config()?;
let l1_rpc_url = secrets
.l1
.context(MSG_L1_SECRETS_MUST_BE_PRESENTED)?
.l1_rpc_url
.expose_str()
.to_string();

let spinner = Spinner::new(MSG_ACCEPTING_ADMIN_SPINNER);
accept_admin(
shell,
&ecosystem_config,
contracts.l1.chain_admin_addr,
chain_config.get_wallets_config()?.governor_private_key(),
contracts.l1.diamond_proxy_addr,
&args,
l1_rpc_url.clone(),
)
.await?;
spinner.finish();
logger::success(MSG_CHAIN_OWNERSHIP_TRANSFERRED);
Ok(())
}
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ impl ChainCreateArgs {
.ask()
});

let wallet_path: Option<PathBuf> = if self.wallet_creation == Some(WalletCreation::InFile) {
let wallet_path: Option<PathBuf> = if wallet_creation == WalletCreation::InFile {
Some(self.wallet_path.unwrap_or_else(|| {
Prompt::new(MSG_WALLET_PATH_PROMPT)
.validate_with(|val: &String| {
Expand Down
41 changes: 41 additions & 0 deletions zk_toolbox/crates/zk_inception/src/commands/chain/args/genesis.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use anyhow::Context;
use clap::Parser;
use common::{db::DatabaseConfig, Prompt};
use config::ChainConfig;
Expand Down Expand Up @@ -77,6 +78,46 @@ impl GenesisArgs {
}
}
}

pub fn fill_values_with_secrets(
mut self,
chain_config: &ChainConfig,
) -> anyhow::Result<GenesisArgsFinal> {
let secrets = chain_config.get_secrets_config()?;
let database = secrets
.database
.context("Database secrets must be present")?;

let (server_db_url, server_db_name) = if let Some(db_full_url) = database.server_url {
let db_config = DatabaseConfig::from_url(db_full_url.expose_url())
.context("Invalid server database URL")?;
(Some(db_config.url), Some(db_config.name))
} else {
(None, None)
};

let (prover_db_url, prover_db_name) = if let Some(db_full_url) = database.prover_url {
let db_config = DatabaseConfig::from_url(db_full_url.expose_url())
.context("Invalid prover database URL")?;
(Some(db_config.url), Some(db_config.name))
} else {
(None, None)
};

self.server_db_url = self.server_db_url.or(server_db_url);
self.server_db_name = self.server_db_name.or(server_db_name);
self.prover_db_url = self.prover_db_url.or(prover_db_url);
self.prover_db_name = self.prover_db_name.or(prover_db_name);

Ok(self.fill_values_with_prompt(chain_config))
}

pub fn reset_db_names(&mut self) {
self.prover_db_name = None;
self.prover_db_url = None;
self.server_db_name = None;
self.server_db_url = None;
}
}

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use clap::Parser;
use common::Prompt;
use config::ChainConfig;
use serde::{Deserialize, Serialize};
use types::L1Network;
use url::Url;

use crate::{
commands::chain::args::{
genesis::{GenesisArgs, GenesisArgsFinal},
init::InitArgsFinal,
},
defaults::LOCAL_RPC_URL,
messages::{
MSG_GENESIS_ARGS_HELP, MSG_L1_RPC_URL_HELP, MSG_L1_RPC_URL_INVALID_ERR,
MSG_L1_RPC_URL_PROMPT, MSG_NO_PORT_REALLOCATION_HELP
},
};

#[derive(Debug, Clone, Serialize, Deserialize, Parser)]
pub struct InitConfigsArgs {
#[clap(flatten, next_help_heading = MSG_GENESIS_ARGS_HELP)]
#[serde(flatten)]
pub genesis_args: GenesisArgs,
#[clap(long, help = MSG_L1_RPC_URL_HELP)]
pub l1_rpc_url: Option<String>,
#[clap(long, help = MSG_NO_PORT_REALLOCATION_HELP, default_value = "false", default_missing_value = "true", num_args = 0..=1)]
pub no_port_reallocation: bool,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct InitConfigsArgsFinal {
pub genesis_args: GenesisArgsFinal,
pub l1_rpc_url: String,
pub no_port_reallocation: bool,
}

impl InitConfigsArgs {
pub fn fill_values_with_prompt(self, config: &ChainConfig) -> InitConfigsArgsFinal {
let l1_rpc_url = self.l1_rpc_url.unwrap_or_else(|| {
let mut prompt = Prompt::new(MSG_L1_RPC_URL_PROMPT);
if config.l1_network == L1Network::Localhost {
prompt = prompt.default(LOCAL_RPC_URL);
}
prompt
.validate_with(|val: &String| -> Result<(), String> {
Url::parse(val)
.map(|_| ())
.map_err(|_| MSG_L1_RPC_URL_INVALID_ERR.to_string())
})
.ask()
});

InitConfigsArgsFinal {
genesis_args: self.genesis_args.fill_values_with_prompt(config),
l1_rpc_url,
no_port_reallocation: self.no_port_reallocation,
}
}
}

impl InitConfigsArgsFinal {
pub fn from_chain_init_args(init_args: &InitArgsFinal) -> InitConfigsArgsFinal {
InitConfigsArgsFinal {
genesis_args: init_args.genesis_args.clone(),
l1_rpc_url: init_args.l1_rpc_url.clone(),
no_port_reallocation: init_args.no_port_reallocation,
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@ use serde::{Deserialize, Serialize};
use types::L1Network;
use url::Url;

use super::genesis::GenesisArgsFinal;
use crate::{
commands::chain::args::genesis::GenesisArgs,
commands::chain::args::genesis::{GenesisArgs, GenesisArgsFinal},
defaults::LOCAL_RPC_URL,
messages::{
MSG_DEPLOY_PAYMASTER_PROMPT, MSG_GENESIS_ARGS_HELP, MSG_L1_RPC_URL_HELP,
MSG_L1_RPC_URL_INVALID_ERR, MSG_L1_RPC_URL_PROMPT, MSG_NO_PORT_REALLOCATION_HELP,
},
};

pub mod configs;

#[derive(Debug, Clone, Serialize, Deserialize, Parser)]
pub struct InitArgs {
/// All ethereum environment related arguments
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ use config::{
use ethers::utils::hex::ToHex;
use xshell::Shell;

use super::common::register_chain;
use crate::{
commands::chain::args::build_transactions::BuildTransactionsArgs,
commands::chain::{
args::build_transactions::BuildTransactionsArgs, register_chain::register_chain,
},
messages::{
MSG_BUILDING_CHAIN_REGISTRATION_TXNS_SPINNER, MSG_CHAIN_NOT_FOUND_ERR,
MSG_CHAIN_TRANSACTIONS_BUILT, MSG_CHAIN_TXN_MISSING_CONTRACT_CONFIG,
Expand Down
58 changes: 2 additions & 56 deletions zk_toolbox/crates/zk_inception/src/commands/chain/common.rs
Original file line number Diff line number Diff line change
@@ -1,66 +1,12 @@
use common::{
forge::{Forge, ForgeScriptArgs},
spinner::Spinner,
};
use config::{
forge_interface::{
register_chain::{input::RegisterChainL1Config, output::RegisterChainOutput},
script_params::REGISTER_CHAIN_SCRIPT_PARAMS,
},
traits::{ReadConfig, SaveConfig},
ChainConfig, ContractsConfig, EcosystemConfig,
};
use common::spinner::Spinner;
use config::{ChainConfig, EcosystemConfig};
use types::{BaseToken, L1Network, WalletCreation};
use xshell::Shell;

use crate::{
consts::AMOUNT_FOR_DISTRIBUTION_TO_WALLETS,
messages::{MSG_DISTRIBUTING_ETH_SPINNER, MSG_MINT_BASE_TOKEN_SPINNER},
utils::forge::{check_the_balance, fill_forge_private_key},
};

#[allow(clippy::too_many_arguments)]
pub async fn register_chain(
shell: &Shell,
forge_args: ForgeScriptArgs,
config: &EcosystemConfig,
chain_config: &ChainConfig,
contracts: &mut ContractsConfig,
l1_rpc_url: String,
sender: Option<String>,
broadcast: bool,
) -> anyhow::Result<()> {
let deploy_config_path = REGISTER_CHAIN_SCRIPT_PARAMS.input(&config.link_to_code);

let deploy_config = RegisterChainL1Config::new(chain_config, contracts)?;
deploy_config.save(shell, deploy_config_path)?;

let mut forge = Forge::new(&config.path_to_foundry())
.script(&REGISTER_CHAIN_SCRIPT_PARAMS.script(), forge_args.clone())
.with_ffi()
.with_rpc_url(l1_rpc_url);

if broadcast {
forge = forge.with_broadcast();
}

if let Some(address) = sender {
forge = forge.with_sender(address);
} else {
forge = fill_forge_private_key(forge, config.get_wallets()?.governor_private_key())?;
check_the_balance(&forge).await?;
}

forge.run(shell)?;

let register_chain_output = RegisterChainOutput::read(
shell,
REGISTER_CHAIN_SCRIPT_PARAMS.output(&chain_config.link_to_code),
)?;
contracts.set_chain_contracts(&register_chain_output);
Ok(())
}

// Distribute eth to the chain wallets for localhost environment
pub async fn distribute_eth(
ecosystem_config: &EcosystemConfig,
Expand Down
Loading

0 comments on commit 057705e

Please sign in to comment.