Skip to content

Commit

Permalink
feat(zk_toolbox): Deploy ConsensusRegistry (BFT-504) (#2713)
Browse files Browse the repository at this point in the history
## What ❔

Adds a `zk_inception chain deploy-consensus-registry` command.

TODO: 
- [x] Change `contracts` submodule back to `main` once
matter-labs/era-contracts#735 is merged

### Contract Owner

The agreement was that on testnet the `ConsensusRegistry` contract
should be owned by the governor account, which is
0xD64e136566a9E04eb05B30184fF577F52682D182, while on mainnet it should
be owned by the [developer multisig
account](https://app.safe.global/transactions/queue?safe=eth:0x9e543149DdfEEE18e95A4655D07096398Dd2Bf52).

The owner is set in
[DeployL2ContractsInput::consensus_registry_owner](https://github.com/matter-labs/zksync-era/blob/f4b7c12431d4bb063c735947f74e30c749119b5f/zk_toolbox/crates/config/src/forge_interface/deploy_l2_contracts/input.rs#L19)
which has access to contract and wallet configuration and these are
written to a config file just before deployment.

~~I added an optional `developer_multisig` wallet to `WalletConfig`, so
the address can be added at the same place as the `governor` address is;
if `developer_multisig` is missing then `governor` is used. I suppose it
could be made part of the `ContractsConfig` instead, but since this is a
wallet with funds that developers can access, I thought it wouldn't be
out of place in `wallets.yaml` even if one doesn't have any of the
corresponding private keys. Let me know if I should be using something
else.~~

### Testing

Since the `zk_toolbox` is replacing the `zk` commands, and `zk init`
doesn't deploy the consensus registry, we have to use the following
commands to see that the contract is built, deployed and its address is
written to the config file:

```shell
./bin/zkt
zk_inception ecosystem create
zk_inception containers
zk_inception ecosystem init --dev
```

After this we can check if we see the address in the generated config
file:

```console
❯ cat ./chains/era/configs/contracts.yaml | yq .l2.consensus_registry
0x72ada8c211f45e768c9a7781793da84daf1d0d1b
```

Finally clean up:

```shell
zk_supervisor clean all
```

## Why ❔

So that we can deploy the L2 consensus registry contract using the
`zk_toolbox`.

## Checklist

<!-- Check your PR fulfills the following items. -->
<!-- For draft PRs check the boxes as you complete them. -->

- [x] PR title corresponds to the body of PR (we generate changelog
entries from PRs).
- [x] 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`.

---------

Co-authored-by: Grzegorz Prusak <pompon.pompon@gmail.com>
  • Loading branch information
aakoshh and pompon0 authored Sep 4, 2024
1 parent 9821a20 commit e1809fb
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 42 deletions.
13 changes: 12 additions & 1 deletion zk_toolbox/crates/config/src/contracts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ use crate::{
consts::CONTRACTS_FILE,
forge_interface::{
deploy_ecosystem::output::DeployL1Output,
deploy_l2_contracts::output::{DefaultL2UpgradeOutput, InitializeBridgeOutput},
deploy_l2_contracts::output::{
ConsensusRegistryOutput, DefaultL2UpgradeOutput, InitializeBridgeOutput,
},
register_chain::output::RegisterChainOutput,
},
traits::{FileConfigWithDefaultName, ZkToolboxConfig},
Expand Down Expand Up @@ -84,6 +86,14 @@ impl ContractsConfig {
Ok(())
}

pub fn set_consensus_registry(
&mut self,
consensus_registry_output: &ConsensusRegistryOutput,
) -> anyhow::Result<()> {
self.l2.consensus_registry = Some(consensus_registry_output.consensus_registry_proxy);
Ok(())
}

pub fn set_default_l2_upgrade(
&mut self,
default_upgrade_output: &DefaultL2UpgradeOutput,
Expand Down Expand Up @@ -140,4 +150,5 @@ pub struct L1Contracts {
pub struct L2Contracts {
pub testnet_paymaster_addr: Address,
pub default_l2_upgrader: Address,
pub consensus_registry: Option<Address>,
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use crate::{traits::ZkToolboxConfig, ChainConfig};

impl ZkToolboxConfig for DeployL2ContractsInput {}

/// Fields corresponding to `contracts/l1-contracts/deploy-script-config-template/config-deploy-l2-config.toml`
/// which are read by `contracts/l1-contracts/deploy-scripts/DeployL2Contracts.sol`.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DeployL2ContractsInput {
pub era_chain_id: L2ChainId,
Expand All @@ -14,6 +16,7 @@ pub struct DeployL2ContractsInput {
pub bridgehub: Address,
pub governance: Address,
pub erc20_bridge: Address,
pub consensus_registry_owner: Address,
}

impl DeployL2ContractsInput {
Expand All @@ -27,6 +30,7 @@ impl DeployL2ContractsInput {
bridgehub: contracts.ecosystem_contracts.bridgehub_proxy_addr,
governance: wallets.governor.address,
erc20_bridge: contracts.bridges.erc20.l1_address,
consensus_registry_owner: wallets.governor.address,
})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use serde::{Deserialize, Serialize};
use crate::traits::ZkToolboxConfig;

impl ZkToolboxConfig for InitializeBridgeOutput {}

impl ZkToolboxConfig for DefaultL2UpgradeOutput {}
impl ZkToolboxConfig for ConsensusRegistryOutput {}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InitializeBridgeOutput {
Expand All @@ -17,3 +17,9 @@ pub struct InitializeBridgeOutput {
pub struct DefaultL2UpgradeOutput {
pub l2_default_upgrader: Address,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConsensusRegistryOutput {
pub consensus_registry_implementation: Address,
pub consensus_registry_proxy: Address,
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use config::{
forge_interface::{
deploy_l2_contracts::{
input::DeployL2ContractsInput,
output::{DefaultL2UpgradeOutput, InitializeBridgeOutput},
output::{ConsensusRegistryOutput, DefaultL2UpgradeOutput, InitializeBridgeOutput},
},
script_params::DEPLOY_L2_CONTRACTS_SCRIPT_PARAMS,
},
Expand All @@ -31,7 +31,8 @@ use crate::{
pub enum Deploy2ContractsOption {
All,
Upgrader,
IntiailizeBridges,
InitiailizeBridges,
ConsensusRegistry,
}

pub async fn run(
Expand Down Expand Up @@ -70,7 +71,17 @@ pub async fn run(
)
.await?;
}
Deploy2ContractsOption::IntiailizeBridges => {
Deploy2ContractsOption::ConsensusRegistry => {
deploy_consensus_registry(
shell,
&chain_config,
&ecosystem_config,
&mut contracts,
args,
)
.await?;
}
Deploy2ContractsOption::InitiailizeBridges => {
initialize_bridges(
shell,
&chain_config,
Expand All @@ -88,29 +99,43 @@ pub async fn run(
Ok(())
}

/// Build the L2 contracts, deploy one or all of them with `forge`, then update the config
/// by reading one or all outputs written by the deploy scripts.
async fn build_and_deploy(
shell: &Shell,
chain_config: &ChainConfig,
ecosystem_config: &EcosystemConfig,
forge_args: ForgeScriptArgs,
signature: Option<&str>,
mut update_config: impl FnMut(&Shell, &Path) -> anyhow::Result<()>,
) -> anyhow::Result<()> {
build_l2_contracts(shell, &ecosystem_config.link_to_code)?;
call_forge(shell, chain_config, ecosystem_config, forge_args, signature).await?;
update_config(
shell,
&DEPLOY_L2_CONTRACTS_SCRIPT_PARAMS.output(&chain_config.link_to_code),
)?;
Ok(())
}

pub async fn initialize_bridges(
shell: &Shell,
chain_config: &ChainConfig,
ecosystem_config: &EcosystemConfig,
contracts_config: &mut ContractsConfig,
forge_args: ForgeScriptArgs,
) -> anyhow::Result<()> {
build_l2_contracts(shell, &ecosystem_config.link_to_code)?;
call_forge(
build_and_deploy(
shell,
chain_config,
ecosystem_config,
forge_args,
Some("runDeploySharedBridge"),
|shell, out| {
contracts_config.set_l2_shared_bridge(&InitializeBridgeOutput::read(shell, out)?)
},
)
.await?;
let output = InitializeBridgeOutput::read(
shell,
DEPLOY_L2_CONTRACTS_SCRIPT_PARAMS.output(&chain_config.link_to_code),
)?;

contracts_config.set_l2_shared_bridge(&output)?;
Ok(())
.await
}

pub async fn deploy_upgrader(
Expand All @@ -120,48 +145,60 @@ pub async fn deploy_upgrader(
contracts_config: &mut ContractsConfig,
forge_args: ForgeScriptArgs,
) -> anyhow::Result<()> {
build_l2_contracts(shell, &ecosystem_config.link_to_code)?;
call_forge(
build_and_deploy(
shell,
chain_config,
ecosystem_config,
forge_args,
Some("runDefaultUpgrader"),
|shell, out| {
contracts_config.set_default_l2_upgrade(&DefaultL2UpgradeOutput::read(shell, out)?)
},
)
.await?;
let output = DefaultL2UpgradeOutput::read(
shell,
DEPLOY_L2_CONTRACTS_SCRIPT_PARAMS.output(&chain_config.link_to_code),
)?;

contracts_config.set_default_l2_upgrade(&output)?;
Ok(())
.await
}

pub async fn deploy_l2_contracts(
pub async fn deploy_consensus_registry(
shell: &Shell,
chain_config: &ChainConfig,
ecosystem_config: &EcosystemConfig,
contracts_config: &mut ContractsConfig,
forge_args: ForgeScriptArgs,
) -> anyhow::Result<()> {
build_l2_contracts(shell, &ecosystem_config.link_to_code)?;
call_forge(shell, chain_config, ecosystem_config, forge_args, None).await?;
let output = InitializeBridgeOutput::read(
build_and_deploy(
shell,
DEPLOY_L2_CONTRACTS_SCRIPT_PARAMS.output(&chain_config.link_to_code),
)?;

contracts_config.set_l2_shared_bridge(&output)?;
chain_config,
ecosystem_config,
forge_args,
Some("runDeployConsensusRegistry"),
|shell, out| {
contracts_config.set_consensus_registry(&ConsensusRegistryOutput::read(shell, out)?)
},
)
.await
}

let output = DefaultL2UpgradeOutput::read(
pub async fn deploy_l2_contracts(
shell: &Shell,
chain_config: &ChainConfig,
ecosystem_config: &EcosystemConfig,
contracts_config: &mut ContractsConfig,
forge_args: ForgeScriptArgs,
) -> anyhow::Result<()> {
build_and_deploy(
shell,
DEPLOY_L2_CONTRACTS_SCRIPT_PARAMS.output(&chain_config.link_to_code),
)?;

contracts_config.set_default_l2_upgrade(&output)?;

Ok(())
chain_config,
ecosystem_config,
forge_args,
None,
|shell, out| {
contracts_config.set_l2_shared_bridge(&InitializeBridgeOutput::read(shell, out)?)?;
contracts_config.set_default_l2_upgrade(&DefaultL2UpgradeOutput::read(shell, out)?)?;
contracts_config.set_consensus_registry(&ConsensusRegistryOutput::read(shell, out)?)?;
Ok(())
},
)
.await
}

async fn call_forge(
Expand Down
8 changes: 7 additions & 1 deletion zk_toolbox/crates/zk_inception/src/commands/chain/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ pub enum ChainCommands {
/// Deploy all l2 contracts
#[command(alias = "l2")]
DeployL2Contracts(ForgeScriptArgs),
/// Deploy L2 consensus registry
#[command(alias = "consensus")]
DeployConsensusRegistry(ForgeScriptArgs),
/// Deploy Default Upgrader
Upgrader(ForgeScriptArgs),
/// Deploy paymaster smart contract
Expand All @@ -48,11 +51,14 @@ pub(crate) async fn run(shell: &Shell, args: ChainCommands) -> anyhow::Result<()
ChainCommands::DeployL2Contracts(args) => {
deploy_l2_contracts::run(args, shell, Deploy2ContractsOption::All).await
}
ChainCommands::DeployConsensusRegistry(args) => {
deploy_l2_contracts::run(args, shell, Deploy2ContractsOption::ConsensusRegistry).await
}
ChainCommands::Upgrader(args) => {
deploy_l2_contracts::run(args, shell, Deploy2ContractsOption::Upgrader).await
}
ChainCommands::InitializeBridges(args) => {
deploy_l2_contracts::run(args, shell, Deploy2ContractsOption::IntiailizeBridges).await
deploy_l2_contracts::run(args, shell, Deploy2ContractsOption::InitiailizeBridges).await
}
ChainCommands::DeployPaymaster(args) => deploy_paymaster::run(args, shell).await,
ChainCommands::UpdateTokenMultiplierSetter(args) => {
Expand Down

0 comments on commit e1809fb

Please sign in to comment.