Skip to content

Commit

Permalink
feat(genesis): Using genesis config only during the genesis (#1423)
Browse files Browse the repository at this point in the history
## What ❔

During the genesis, we have some fixed params, and they are changing
only during protocol upgrade. In this PR, I've not created an additional
file that represents genesis state, but only loaded it from
environmental variables.



## Why ❔

For system config refactoring we have to split our config system to a
few different files and it's the first step to it

## 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).
- [ ] 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`.
- [x] Spellcheck has been run via `zk spellcheck`.
- [x] Linkcheck has been run via `zk linkcheck`.

---------

Signed-off-by: Danil <deniallugo@gmail.com>
  • Loading branch information
Deniallugo committed Mar 25, 2024
1 parent 16dce75 commit 4b634fd
Show file tree
Hide file tree
Showing 47 changed files with 844 additions and 650 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 22 additions & 18 deletions core/bin/zksync_server/src/main.rs
Expand Up @@ -15,10 +15,10 @@ use zksync_config::{
PrometheusConfig, ProofDataHandlerConfig, WitnessGeneratorConfig,
},
ApiConfig, ContractsConfig, DBConfig, ETHClientConfig, ETHSenderConfig, ETHWatchConfig,
GasAdjusterConfig, ObjectStoreConfig, PostgresConfig,
GasAdjusterConfig, GenesisConfig, ObjectStoreConfig, PostgresConfig,
};
use zksync_core::{
genesis_init, initialize_components, is_genesis_needed, setup_sigint_handler,
genesis, genesis_init, initialize_components, is_genesis_needed, setup_sigint_handler,
temp_config_store::{decode_yaml, Secrets, TempConfigStore},
Component, Components,
};
Expand All @@ -38,8 +38,7 @@ struct Cli {
/// Generate genesis block for the first contract deployment using temporary DB.
#[arg(long)]
genesis: bool,
/// Wait for the `setChainId` event during genesis.
/// If `--genesis` is not set, this flag is ignored.
/// Set chain id (temporary will be moved to genesis config)
#[arg(long)]
set_chain_id: bool,
/// Rebuild tree.
Expand Down Expand Up @@ -156,25 +155,30 @@ async fn main() -> anyhow::Result<()> {
let postgres_config = configs.postgres_config.clone().context("PostgresConfig")?;

if opt.genesis || is_genesis_needed(&postgres_config).await {
let network = NetworkConfig::from_env().context("NetworkConfig")?;
let eth_sender = ETHSenderConfig::from_env().context("ETHSenderConfig")?;
let contracts = ContractsConfig::from_env().context("ContractsConfig")?;
let eth_client = ETHClientConfig::from_env().context("EthClientConfig")?;
genesis_init(
&postgres_config,
&eth_sender,
&network,
&contracts,
&eth_client.web3_url,
opt.set_chain_id,
)
.await
.context("genesis_init")?;
let genesis = GenesisConfig::from_env().context("Genesis config")?;
genesis_init(genesis, &postgres_config)
.await
.context("genesis_init")?;
if opt.genesis {
return Ok(());
}
}

if opt.set_chain_id {
let eth_client = ETHClientConfig::from_env().context("EthClientConfig")?;
let contracts = ContractsConfig::from_env().context("ContractsConfig")?;
if let Some(state_transition_proxy_addr) = contracts.state_transition_proxy_addr {
genesis::save_set_chain_id_tx(
&eth_client.web3_url,
contracts.diamond_proxy_addr,
state_transition_proxy_addr,
&postgres_config,
)
.await
.context("Failed to save SetChainId upgrade transaction")?;
}
}

let components = if opt.rebuild_tree {
vec![Component::Tree]
} else {
Expand Down
63 changes: 47 additions & 16 deletions core/lib/basic_types/src/lib.rs
Expand Up @@ -89,8 +89,31 @@ impl<'de> Deserialize<'de> for L2ChainId {
where
D: Deserializer<'de>,
{
let s: String = Deserialize::deserialize(deserializer)?;
s.parse().map_err(de::Error::custom)
let value: serde_json::Value = Deserialize::deserialize(deserializer)?;
match &value {
serde_json::Value::Number(number) => Self::new(number.as_u64().ok_or(
de::Error::custom(format!("Failed to parse: {}, Expected u64", number)),
)?)
.map_err(de::Error::custom),
serde_json::Value::String(string) => string.parse().map_err(de::Error::custom),
_ => Err(de::Error::custom(format!(
"Failed to parse: {}, Expected number or string",
value
))),
}
}
}

impl L2ChainId {
fn new(number: u64) -> Result<Self, String> {
if number > L2ChainId::max().0 {
return Err(format!(
"Cannot convert given value {} into L2ChainId. It's greater than MAX: {}",
number,
L2ChainId::max().0
));
}
Ok(L2ChainId(number))
}
}

Expand All @@ -108,11 +131,7 @@ impl FromStr for L2ChainId {
.map_err(|err| format!("Failed to parse L2ChainId: Err {err}"))?
}
};

if number.as_u64() > L2ChainId::max().0 {
return Err(format!("Too big chain ID. MAX: {}", L2ChainId::max().0));
}
Ok(L2ChainId(number.as_u64()))
L2ChainId::new(number.as_u64())
}
}

Expand Down Expand Up @@ -142,19 +161,13 @@ impl TryFrom<u64> for L2ChainId {
type Error = String;

fn try_from(val: u64) -> Result<Self, Self::Error> {
if val > L2ChainId::max().0 {
return Err(format!(
"Cannot convert given value {} into L2ChainId. It's greater than MAX: {},",
val,
L2ChainId::max().0,
));
}
Ok(Self(val))
Self::new(val)
}
}

impl From<u32> for L2ChainId {
fn from(value: u32) -> Self {
// Max value is guaranteed bigger than u32
Self(value as u64)
}
}
Expand Down Expand Up @@ -236,6 +249,20 @@ mod tests {
assert_eq!(result.unwrap().as_u64(), 42);
}

#[test]
fn test_serialize_deserialize() {
#[derive(Serialize, Deserialize)]
struct Test {
chain_id: L2ChainId,
}
let test = Test {
chain_id: L2ChainId(200),
};
let result_ser = serde_json::to_string(&test).unwrap();
let result_deser: Test = serde_json::from_str(&result_ser).unwrap();
assert_eq!(test.chain_id, result_deser.chain_id)
}

#[test]
fn test_from_str_valid_hexadecimal() {
let input = "0x2A";
Expand All @@ -249,7 +276,11 @@ mod tests {
let result = L2ChainId::from_str(input);
assert_eq!(
result,
Err(format!("Too big chain ID. MAX: {}", L2ChainId::max().0))
Err(format!(
"Cannot convert given value {} into L2ChainId. It's greater than MAX: {}",
input,
L2ChainId::max().0
))
);
}

Expand Down
9 changes: 8 additions & 1 deletion core/lib/config/src/configs/chain.rs
@@ -1,7 +1,7 @@
use std::{str::FromStr, time::Duration};

use serde::Deserialize;
use zksync_basic_types::{network::Network, Address, L2ChainId};
use zksync_basic_types::{network::Network, Address, L2ChainId, H256};

#[derive(Debug, Deserialize, Clone, PartialEq)]
pub struct NetworkConfig {
Expand Down Expand Up @@ -116,6 +116,11 @@ pub struct StateKeeperConfig {

/// Number of keys that is processed by enum_index migration in State Keeper each L1 batch.
pub enum_index_migration_chunk_size: Option<usize>,

// Base system contract hash, required only for genesis file, it's temporary solution
// #PLA-811
pub bootloader_hash: Option<H256>,
pub default_aa_hash: Option<H256>,
}

impl StateKeeperConfig {
Expand Down Expand Up @@ -150,6 +155,8 @@ impl StateKeeperConfig {
virtual_blocks_per_miniblock: 1,
upload_witness_inputs_to_gcs: false,
enum_index_migration_chunk_size: None,
bootloader_hash: None,
default_aa_hash: None,
}
}

Expand Down
16 changes: 8 additions & 8 deletions core/lib/config/src/configs/contracts.rs
Expand Up @@ -2,16 +2,14 @@
use serde::Deserialize;
// Workspace uses
use zksync_basic_types::{Address, H256};
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum ProverAtGenesis {
Fri,
Old,
}

/// Data about deployed contracts.
#[derive(Debug, Deserialize, Clone, PartialEq)]
pub struct ContractsConfig {
pub genesis_root: Option<H256>,
pub genesis_rollup_leaf_index: Option<u64>,
pub genesis_batch_commitment: Option<H256>,
pub genesis_protocol_version: Option<u16>,
pub governance_addr: Address,
pub mailbox_facet_addr: Address,
pub executor_facet_addr: Address,
Expand All @@ -38,7 +36,6 @@ pub struct ContractsConfig {
pub fri_recursion_scheduler_level_vk_hash: H256,
pub fri_recursion_node_level_vk_hash: H256,
pub fri_recursion_leaf_level_vk_hash: H256,
pub prover_at_genesis: ProverAtGenesis,
pub snark_wrapper_vk_hash: H256,

// These contracts will be used after shared bridge integration.
Expand All @@ -56,6 +53,8 @@ impl ContractsConfig {
/// Same goes for hashes.
pub fn for_tests() -> Self {
Self {
genesis_root: Some(H256::repeat_byte(0x01)),
genesis_rollup_leaf_index: Some(26),
mailbox_facet_addr: Address::repeat_byte(0x01),
executor_facet_addr: Address::repeat_byte(0x02),
admin_facet_addr: Address::repeat_byte(0x03),
Expand Down Expand Up @@ -83,12 +82,13 @@ impl ContractsConfig {
fri_recursion_node_level_vk_hash: H256::repeat_byte(0x07),
fri_recursion_leaf_level_vk_hash: H256::repeat_byte(0x08),
governance_addr: Address::repeat_byte(0x13),
prover_at_genesis: ProverAtGenesis::Fri,
snark_wrapper_vk_hash: H256::repeat_byte(0x09),
bridgehub_proxy_addr: Some(Address::repeat_byte(0x14)),
bridgehub_impl_addr: Some(Address::repeat_byte(0x15)),
state_transition_proxy_addr: Some(Address::repeat_byte(0x16)),
state_transition_impl_addr: Some(Address::repeat_byte(0x17)),
genesis_batch_commitment: Some(H256::repeat_byte(0x17)),
genesis_protocol_version: Some(22),
}
}
}
20 changes: 20 additions & 0 deletions core/lib/config/src/configs/genesis.rs
@@ -0,0 +1,20 @@
use serde::{Deserialize, Serialize};
use zksync_basic_types::{Address, L1ChainId, L2ChainId, H256};

/// This config represents the genesis state of the chain.
/// Each chain has this config immutable and we update it only during the protocol upgrade
#[derive(Debug, Serialize, Deserialize, Clone, PartialOrd, PartialEq)]
pub struct GenesisConfig {
pub protocol_version: u16,
pub genesis_root_hash: H256,
pub rollup_last_leaf_index: u64,
pub genesis_commitment: H256,
pub bootloader_hash: H256,
pub default_aa_hash: H256,
pub fee_account: Address,
pub l1_chain_id: L1ChainId,
pub l2_chain_id: L2ChainId,
pub recursion_node_level_vk_hash: H256,
pub recursion_leaf_level_vk_hash: H256,
pub recursion_scheduler_level_vk_hash: H256,
}
2 changes: 2 additions & 0 deletions core/lib/config/src/configs/mod.rs
Expand Up @@ -13,6 +13,7 @@ pub use self::{
fri_prover_gateway::FriProverGatewayConfig,
fri_witness_generator::FriWitnessGeneratorConfig,
fri_witness_vector_generator::FriWitnessVectorGeneratorConfig,
genesis::GenesisConfig,
object_store::ObjectStoreConfig,
observability::{ObservabilityConfig, OpentelemetryConfig},
proof_data_handler::ProofDataHandlerConfig,
Expand All @@ -36,6 +37,7 @@ pub mod fri_prover_gateway;
pub mod fri_prover_group;
pub mod fri_witness_generator;
pub mod fri_witness_vector_generator;
pub mod genesis;
pub mod house_keeper;
pub mod object_store;
pub mod observability;
Expand Down
3 changes: 2 additions & 1 deletion core/lib/config/src/lib.rs
Expand Up @@ -2,7 +2,8 @@

pub use crate::configs::{
ApiConfig, ContractVerifierConfig, ContractsConfig, DBConfig, ETHClientConfig, ETHSenderConfig,
ETHWatchConfig, GasAdjusterConfig, ObjectStoreConfig, PostgresConfig, SnapshotsCreatorConfig,
ETHWatchConfig, GasAdjusterConfig, GenesisConfig, ObjectStoreConfig, PostgresConfig,
SnapshotsCreatorConfig,
};

pub mod configs;
Expand Down
37 changes: 26 additions & 11 deletions core/lib/config/src/testonly.rs
Expand Up @@ -2,7 +2,7 @@ use std::collections::HashSet;

use rand::{distributions::Alphanumeric, Rng};
use zksync_basic_types::{
basic_fri_types::CircuitIdRoundTuple, network::Network, Address, L2ChainId, H256,
basic_fri_types::CircuitIdRoundTuple, network::Network, Address, L1ChainId, L2ChainId, H256,
};

use crate::configs::{self, eth_sender::PubdataSendingMode};
Expand Down Expand Up @@ -290,6 +290,8 @@ impl RandomConfig for configs::chain::StateKeeperConfig {
virtual_blocks_per_miniblock: g.gen(),
upload_witness_inputs_to_gcs: g.gen(),
enum_index_migration_chunk_size: g.gen(),
bootloader_hash: g.gen(),
default_aa_hash: g.gen(),
}
}
}
Expand Down Expand Up @@ -336,15 +338,6 @@ impl RandomConfig for configs::ContractVerifierConfig {
}
}

impl RandomConfig for configs::contracts::ProverAtGenesis {
fn sample(g: &mut Gen<impl Rng>) -> Self {
match g.rng.gen_range(0..2) {
0 => Self::Fri,
_ => Self::Old,
}
}
}

impl RandomConfig for configs::ContractsConfig {
fn sample(g: &mut Gen<impl Rng>) -> Self {
Self {
Expand Down Expand Up @@ -374,13 +367,16 @@ impl RandomConfig for configs::ContractsConfig {
fri_recursion_scheduler_level_vk_hash: g.gen(),
fri_recursion_node_level_vk_hash: g.gen(),
fri_recursion_leaf_level_vk_hash: g.gen(),
prover_at_genesis: g.gen(),
snark_wrapper_vk_hash: g.gen(),
bridgehub_impl_addr: g.gen(),
bridgehub_proxy_addr: g.gen(),
state_transition_proxy_addr: g.gen(),
state_transition_impl_addr: g.gen(),
transparent_proxy_admin_addr: g.gen(),
genesis_batch_commitment: g.gen(),
genesis_rollup_leaf_index: g.gen(),
genesis_root: g.gen(),
genesis_protocol_version: g.gen(),
}
}
}
Expand Down Expand Up @@ -767,3 +763,22 @@ impl RandomConfig for configs::OpentelemetryConfig {
}
}
}

impl RandomConfig for configs::GenesisConfig {
fn sample(g: &mut Gen<impl Rng>) -> Self {
Self {
protocol_version: g.gen(),
genesis_root_hash: g.gen(),
rollup_last_leaf_index: g.gen(),
genesis_commitment: g.gen(),
bootloader_hash: g.gen(),
default_aa_hash: g.gen(),
fee_account: g.gen(),
l1_chain_id: L1ChainId(g.gen()),
l2_chain_id: L2ChainId::default(),
recursion_node_level_vk_hash: g.gen(),
recursion_leaf_level_vk_hash: g.gen(),
recursion_scheduler_level_vk_hash: g.gen(),
}
}
}

0 comments on commit 4b634fd

Please sign in to comment.