From 0275435c7f3f35d9ecf7b65b06d217987cd7a505 Mon Sep 17 00:00:00 2001 From: Ivan Schasny <31857042+ischasny@users.noreply.github.com> Date: Tue, 20 Aug 2024 15:05:14 +0100 Subject: [PATCH] feat: add `update-token-multiplier-setter` command (#2688) Add a top level command `zk_inception chain update-token-multiplier-setter`. It allows to invoke "IChainAdmin.setTokenMultiplierSetter` which will be useful for the chains with a custom base token that hasn't had that role before. --- zk_toolbox/crates/zk_inception/README.md | 10 ++ .../zk_inception/src/accept_ownership.rs | 45 ------- .../zk_inception/src/commands/chain/init.rs | 3 +- .../zk_inception/src/commands/chain/mod.rs | 6 + .../chain/set_token_multiplier_setter.rs | 116 ++++++++++++++++++ .../crates/zk_inception/src/messages.rs | 4 + 6 files changed, 138 insertions(+), 46 deletions(-) create mode 100644 zk_toolbox/crates/zk_inception/src/commands/chain/set_token_multiplier_setter.rs diff --git a/zk_toolbox/crates/zk_inception/README.md b/zk_toolbox/crates/zk_inception/README.md index 61fd9ec2e36..4cb6d213688 100644 --- a/zk_toolbox/crates/zk_inception/README.md +++ b/zk_toolbox/crates/zk_inception/README.md @@ -18,6 +18,7 @@ This document contains the help content for the `zk_inception` command-line prog - [`zk_inception chain deploy-l2-contracts`↴](#zk_inception-chain-deploy-l2-contracts) - [`zk_inception chain upgrader`↴](#zk_inception-chain-upgrader) - [`zk_inception chain deploy-paymaster`↴](#zk_inception-chain-deploy-paymaster) +- [`zk_inception chain update-token-multiplier-setter`↴](#zk_inception-chain-update-token-multiplier-setter) - [`zk_inception prover`↴](#zk_inception-prover) - [`zk_inception prover init`↴](#zk_inception-prover-init) - [`zk_inception prover generate-sk`↴](#zk_inception-prover-generate-sk) @@ -198,6 +199,7 @@ Chain related commands - `deploy-l2-contracts` — Deploy all l2 contracts - `upgrader` — Deploy Default Upgrader - `deploy-paymaster` — Deploy paymaster smart contract +- `update-token-multiplier-setter` — Update Token Multiplier Setter address on l1 ## `zk_inception chain create` @@ -389,6 +391,14 @@ Deploy paymaster smart contract e.g.: `zk_inception init -a --private-key=` +## `zk_inception chain update-token-multiplier-setter` + +Update Token Multiplier Setter address on l1. Token Multiplier Setter is used by chains with custom base token to +propagate the changes to numerator / denominator to the l1. Address of the Token Multiplier Setter is taken from the +wallets configuration. + +**Usage:** `zk_inception chain update-token-multiplier-setter` + ## `zk_inception prover` Prover related commands diff --git a/zk_toolbox/crates/zk_inception/src/accept_ownership.rs b/zk_toolbox/crates/zk_inception/src/accept_ownership.rs index ad37f7cff4d..d2bab928374 100644 --- a/zk_toolbox/crates/zk_inception/src/accept_ownership.rs +++ b/zk_toolbox/crates/zk_inception/src/accept_ownership.rs @@ -58,40 +58,6 @@ pub async fn accept_admin( accept_ownership(shell, governor, forge).await } -pub async fn set_token_multiplier_setter( - shell: &Shell, - ecosystem_config: &EcosystemConfig, - governor: Option, - chain_admin_address: Address, - target_address: Address, - forge_args: &ForgeScriptArgs, - l1_rpc_url: String, -) -> anyhow::Result<()> { - // Resume for accept admin doesn't work properly. Foundry assumes that if signature of the function is the same, - // than it's the same call, but because we are calling this function multiple times during the init process, - // code assumes that doing only once is enough, but actually we need to accept admin multiple times - let mut forge_args = forge_args.clone(); - forge_args.resume = false; - - let calldata = ACCEPT_ADMIN - .encode( - "chainSetTokenMultiplierSetter", - (chain_admin_address, target_address), - ) - .unwrap(); - let foundry_contracts_path = ecosystem_config.path_to_foundry(); - let forge = Forge::new(&foundry_contracts_path) - .script( - &ACCEPT_GOVERNANCE_SCRIPT_PARAMS.script(), - forge_args.clone(), - ) - .with_ffi() - .with_rpc_url(l1_rpc_url) - .with_broadcast() - .with_calldata(&calldata); - update_token_multiplier_setter(shell, governor, forge).await -} - pub async fn accept_owner( shell: &Shell, ecosystem_config: &EcosystemConfig, @@ -133,14 +99,3 @@ async fn accept_ownership( spinner.finish(); Ok(()) } - -async fn update_token_multiplier_setter( - shell: &Shell, - governor: Option, - mut forge: ForgeScript, -) -> anyhow::Result<()> { - forge = fill_forge_private_key(forge, governor)?; - check_the_balance(&forge).await?; - forge.run(shell)?; - Ok(()) -} 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 69a2f2d940f..05599ef94e4 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/chain/init.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/chain/init.rs @@ -19,11 +19,12 @@ use types::{BaseToken, L1Network, WalletCreation}; use xshell::Shell; use crate::{ - accept_ownership::{accept_admin, set_token_multiplier_setter}, + accept_ownership::accept_admin, commands::chain::{ args::init::{InitArgs, InitArgsFinal}, deploy_l2_contracts, deploy_paymaster, genesis::genesis, + set_token_multiplier_setter::set_token_multiplier_setter, }, consts::AMOUNT_FOR_DISTRIBUTION_TO_WALLETS, messages::{ diff --git a/zk_toolbox/crates/zk_inception/src/commands/chain/mod.rs b/zk_toolbox/crates/zk_inception/src/commands/chain/mod.rs index 6fcb20478c7..dbddc923336 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/chain/mod.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/chain/mod.rs @@ -15,6 +15,7 @@ pub mod deploy_l2_contracts; pub mod deploy_paymaster; pub mod genesis; pub(crate) mod init; +mod set_token_multiplier_setter; #[derive(Subcommand, Debug)] pub enum ChainCommands { @@ -35,6 +36,8 @@ pub enum ChainCommands { /// Deploy paymaster smart contract #[command(alias = "paymaster")] DeployPaymaster(ForgeScriptArgs), + /// Update Token Multiplier Setter address on L1 + UpdateTokenMultiplierSetter(ForgeScriptArgs), } pub(crate) async fn run(shell: &Shell, args: ChainCommands) -> anyhow::Result<()> { @@ -52,5 +55,8 @@ pub(crate) async fn run(shell: &Shell, args: ChainCommands) -> anyhow::Result<() deploy_l2_contracts::run(args, shell, Deploy2ContractsOption::IntiailizeBridges).await } ChainCommands::DeployPaymaster(args) => deploy_paymaster::run(args, shell).await, + ChainCommands::UpdateTokenMultiplierSetter(args) => { + set_token_multiplier_setter::run(args, shell).await + } } } diff --git a/zk_toolbox/crates/zk_inception/src/commands/chain/set_token_multiplier_setter.rs b/zk_toolbox/crates/zk_inception/src/commands/chain/set_token_multiplier_setter.rs new file mode 100644 index 00000000000..0ab0d451f1f --- /dev/null +++ b/zk_toolbox/crates/zk_inception/src/commands/chain/set_token_multiplier_setter.rs @@ -0,0 +1,116 @@ +use anyhow::Context; +use common::{ + config::global_config, + forge::{Forge, ForgeScript, ForgeScriptArgs}, + logger, + spinner::Spinner, +}; +use config::{forge_interface::script_params::ACCEPT_GOVERNANCE_SCRIPT_PARAMS, EcosystemConfig}; +use ethers::{abi::parse_abi, contract::BaseContract, utils::hex}; +use lazy_static::lazy_static; +use xshell::Shell; +use zksync_basic_types::{Address, H256}; + +use crate::{ + messages::{ + MSG_CHAIN_NOT_INITIALIZED, MSG_L1_SECRETS_MUST_BE_PRESENTED, + MSG_TOKEN_MULTIPLIER_SETTER_UPDATED_TO, MSG_UPDATING_TOKEN_MULTIPLIER_SETTER_SPINNER, + MSG_WALLETS_CONFIG_MUST_BE_PRESENT, + }, + utils::forge::{check_the_balance, fill_forge_private_key}, +}; + +lazy_static! { + static ref SET_TOKEN_MULTIPLIER_SETTER: BaseContract = BaseContract::from( + parse_abi(&[ + "function chainSetTokenMultiplierSetter(address chainAdmin, address target) public" + ]) + .unwrap(), + ); +} + +pub async fn run(args: ForgeScriptArgs, shell: &Shell) -> anyhow::Result<()> { + let chain_name = global_config().chain_name.clone(); + let ecosystem_config = EcosystemConfig::from_file(shell)?; + let chain_config = ecosystem_config + .load_chain(chain_name) + .context(MSG_CHAIN_NOT_INITIALIZED)?; + let contracts_config = chain_config.get_contracts_config()?; + let l1_url = chain_config + .get_secrets_config()? + .l1 + .context(MSG_L1_SECRETS_MUST_BE_PRESENTED)? + .l1_rpc_url + .expose_str() + .to_string(); + let token_multiplier_setter_address = ecosystem_config + .get_wallets() + .context(MSG_WALLETS_CONFIG_MUST_BE_PRESENT)? + .token_multiplier_setter + .address; + + let spinner = Spinner::new(MSG_UPDATING_TOKEN_MULTIPLIER_SETTER_SPINNER); + set_token_multiplier_setter( + shell, + &ecosystem_config, + chain_config.get_wallets_config()?.governor_private_key(), + contracts_config.l1.chain_admin_addr, + token_multiplier_setter_address, + &args.clone(), + l1_url, + ) + .await?; + spinner.finish(); + + logger::note( + MSG_TOKEN_MULTIPLIER_SETTER_UPDATED_TO, + hex::encode(token_multiplier_setter_address), + ); + + Ok(()) +} + +pub async fn set_token_multiplier_setter( + shell: &Shell, + ecosystem_config: &EcosystemConfig, + governor: Option, + chain_admin_address: Address, + target_address: Address, + forge_args: &ForgeScriptArgs, + l1_rpc_url: String, +) -> anyhow::Result<()> { + // Resume for accept admin doesn't work properly. Foundry assumes that if signature of the function is the same, + // then it's the same call, but because we are calling this function multiple times during the init process, + // code assumes that doing only once is enough, but actually we need to accept admin multiple times + let mut forge_args = forge_args.clone(); + forge_args.resume = false; + + let calldata = SET_TOKEN_MULTIPLIER_SETTER + .encode( + "chainSetTokenMultiplierSetter", + (chain_admin_address, target_address), + ) + .unwrap(); + let foundry_contracts_path = ecosystem_config.path_to_foundry(); + let forge = Forge::new(&foundry_contracts_path) + .script( + &ACCEPT_GOVERNANCE_SCRIPT_PARAMS.script(), + forge_args.clone(), + ) + .with_ffi() + .with_rpc_url(l1_rpc_url) + .with_broadcast() + .with_calldata(&calldata); + update_token_multiplier_setter(shell, governor, forge).await +} + +async fn update_token_multiplier_setter( + shell: &Shell, + governor: Option, + mut forge: ForgeScript, +) -> anyhow::Result<()> { + forge = fill_forge_private_key(forge, governor)?; + check_the_balance(&forge).await?; + forge.run(shell)?; + Ok(()) +} diff --git a/zk_toolbox/crates/zk_inception/src/messages.rs b/zk_toolbox/crates/zk_inception/src/messages.rs index 5a86260b16b..441a1e5c853 100644 --- a/zk_toolbox/crates/zk_inception/src/messages.rs +++ b/zk_toolbox/crates/zk_inception/src/messages.rs @@ -77,6 +77,8 @@ pub(super) const MSG_REGISTERING_CHAIN_SPINNER: &str = "Registering chain..."; pub(super) const MSG_ACCEPTING_ADMIN_SPINNER: &str = "Accepting admin..."; pub(super) const MSG_UPDATING_TOKEN_MULTIPLIER_SETTER_SPINNER: &str = "Updating token multiplier setter..."; +pub(super) const MSG_TOKEN_MULTIPLIER_SETTER_UPDATED_TO: &str = + "Token multiplier setter updated to"; pub(super) const MSG_RECREATE_ROCKS_DB_ERRROR: &str = "Failed to create rocks db path"; pub(super) const MSG_ERA_OBSERVABILITY_ALREADY_SETUP: &str = "Era observability already setup"; pub(super) const MSG_DOWNLOADING_ERA_OBSERVABILITY_SPINNER: &str = @@ -161,6 +163,8 @@ pub(super) const MSG_INITIALIZING_SERVER_DATABASE: &str = "Initializing server d pub(super) const MSG_FAILED_TO_DROP_SERVER_DATABASE_ERR: &str = "Failed to drop server database"; pub(super) const MSG_INITIALIZING_PROVER_DATABASE: &str = "Initializing prover database"; pub(super) const MSG_FAILED_TO_DROP_PROVER_DATABASE_ERR: &str = "Failed to drop prover database"; +/// Chain update related messages +pub(super) const MSG_WALLETS_CONFIG_MUST_BE_PRESENT: &str = "Wallets configuration must be present"; pub(super) fn msg_server_db_url_prompt(chain_name: &str) -> String { format!("Please provide server database url for chain {chain_name}")