diff --git a/Cargo.lock b/Cargo.lock index f7c41b39491..254de85a383 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8795,6 +8795,7 @@ dependencies = [ "serde", "serde_json", "thiserror", + "zksync_config", "zksync_types", ] diff --git a/core/bin/zksync_server/src/main.rs b/core/bin/zksync_server/src/main.rs index b7644a7647c..951bc61c475 100644 --- a/core/bin/zksync_server/src/main.rs +++ b/core/bin/zksync_server/src/main.rs @@ -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, }; @@ -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. @@ -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, - ð_sender, - &network, - &contracts, - ð_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( + ð_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 { diff --git a/core/lib/basic_types/src/lib.rs b/core/lib/basic_types/src/lib.rs index 4c0b1c7f9e9..156baddf02e 100644 --- a/core/lib/basic_types/src/lib.rs +++ b/core/lib/basic_types/src/lib.rs @@ -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 { + 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)) } } @@ -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()) } } @@ -142,19 +161,13 @@ impl TryFrom for L2ChainId { type Error = String; fn try_from(val: u64) -> Result { - 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 for L2ChainId { fn from(value: u32) -> Self { + // Max value is guaranteed bigger than u32 Self(value as u64) } } @@ -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"; @@ -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 + )) ); } diff --git a/core/lib/config/src/configs/chain.rs b/core/lib/config/src/configs/chain.rs index d35c6ed52b5..1b514ce178d 100644 --- a/core/lib/config/src/configs/chain.rs +++ b/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 { @@ -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, + + // Base system contract hash, required only for genesis file, it's temporary solution + // #PLA-811 + pub bootloader_hash: Option, + pub default_aa_hash: Option, } impl StateKeeperConfig { @@ -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, } } diff --git a/core/lib/config/src/configs/contracts.rs b/core/lib/config/src/configs/contracts.rs index 70d4e685586..7835d94b263 100644 --- a/core/lib/config/src/configs/contracts.rs +++ b/core/lib/config/src/configs/contracts.rs @@ -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, + pub genesis_rollup_leaf_index: Option, + pub genesis_batch_commitment: Option, + pub genesis_protocol_version: Option, pub governance_addr: Address, pub mailbox_facet_addr: Address, pub executor_facet_addr: Address, @@ -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. @@ -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), @@ -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), } } } diff --git a/core/lib/config/src/configs/genesis.rs b/core/lib/config/src/configs/genesis.rs new file mode 100644 index 00000000000..4ca9595498c --- /dev/null +++ b/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, +} diff --git a/core/lib/config/src/configs/mod.rs b/core/lib/config/src/configs/mod.rs index 866aa25fa89..93116151d7a 100644 --- a/core/lib/config/src/configs/mod.rs +++ b/core/lib/config/src/configs/mod.rs @@ -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, @@ -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; diff --git a/core/lib/config/src/lib.rs b/core/lib/config/src/lib.rs index cde1582a1a2..63d1e6f9cc6 100644 --- a/core/lib/config/src/lib.rs +++ b/core/lib/config/src/lib.rs @@ -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; diff --git a/core/lib/config/src/testonly.rs b/core/lib/config/src/testonly.rs index 4b3ff93ed59..bf2e9266534 100644 --- a/core/lib/config/src/testonly.rs +++ b/core/lib/config/src/testonly.rs @@ -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}; @@ -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(), } } } @@ -336,15 +338,6 @@ impl RandomConfig for configs::ContractVerifierConfig { } } -impl RandomConfig for configs::contracts::ProverAtGenesis { - fn sample(g: &mut Gen) -> Self { - match g.rng.gen_range(0..2) { - 0 => Self::Fri, - _ => Self::Old, - } - } -} - impl RandomConfig for configs::ContractsConfig { fn sample(g: &mut Gen) -> Self { Self { @@ -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(), } } } @@ -767,3 +763,22 @@ impl RandomConfig for configs::OpentelemetryConfig { } } } + +impl RandomConfig for configs::GenesisConfig { + fn sample(g: &mut Gen) -> 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(), + } + } +} diff --git a/core/lib/env_config/src/chain.rs b/core/lib/env_config/src/chain.rs index b5028e99107..ab93c552e65 100644 --- a/core/lib/env_config/src/chain.rs +++ b/core/lib/env_config/src/chain.rs @@ -40,7 +40,7 @@ mod tests { use zksync_config::configs::chain::FeeModelVersion; use super::*; - use crate::test_utils::{addr, EnvMutex}; + use crate::test_utils::{addr, hash, EnvMutex}; static MUTEX: EnvMutex = EnvMutex::new(); @@ -94,6 +94,12 @@ mod tests { virtual_blocks_per_miniblock: 1, upload_witness_inputs_to_gcs: false, enum_index_migration_chunk_size: Some(2_000), + bootloader_hash: Some(hash( + "0x010007ede999d096c84553fb514d3d6ca76fbf39789dda76bfeda9f3ae06236e", + )), + default_aa_hash: Some(hash( + "0x0100055b041eb28aff6e3a6e0f37c31fd053fc9ef142683b05e5f0aee6934066", + )), } } @@ -127,6 +133,8 @@ mod tests { CHAIN_STATE_KEEPER_ENUM_INDEX_MIGRATION_CHUNK_SIZE="2000" CHAIN_STATE_KEEPER_VIRTUAL_BLOCKS_PER_MINIBLOCK="1" CHAIN_STATE_KEEPER_VIRTUAL_BLOCKS_INTERVAL="1" + CHAIN_STATE_KEEPER_BOOTLOADER_HASH=0x010007ede999d096c84553fb514d3d6ca76fbf39789dda76bfeda9f3ae06236e + CHAIN_STATE_KEEPER_DEFAULT_AA_HASH=0x0100055b041eb28aff6e3a6e0f37c31fd053fc9ef142683b05e5f0aee6934066 "#; lock.set_env(config); diff --git a/core/lib/env_config/src/contracts.rs b/core/lib/env_config/src/contracts.rs index bf2dc31d7bb..6c50b830876 100644 --- a/core/lib/env_config/src/contracts.rs +++ b/core/lib/env_config/src/contracts.rs @@ -10,8 +10,6 @@ impl FromEnv for ContractsConfig { #[cfg(test)] mod tests { - use zksync_config::configs::contracts::ProverAtGenesis; - use super::*; use crate::test_utils::{addr, hash, EnvMutex}; @@ -19,6 +17,13 @@ mod tests { fn expected_config() -> ContractsConfig { ContractsConfig { + genesis_root: Some(hash( + "0x436cf80dd02a7e1a1df65be6ec9ea231ccec97c44f4c8c9cd2aa26c2feb074cd", + )), + genesis_rollup_leaf_index: Some(26), + genesis_batch_commitment: Some(hash( + "0x938016208176c5a49d47c8aa582b5d18afc4f159dfa099087770e0796948fd1a", + )), bridgehub_proxy_addr: Some(addr("35ea7f92f4c5f433efe15284e99c040110cf6297")), bridgehub_impl_addr: Some(addr("87d456da9ed212eb49d80d96afb44afddf36adf8")), state_transition_proxy_addr: Some(addr("d90f1c081c6117241624e97cb6147257c3cb2097")), @@ -66,10 +71,10 @@ mod tests { fri_recursion_leaf_level_vk_hash: hash( "0x72167c43a46cf38875b267d67716edc4563861364a3c03ab7aee73498421e828", ), - prover_at_genesis: ProverAtGenesis::Fri, snark_wrapper_vk_hash: hash( "0x4be443afd605a782b6e56d199df2460a025c81b3dea144e135bece83612563f2", ), + genesis_protocol_version: Some(22), } } @@ -110,6 +115,9 @@ CONTRACTS_BRIDGEHUB_IMPL_ADDR="0x87d456da9ed212eb49d80d96afb44afddf36adf8" CONTRACTS_STATE_TRANSITION_PROXY_ADDR="0xd90f1c081c6117241624e97cb6147257c3cb2097" CONTRACTS_STATE_TRANSITION_IMPL_ADDR="0xc957c0e82d3bafb5ad46ffbcc66900648784eb05" CONTRACTS_TRANSPARENT_PROXY_ADMIN_ADDR="0xdd6fa5c14e7550b4caf2aa2818d24c69cbc347e5" +CONTRACTS_GENESIS_ROOT=0x436cf80dd02a7e1a1df65be6ec9ea231ccec97c44f4c8c9cd2aa26c2feb074cd +CONTRACTS_GENESIS_BATCH_COMMITMENT=0x938016208176c5a49d47c8aa582b5d18afc4f159dfa099087770e0796948fd1a +CONTRACTS_GENESIS_ROLLUP_LEAF_INDEX=26 "#; lock.set_env(config); diff --git a/core/lib/env_config/src/genesis.rs b/core/lib/env_config/src/genesis.rs new file mode 100644 index 00000000000..32290dcb14f --- /dev/null +++ b/core/lib/env_config/src/genesis.rs @@ -0,0 +1,44 @@ +use anyhow::anyhow; +use zksync_config::{ + configs::chain::{NetworkConfig, StateKeeperConfig}, + ContractsConfig, GenesisConfig, +}; + +use crate::FromEnv; + +impl FromEnv for GenesisConfig { + fn from_env() -> anyhow::Result { + // Getting genesis from environmental variables is a temporary measure, that will be + // re-implemented and for the sake of simplicity we combine values from different sources + // #PLA-811 + let network_config = &NetworkConfig::from_env()?; + let contracts_config = &ContractsConfig::from_env()?; + let state_keeper = StateKeeperConfig::from_env()?; + Ok(GenesisConfig { + protocol_version: contracts_config + .genesis_protocol_version + .ok_or(anyhow!("Protocol version is required for genesis"))?, + genesis_root_hash: contracts_config + .genesis_root + .ok_or(anyhow!("genesis_root_hash required for genesis"))?, + rollup_last_leaf_index: contracts_config + .genesis_rollup_leaf_index + .ok_or(anyhow!("rollup_last_leaf_index required for genesis"))?, + genesis_commitment: contracts_config + .genesis_batch_commitment + .ok_or(anyhow!("genesis_commitment required for genesis"))?, + bootloader_hash: state_keeper + .bootloader_hash + .ok_or(anyhow!("Bootloader hash required for genesis"))?, + default_aa_hash: state_keeper + .default_aa_hash + .ok_or(anyhow!("Default aa hash required for genesis"))?, + fee_account: state_keeper.fee_account_addr, + l1_chain_id: network_config.network.chain_id(), + l2_chain_id: network_config.zksync_network_id, + recursion_node_level_vk_hash: contracts_config.fri_recursion_node_level_vk_hash, + recursion_leaf_level_vk_hash: contracts_config.fri_recursion_leaf_level_vk_hash, + recursion_scheduler_level_vk_hash: contracts_config.snark_wrapper_vk_hash, + }) + } +} diff --git a/core/lib/env_config/src/lib.rs b/core/lib/env_config/src/lib.rs index 973e2ff9ae5..edc768b0be0 100644 --- a/core/lib/env_config/src/lib.rs +++ b/core/lib/env_config/src/lib.rs @@ -24,6 +24,7 @@ mod snapshots_creator; mod utils; mod witness_generator; +mod genesis; #[cfg(test)] mod test_utils; diff --git a/core/lib/protobuf_config/src/chain.rs b/core/lib/protobuf_config/src/chain.rs index 8773d6268dd..0fb01b90927 100644 --- a/core/lib/protobuf_config/src/chain.rs +++ b/core/lib/protobuf_config/src/chain.rs @@ -3,7 +3,7 @@ use zksync_basic_types::network::Network; use zksync_config::configs; use zksync_protobuf::{repr::ProtoRepr, required}; -use crate::{parse_h160, proto::chain as proto}; +use crate::{parse_h160, parse_h256, proto::chain as proto}; impl proto::Network { fn new(n: &Network) -> Self { @@ -140,6 +140,18 @@ impl ProtoRepr for proto::StateKeeper { .map(|x| x.try_into()) .transpose() .context("enum_index_migration_chunk_size")?, + bootloader_hash: self + .bootloader_hash + .as_ref() + .map(|a| parse_h256(a)) + .transpose() + .context("bootloader_hash")?, + default_aa_hash: self + .default_aa_hash + .as_ref() + .map(|a| parse_h256(a)) + .transpose() + .context("default_aa_hash")?, }) } @@ -176,6 +188,8 @@ impl ProtoRepr for proto::StateKeeper { .enum_index_migration_chunk_size .as_ref() .map(|x| (*x).try_into().unwrap()), + bootloader_hash: this.bootloader_hash.map(|a| a.as_bytes().into()), + default_aa_hash: this.default_aa_hash.map(|a| a.as_bytes().into()), } } } diff --git a/core/lib/protobuf_config/src/contracts.rs b/core/lib/protobuf_config/src/contracts.rs index 1d168a78632..05cba0a1578 100644 --- a/core/lib/protobuf_config/src/contracts.rs +++ b/core/lib/protobuf_config/src/contracts.rs @@ -4,24 +4,6 @@ use zksync_protobuf::{repr::ProtoRepr, required}; use crate::{parse_h160, parse_h256, proto::contracts as proto}; -impl proto::ProverAtGenesis { - fn new(x: &configs::contracts::ProverAtGenesis) -> Self { - use configs::contracts::ProverAtGenesis as From; - match x { - From::Fri => Self::Fri, - From::Old => Self::Old, - } - } - - fn parse(&self) -> configs::contracts::ProverAtGenesis { - use configs::contracts::ProverAtGenesis as To; - match self { - Self::Fri => To::Fri, - Self::Old => To::Old, - } - } -} - impl ProtoRepr for proto::Contracts { type Type = configs::ContractsConfig; fn read(&self) -> anyhow::Result { @@ -115,10 +97,6 @@ impl ProtoRepr for proto::Contracts { fri_recursion_leaf_level_vk_hash: required(&self.fri_recursion_leaf_level_vk_hash) .and_then(|x| parse_h256(x)) .context("fri_recursion_leaf_level_vk_hash")?, - prover_at_genesis: required(&self.prover_at_genesis) - .and_then(|x| Ok(proto::ProverAtGenesis::try_from(*x)?)) - .context("prover_at_genesis")? - .parse(), snark_wrapper_vk_hash: required(&self.snark_wrapper_vk_hash) .and_then(|x| parse_h256(x)) .context("snark_wrapper_vk_hash")?, @@ -152,6 +130,20 @@ impl ProtoRepr for proto::Contracts { .map(|x| parse_h160(x)) .transpose() .context("transparent_proxy_admin_addr")?, + genesis_batch_commitment: self + .genesis_batch_commitment + .as_ref() + .map(|x| parse_h256(x)) + .transpose() + .context("genesis_batch_commitment")?, + genesis_rollup_leaf_index: self.genesis_rollup_leaf_index, + genesis_root: self + .genesis_root + .as_ref() + .map(|x| parse_h256(x)) + .transpose() + .context("genesis_root")?, + genesis_protocol_version: self.genesis_protocol_version.map(|a| a as u16), }) } @@ -202,7 +194,6 @@ impl ProtoRepr for proto::Contracts { fri_recursion_leaf_level_vk_hash: Some( this.fri_recursion_leaf_level_vk_hash.as_bytes().into(), ), - prover_at_genesis: Some(proto::ProverAtGenesis::new(&this.prover_at_genesis).into()), snark_wrapper_vk_hash: Some(this.snark_wrapper_vk_hash.as_bytes().into()), bridgehub_proxy_addr: this .bridgehub_proxy_addr @@ -224,6 +215,13 @@ impl ProtoRepr for proto::Contracts { .transparent_proxy_admin_addr .as_ref() .map(|x| x.as_bytes().into()), + genesis_root: this.genesis_root.as_ref().map(|x| x.as_bytes().into()), + genesis_batch_commitment: this + .genesis_batch_commitment + .as_ref() + .map(|x| x.as_bytes().into()), + genesis_rollup_leaf_index: this.genesis_rollup_leaf_index, + genesis_protocol_version: this.genesis_protocol_version.map(|a| a as u32), } } } diff --git a/core/lib/protobuf_config/src/proto/chain.proto b/core/lib/protobuf_config/src/proto/chain.proto index 3b2569d9899..093303778d2 100644 --- a/core/lib/protobuf_config/src/proto/chain.proto +++ b/core/lib/protobuf_config/src/proto/chain.proto @@ -51,6 +51,8 @@ message StateKeeper { optional uint32 virtual_blocks_per_miniblock = 24; // required optional bool upload_witness_inputs_to_gcs = 25; // required optional uint64 enum_index_migration_chunk_size = 26; // optional + optional bytes bootloader_hash = 27; // required; H256 + optional bytes default_aa_hash = 28; // required; H256 } message OperationsManager { diff --git a/core/lib/protobuf_config/src/proto/contracts.proto b/core/lib/protobuf_config/src/proto/contracts.proto index b84217181fe..99484bc3d5c 100644 --- a/core/lib/protobuf_config/src/proto/contracts.proto +++ b/core/lib/protobuf_config/src/proto/contracts.proto @@ -2,11 +2,6 @@ syntax = "proto3"; package zksync.config.contracts; -enum ProverAtGenesis { - FRI = 0; - OLD = 1; -} - message Contracts { optional bytes governance_addr = 1; // required; H160 optional bytes mailbox_facet_addr = 2; // required; H160 @@ -34,11 +29,14 @@ message Contracts { optional bytes fri_recursion_scheduler_level_vk_hash = 24; // required; H256 optional bytes fri_recursion_node_level_vk_hash = 25; // required; H256 optional bytes fri_recursion_leaf_level_vk_hash = 26; // required; H256 - optional ProverAtGenesis prover_at_genesis = 27; // required optional bytes snark_wrapper_vk_hash = 28; // required; H256 optional bytes bridgehub_proxy_addr = 29; // optional; H160 optional bytes bridgehub_impl_addr = 30; // optional; H160 optional bytes state_transition_proxy_addr = 31; // optional; H160 optional bytes state_transition_impl_addr = 32; // optional; H160 - optional bytes transparent_proxy_admin_addr = 33; // optional; H160 + optional bytes transparent_proxy_admin_addr = 33; // optional; h160 + optional bytes genesis_root = 34; // optional; h256 + optional uint64 genesis_rollup_leaf_index = 35; // optional; + optional bytes genesis_batch_commitment = 36; // optional; h256 + optional uint32 genesis_protocol_version= 37; // optional; } diff --git a/core/lib/web3_decl/Cargo.toml b/core/lib/web3_decl/Cargo.toml index 89790fa4d5b..d94d44b4325 100644 --- a/core/lib/web3_decl/Cargo.toml +++ b/core/lib/web3_decl/Cargo.toml @@ -19,6 +19,7 @@ jsonrpsee = { workspace = true, features = [ ] } pin-project-lite.workspace = true zksync_types.workspace = true +zksync_config.workspace = true [dev-dependencies] serde_json.workspace = true diff --git a/core/lib/web3_decl/src/namespaces/en.rs b/core/lib/web3_decl/src/namespaces/en.rs index e15e4c70f9c..e8451eb14a1 100644 --- a/core/lib/web3_decl/src/namespaces/en.rs +++ b/core/lib/web3_decl/src/namespaces/en.rs @@ -1,4 +1,5 @@ use jsonrpsee::{core::RpcResult, proc_macros::rpc}; +use zksync_config::GenesisConfig; use zksync_types::{api::en, tokens::TokenInfo, MiniblockNumber}; #[cfg_attr( @@ -30,4 +31,8 @@ pub trait EnNamespace { #[method(name = "syncTokens")] async fn sync_tokens(&self, block_number: Option) -> RpcResult>; + + /// Get genesis configuration + #[method(name = "genesisConfig")] + async fn genesis_config(&self) -> RpcResult; } diff --git a/core/lib/zksync_core/src/api_server/execution_sandbox/tests.rs b/core/lib/zksync_core/src/api_server/execution_sandbox/tests.rs index f062c8df3c4..c858145c7bf 100644 --- a/core/lib/zksync_core/src/api_server/execution_sandbox/tests.rs +++ b/core/lib/zksync_core/src/api_server/execution_sandbox/tests.rs @@ -5,7 +5,7 @@ use assert_matches::assert_matches; use super::*; use crate::{ api_server::{execution_sandbox::apply::apply_vm_in_sandbox, tx_sender::ApiContracts}, - genesis::{ensure_genesis_state, GenesisParams}, + genesis::{insert_genesis_batch, GenesisParams}, utils::testonly::{create_l2_transaction, create_miniblock, prepare_recovery_snapshot}, }; @@ -13,7 +13,7 @@ use crate::{ async fn creating_block_args() { let pool = ConnectionPool::::test_pool().await; let mut storage = pool.connection().await.unwrap(); - ensure_genesis_state(&mut storage, L2ChainId::default(), &GenesisParams::mock()) + insert_genesis_batch(&mut storage, &GenesisParams::mock()) .await .unwrap(); let miniblock = create_miniblock(1); @@ -160,7 +160,7 @@ async fn creating_block_args_after_snapshot_recovery() { async fn instantiating_vm() { let pool = ConnectionPool::::test_pool().await; let mut storage = pool.connection().await.unwrap(); - ensure_genesis_state(&mut storage, L2ChainId::default(), &GenesisParams::mock()) + insert_genesis_batch(&mut storage, &GenesisParams::mock()) .await .unwrap(); diff --git a/core/lib/zksync_core/src/api_server/tx_sender/tests.rs b/core/lib/zksync_core/src/api_server/tx_sender/tests.rs index d78730ed353..73dcaf98e4d 100644 --- a/core/lib/zksync_core/src/api_server/tx_sender/tests.rs +++ b/core/lib/zksync_core/src/api_server/tx_sender/tests.rs @@ -5,7 +5,7 @@ use zksync_types::{get_nonce_key, L1BatchNumber, StorageLog}; use super::*; use crate::{ api_server::execution_sandbox::{testonly::MockTransactionExecutor, VmConcurrencyBarrier}, - genesis::{ensure_genesis_state, GenesisParams}, + genesis::{insert_genesis_batch, GenesisParams}, utils::testonly::{create_miniblock, prepare_recovery_snapshot, MockBatchFeeParamsProvider}, }; @@ -41,7 +41,7 @@ async fn getting_nonce_for_account() { let test_address = Address::repeat_byte(1); let pool = ConnectionPool::::test_pool().await; let mut storage = pool.connection().await.unwrap(); - ensure_genesis_state(&mut storage, l2_chain_id, &GenesisParams::mock()) + insert_genesis_batch(&mut storage, &GenesisParams::mock()) .await .unwrap(); // Manually insert a nonce for the address. diff --git a/core/lib/zksync_core/src/api_server/web3/backend_jsonrpsee/namespaces/en.rs b/core/lib/zksync_core/src/api_server/web3/backend_jsonrpsee/namespaces/en.rs index 15075d67f3f..90e9e218e0d 100644 --- a/core/lib/zksync_core/src/api_server/web3/backend_jsonrpsee/namespaces/en.rs +++ b/core/lib/zksync_core/src/api_server/web3/backend_jsonrpsee/namespaces/en.rs @@ -1,3 +1,4 @@ +use zksync_config::GenesisConfig; use zksync_types::{api::en, tokens::TokenInfo, MiniblockNumber}; use zksync_web3_decl::{ jsonrpsee::core::{async_trait, RpcResult}, @@ -32,4 +33,10 @@ impl EnNamespaceServer for EnNamespace { .await .map_err(|err| self.current_method().map_err(err)) } + + async fn genesis_config(&self) -> RpcResult { + self.genesis_config_impl() + .await + .map_err(|err| self.current_method().map_err(err)) + } } diff --git a/core/lib/zksync_core/src/api_server/web3/namespaces/en.rs b/core/lib/zksync_core/src/api_server/web3/namespaces/en.rs index ede0fe04a08..5ccf57f3c7e 100644 --- a/core/lib/zksync_core/src/api_server/web3/namespaces/en.rs +++ b/core/lib/zksync_core/src/api_server/web3/namespaces/en.rs @@ -1,6 +1,7 @@ use anyhow::Context as _; +use zksync_config::GenesisConfig; use zksync_dal::CoreDal; -use zksync_types::{api::en, tokens::TokenInfo, MiniblockNumber}; +use zksync_types::{api::en, tokens::TokenInfo, L1BatchNumber, MiniblockNumber, H256}; use zksync_web3_decl::error::Web3Error; use crate::api_server::web3::{backend_jsonrpsee::MethodTracer, state::RpcState}; @@ -64,4 +65,64 @@ impl EnNamespace { .await .context("get_all_tokens")?) } + + #[tracing::instrument(skip(self))] + pub async fn genesis_config_impl(&self) -> Result { + // If this method will cause some load, we can cache everything in memory + let mut storage = self.state.connection_pool.connection_tagged("api").await?; + let genesis_batch = storage + .blocks_dal() + .get_storage_l1_batch(L1BatchNumber(0)) + .await + .context("genesis_config")? + .context("Genesis batch doesn't exist")?; + + let protocol_version = genesis_batch + .protocol_version + .context("Genesis is not finished")? as u16; + let verifier_config = storage + .protocol_versions_dal() + .l1_verifier_config_for_version(protocol_version.try_into().unwrap()) + .await + .context("Genesis is not finished")?; + let fee_account = storage + .blocks_dal() + .get_fee_address_for_miniblock(MiniblockNumber(0)) + .await + .context("genesis_config")? + .context("Genesis not finished")?; + let config = GenesisConfig { + protocol_version, + genesis_root_hash: H256::from_slice( + &genesis_batch.hash.context("Genesis is not finished")?, + ), + rollup_last_leaf_index: genesis_batch + .rollup_last_leaf_index + .context("Genesis is not finished")? as u64, + genesis_commitment: H256::from_slice( + &genesis_batch + .commitment + .context("Genesis is not finished")?, + ), + bootloader_hash: H256::from_slice( + &genesis_batch + .bootloader_code_hash + .context("Genesis is not finished")?, + ), + default_aa_hash: H256::from_slice( + &genesis_batch + .default_aa_code_hash + .context("Genesis is not finished")?, + ), + fee_account, + l1_chain_id: self.state.api_config.l1_chain_id, + + l2_chain_id: self.state.api_config.l2_chain_id, + recursion_node_level_vk_hash: verifier_config.params.recursion_node_level_vk_hash, + recursion_leaf_level_vk_hash: verifier_config.params.recursion_leaf_level_vk_hash, + recursion_scheduler_level_vk_hash: verifier_config.recursion_scheduler_level_vk_hash, + }; + dbg!(&config); + Ok(config) + } } diff --git a/core/lib/zksync_core/src/api_server/web3/tests/mod.rs b/core/lib/zksync_core/src/api_server/web3/tests/mod.rs index 2e2ec4355ec..263e70da954 100644 --- a/core/lib/zksync_core/src/api_server/web3/tests/mod.rs +++ b/core/lib/zksync_core/src/api_server/web3/tests/mod.rs @@ -10,10 +10,13 @@ use async_trait::async_trait; use jsonrpsee::core::{client::ClientT, params::BatchRequestBuilder, ClientError}; use multivm::zk_evm_latest::ethereum_types::U256; use tokio::sync::watch; -use zksync_config::configs::{ - api::Web3JsonRpcConfig, - chain::{NetworkConfig, StateKeeperConfig}, - ContractsConfig, +use zksync_config::{ + configs::{ + api::Web3JsonRpcConfig, + chain::{NetworkConfig, StateKeeperConfig}, + ContractsConfig, + }, + GenesisConfig, }; use zksync_dal::{transactions_dal::L2TxSubmissionResult, Connection, ConnectionPool, CoreDal}; use zksync_health_check::CheckHealth; @@ -35,7 +38,7 @@ use zksync_types::{ use zksync_utils::u256_to_h256; use zksync_web3_decl::{ jsonrpsee::{http_client::HttpClient, types::error::ErrorCode}, - namespaces::{EthNamespaceClient, ZksNamespaceClient}, + namespaces::{EnNamespaceClient, EthNamespaceClient, ZksNamespaceClient}, }; use super::{metrics::ApiTransportLabel, *}; @@ -44,7 +47,7 @@ use crate::{ execution_sandbox::testonly::MockTransactionExecutor, tx_sender::tests::create_test_tx_sender, }, - genesis::{ensure_genesis_state, GenesisParams}, + genesis::{insert_genesis_batch, mock_genesis_config, GenesisParams}, utils::testonly::{ create_l1_batch, create_l1_batch_metadata, create_l2_transaction, create_miniblock, l1_batch_metadata_to_commitment_artifacts, prepare_recovery_snapshot, @@ -237,13 +240,13 @@ impl StorageInitialization { ) -> anyhow::Result<()> { match self { Self::Genesis => { + let params = GenesisParams::load_genesis_params(GenesisConfig { + l2_chain_id: network_config.zksync_network_id, + ..mock_genesis_config() + }) + .unwrap(); if storage.blocks_dal().is_genesis_needed().await? { - ensure_genesis_state( - storage, - network_config.zksync_network_id, - &GenesisParams::mock(), - ) - .await?; + insert_genesis_batch(storage, ¶ms).await?; } } Self::Recovery { logs, factory_deps } => { @@ -1077,3 +1080,21 @@ impl HttpTest for RpcCallsTracingTest { async fn tracing_rpc_calls() { test_http_server(RpcCallsTracingTest::default()).await; } + +#[derive(Debug, Default)] +struct GenesisConfigTest; + +#[async_trait] +impl HttpTest for GenesisConfigTest { + async fn test(&self, client: &HttpClient, _pool: &ConnectionPool) -> anyhow::Result<()> { + // It's enough to check that we fill all fields and deserialization is correct. + // Mocking values is not suitable since they will always change + client.genesis_config().await.unwrap(); + Ok(()) + } +} + +#[tokio::test] +async fn tracing_genesis_config() { + test_http_server(GenesisConfigTest).await; +} diff --git a/core/lib/zksync_core/src/consensus/storage/testonly.rs b/core/lib/zksync_core/src/consensus/storage/testonly.rs index 64ea99281ea..113afdb254d 100644 --- a/core/lib/zksync_core/src/consensus/storage/testonly.rs +++ b/core/lib/zksync_core/src/consensus/storage/testonly.rs @@ -5,11 +5,10 @@ use zksync_consensus_roles::validator; use zksync_consensus_storage as storage; use zksync_consensus_storage::PersistentBlockStore as _; use zksync_dal::ConnectionPool; -use zksync_types::L2ChainId; use super::Store; use crate::{ - genesis::{ensure_genesis_state, GenesisParams}, + genesis::{insert_genesis_batch, GenesisParams}, utils::testonly::{recover, snapshot, Snapshot}, }; @@ -65,7 +64,7 @@ impl Store { let pool = ConnectionPool::test_pool().await; { let mut storage = pool.connection().await.unwrap(); - ensure_genesis_state(&mut storage, L2ChainId::default(), &GenesisParams::mock()) + insert_genesis_batch(&mut storage, &GenesisParams::mock()) .await .unwrap(); } diff --git a/core/lib/zksync_core/src/consensus/testonly.rs b/core/lib/zksync_core/src/consensus/testonly.rs index 769f81e0883..341a106270b 100644 --- a/core/lib/zksync_core/src/consensus/testonly.rs +++ b/core/lib/zksync_core/src/consensus/testonly.rs @@ -4,7 +4,7 @@ use std::{collections::HashMap, sync::Arc}; use anyhow::Context as _; use rand::Rng; use zksync_concurrency::{ctx, error::Wrap as _, limiter, scope, sync, time}; -use zksync_config::configs; +use zksync_config::{configs, GenesisConfig}; use zksync_consensus_roles::validator; use zksync_contracts::BaseSystemContractsHashes; use zksync_dal::CoreDal; @@ -20,7 +20,7 @@ use zksync_web3_decl::{ use crate::{ api_server::web3::{state::InternalApiConfig, tests::spawn_http_server}, consensus::{fetcher::P2PConfig, Fetcher, Store}, - genesis::GenesisParams, + genesis::{mock_genesis_config, GenesisParams}, state_keeper::{ io::common::IoCursor, seal_criteria::NoopSealer, tests::MockBatchExecutor, MiniblockSealer, ZkSyncStateKeeper, @@ -103,13 +103,6 @@ impl MainNodeClient for MockMainNodeClient { Ok(self.protocol_versions.get(&protocol_version).cloned()) } - async fn fetch_genesis_l1_batch_hash(&self) -> EnrichedClientResult { - Err(EnrichedClientError::custom( - "not implemented", - "fetch_genesis_l1_batch_hash", - )) - } - async fn fetch_l2_block_number(&self) -> EnrichedClientResult { if let Some(number) = self.l2_blocks.len().checked_sub(1) { Ok(MiniblockNumber(number as u32)) @@ -143,6 +136,10 @@ impl MainNodeClient for MockMainNodeClient { ) -> EnrichedClientResult> { unimplemented!() } + + async fn fetch_genesis_config(&self) -> EnrichedClientResult { + Ok(mock_genesis_config()) + } } /// Fake StateKeeper for tests. @@ -232,7 +229,7 @@ impl StateKeeper { l1_gas_price: 2, l2_fair_gas_price: 3, fair_pubdata_price: Some(24), - operator_address: GenesisParams::mock().first_validator, + operator_address: GenesisParams::mock().config().fee_account, protocol_version: ProtocolVersionId::latest(), first_miniblock_info: (self.last_block, 1), } diff --git a/core/lib/zksync_core/src/consistency_checker/tests/mod.rs b/core/lib/zksync_core/src/consistency_checker/tests/mod.rs index b34255b9fe7..1e01a498a50 100644 --- a/core/lib/zksync_core/src/consistency_checker/tests/mod.rs +++ b/core/lib/zksync_core/src/consistency_checker/tests/mod.rs @@ -6,17 +6,18 @@ use assert_matches::assert_matches; use once_cell::sync::Lazy; use test_casing::{test_casing, Product}; use tokio::sync::mpsc; +use zksync_config::GenesisConfig; use zksync_dal::Connection; use zksync_eth_client::{clients::MockEthereum, Options}; use zksync_l1_contract_interface::i_executor::structures::StoredBatchInfo; use zksync_types::{ - aggregated_operations::AggregatedActionType, commitment::L1BatchWithMetadata, L2ChainId, Log, + aggregated_operations::AggregatedActionType, commitment::L1BatchWithMetadata, Log, ProtocolVersion, ProtocolVersionId, H256, }; use super::*; use crate::{ - genesis::{ensure_genesis_state, GenesisParams}, + genesis::{insert_genesis_batch, mock_genesis_config, GenesisParams}, utils::testonly::{ create_l1_batch, create_l1_batch_metadata, l1_batch_metadata_to_commitment_artifacts, }, @@ -363,7 +364,7 @@ async fn normal_checker_function( let pool = ConnectionPool::::test_pool().await; let mut storage = pool.connection().await.unwrap(); - ensure_genesis_state(&mut storage, L2ChainId::default(), &GenesisParams::mock()) + insert_genesis_batch(&mut storage, &GenesisParams::mock()) .await .unwrap(); @@ -433,11 +434,12 @@ async fn checker_processes_pre_boojum_batches( let pool = ConnectionPool::::test_pool().await; let mut storage = pool.connection().await.unwrap(); - let genesis_params = GenesisParams { - protocol_version: PRE_BOOJUM_PROTOCOL_VERSION, - ..GenesisParams::mock() - }; - ensure_genesis_state(&mut storage, L2ChainId::default(), &genesis_params) + let genesis_params = GenesisParams::load_genesis_params(GenesisConfig { + protocol_version: PRE_BOOJUM_PROTOCOL_VERSION as u16, + ..mock_genesis_config() + }) + .unwrap(); + insert_genesis_batch(&mut storage, &genesis_params) .await .unwrap(); storage @@ -685,7 +687,7 @@ async fn checker_detects_incorrect_tx_data(kind: IncorrectDataKind, snapshot_rec .save_protocol_version_with_tx(ProtocolVersion::default()) .await; } else { - ensure_genesis_state(&mut storage, L2ChainId::default(), &GenesisParams::mock()) + insert_genesis_batch(&mut storage, &GenesisParams::mock()) .await .unwrap(); } diff --git a/core/lib/zksync_core/src/genesis.rs b/core/lib/zksync_core/src/genesis.rs index 7514c4577aa..a78770f959e 100644 --- a/core/lib/zksync_core/src/genesis.rs +++ b/core/lib/zksync_core/src/genesis.rs @@ -2,14 +2,18 @@ //! It initializes the Merkle tree with the basic setup (such as fields of special service accounts), //! setups the required databases, and outputs the data required to initialize a smart contract. +use std::fmt::Formatter; + use anyhow::Context as _; use multivm::{ circuit_sequencer_api_latest::sort_storage_access::sort_storage_access_queries, utils::get_max_gas_per_pubdata_byte, zk_evm_latest::aux_structures::{LogQuery as MultiVmLogQuery, Timestamp as MultiVMTimestamp}, }; -use zksync_contracts::{BaseSystemContracts, SET_CHAIN_ID_EVENT}; -use zksync_dal::{Connection, Core, CoreDal}; +use zksync_config::{GenesisConfig, PostgresConfig}; +use zksync_contracts::{BaseSystemContracts, BaseSystemContractsHashes, SET_CHAIN_ID_EVENT}; +use zksync_dal::{Connection, Core, CoreDal, SqlxError}; +use zksync_db_connection::connection_pool::ConnectionPool; use zksync_eth_client::{clients::QueryClient, EthInterface}; use zksync_merkle_tree::domain::ZkSyncTree; use zksync_system_constants::PRIORITY_EXPIRATION; @@ -22,7 +26,8 @@ use zksync_types::{ fee_model::BatchFeeInput, get_code_key, get_system_context_init_logs, protocol_upgrade::{decode_set_chain_id_event, ProtocolVersion}, - protocol_version::L1VerifierConfig, + protocol_version::{L1VerifierConfig, VerifierParams}, + system_contracts::get_system_smart_contracts, tokens::{TokenInfo, TokenMetadata, ETHEREUM_ADDRESS}, web3::types::{BlockNumber, FilterBuilder}, zk_evm_types::{LogQuery, Timestamp}, @@ -33,67 +38,165 @@ use zksync_utils::{be_words_to_bytes, bytecode::hash_bytecode, h256_to_u256, u25 use crate::metadata_calculator::L1BatchWithLogs; +#[derive(Debug, Clone)] +pub struct BaseContractsHashError { + from_config: BaseSystemContractsHashes, + calculated: BaseSystemContractsHashes, +} + +impl std::fmt::Display for BaseContractsHashError { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!( + f, + "From Config {:?}, Calculated : {:?}", + &self.from_config, &self.calculated + ) + } +} + +#[derive(Debug, thiserror::Error)] +pub enum GenesisError { + #[error("Root hash mismatched: From config: {0:?}, Calculated {1:?}")] + RootHash(H256, H256), + #[error("Leaf indexes mismatched: From config: {0:?}, Calculated {1:?}")] + LeafIndexes(u64, u64), + #[error("Base system contracts mismatched: {0}")] + BaseSystemContractsHashes(Box), + #[error("Commitment mismatched: From config: {0:?}, Calculated {1:?}")] + Commitment(H256, H256), + #[error("Wrong protocol version")] + ProtocolVersion(u16), + #[error("DB Error: {0}")] + DBError(#[from] SqlxError), + #[error("Error: {0}")] + Other(#[from] anyhow::Error), +} + #[derive(Debug, Clone)] pub struct GenesisParams { - pub first_validator: Address, - pub protocol_version: ProtocolVersionId, - pub base_system_contracts: BaseSystemContracts, - pub system_contracts: Vec, - pub first_l1_verifier_config: L1VerifierConfig, + base_system_contracts: BaseSystemContracts, + system_contracts: Vec, + config: GenesisConfig, } impl GenesisParams { + pub fn system_contracts(&self) -> &[DeployedContract] { + &self.system_contracts + } + pub fn base_system_contracts(&self) -> &BaseSystemContracts { + &self.base_system_contracts + } + pub fn config(&self) -> &GenesisConfig { + &self.config + } + + pub fn from_genesis_config( + config: GenesisConfig, + base_system_contracts: BaseSystemContracts, + system_contracts: Vec, + ) -> Result { + let base_system_contracts_hashes = BaseSystemContractsHashes { + bootloader: config.bootloader_hash, + default_aa: config.default_aa_hash, + }; + if base_system_contracts_hashes != base_system_contracts.hashes() { + return Err(GenesisError::BaseSystemContractsHashes(Box::new( + BaseContractsHashError { + from_config: base_system_contracts_hashes, + calculated: base_system_contracts.hashes(), + }, + ))); + } + // Try to convert value from config to the real protocol version and return error + // if the version doesn't exist + let _: ProtocolVersionId = config + .protocol_version + .try_into() + .map_err(|_| GenesisError::ProtocolVersion(config.protocol_version))?; + Ok(GenesisParams { + base_system_contracts, + system_contracts, + config, + }) + } + + pub fn load_genesis_params(config: GenesisConfig) -> Result { + let base_system_contracts = BaseSystemContracts::load_from_disk(); + let system_contracts = get_system_smart_contracts(); + Self::from_genesis_config(config, base_system_contracts, system_contracts) + } + #[cfg(test)] pub(crate) fn mock() -> Self { - use zksync_types::system_contracts::get_system_smart_contracts; - Self { - first_validator: Address::repeat_byte(0x01), - protocol_version: ProtocolVersionId::latest(), base_system_contracts: BaseSystemContracts::load_from_disk(), system_contracts: get_system_smart_contracts(), - first_l1_verifier_config: L1VerifierConfig::default(), + config: mock_genesis_config(), } } -} -pub async fn ensure_genesis_state( - storage: &mut Connection<'_, Core>, - zksync_chain_id: L2ChainId, - genesis_params: &GenesisParams, -) -> anyhow::Result { - let mut transaction = storage.start_transaction().await?; + pub fn protocol_version(&self) -> ProtocolVersionId { + // It's impossible to instantiate Genesis params with wrong protocol version + self.config + .protocol_version + .try_into() + .expect("Protocol version must be correctly initialized for genesis") + } +} - // return if genesis block was already processed - if !transaction.blocks_dal().is_genesis_needed().await? { - tracing::debug!("genesis is not needed!"); - return transaction - .blocks_dal() - .get_l1_batch_state_root(L1BatchNumber(0)) - .await - .context("failed fetching state root hash for genesis L1 batch")? - .context("genesis L1 batch hash is empty"); +#[cfg(test)] +pub fn mock_genesis_config() -> GenesisConfig { + use zksync_types::L1ChainId; + + let base_system_contracts_hashes = BaseSystemContracts::load_from_disk().hashes(); + let first_l1_verifier_config = L1VerifierConfig::default(); + + GenesisConfig { + protocol_version: ProtocolVersionId::latest() as u16, + genesis_root_hash: Default::default(), + rollup_last_leaf_index: 26, + genesis_commitment: Default::default(), + bootloader_hash: base_system_contracts_hashes.bootloader, + default_aa_hash: base_system_contracts_hashes.default_aa, + fee_account: Address::repeat_byte(0x01), + l1_chain_id: L1ChainId(9), + l2_chain_id: L2ChainId::default(), + recursion_node_level_vk_hash: first_l1_verifier_config.params.recursion_node_level_vk_hash, + recursion_leaf_level_vk_hash: first_l1_verifier_config.params.recursion_leaf_level_vk_hash, + recursion_scheduler_level_vk_hash: first_l1_verifier_config + .recursion_scheduler_level_vk_hash, } +} - tracing::info!("running regenesis"); - let GenesisParams { - first_validator, - protocol_version, - base_system_contracts, - system_contracts, - first_l1_verifier_config, - } = genesis_params; +pub struct GenesisBatchParams { + pub root_hash: H256, + pub commitment: H256, + pub rollup_last_leaf_index: u64, +} - let base_system_contracts_hashes = base_system_contracts.hashes(); +// Insert genesis batch into the database +pub async fn insert_genesis_batch( + storage: &mut Connection<'_, Core>, + genesis_params: &GenesisParams, +) -> Result { + let mut transaction = storage.start_transaction().await?; + let verifier_config = L1VerifierConfig { + params: VerifierParams { + recursion_node_level_vk_hash: genesis_params.config.recursion_node_level_vk_hash, + recursion_leaf_level_vk_hash: genesis_params.config.recursion_leaf_level_vk_hash, + recursion_circuits_set_vks_hash: H256::zero(), + }, + recursion_scheduler_level_vk_hash: genesis_params.config.recursion_scheduler_level_vk_hash, + }; create_genesis_l1_batch( &mut transaction, - *first_validator, - zksync_chain_id, - *protocol_version, - base_system_contracts, - system_contracts, - *first_l1_verifier_config, + genesis_params.config.fee_account, + genesis_params.config.l2_chain_id, + genesis_params.protocol_version(), + genesis_params.base_system_contracts(), + genesis_params.system_contracts(), + verifier_config, ) .await?; tracing::info!("chain_schema_genesis is complete"); @@ -106,11 +209,15 @@ pub async fn ensure_genesis_state( let genesis_root_hash = metadata.root_hash; let rollup_last_leaf_index = metadata.leaf_count + 1; + let base_system_contract_hashes = BaseSystemContractsHashes { + bootloader: genesis_params.config.bootloader_hash, + default_aa: genesis_params.config.default_aa_hash, + }; let commitment_input = CommitmentInput::for_genesis_batch( genesis_root_hash, rollup_last_leaf_index, - base_system_contracts_hashes, - *protocol_version, + base_system_contract_hashes, + genesis_params.protocol_version(), ); let block_commitment = L1BatchCommitment::new(commitment_input); @@ -121,30 +228,59 @@ pub async fn ensure_genesis_state( rollup_last_leaf_index, ) .await?; - tracing::info!("operations_schema_genesis is complete"); - transaction.commit().await?; + Ok(GenesisBatchParams { + root_hash: genesis_root_hash, + commitment: block_commitment.hash().commitment, + rollup_last_leaf_index, + }) +} - // We need to `println` this value because it will be used to initialize the smart contract. - println!("CONTRACTS_GENESIS_ROOT={:?}", genesis_root_hash); - println!( - "CONTRACTS_GENESIS_BATCH_COMMITMENT={:?}", - block_commitment.hash().commitment - ); - println!( - "CONTRACTS_GENESIS_ROLLUP_LEAF_INDEX={}", - rollup_last_leaf_index - ); - println!( - "CHAIN_STATE_KEEPER_BOOTLOADER_HASH={:?}", - base_system_contracts_hashes.bootloader - ); - println!( - "CHAIN_STATE_KEEPER_DEFAULT_AA_HASH={:?}", - base_system_contracts_hashes.default_aa - ); +pub async fn ensure_genesis_state( + storage: &mut Connection<'_, Core>, + genesis_params: &GenesisParams, +) -> Result { + let mut transaction = storage.start_transaction().await?; - Ok(genesis_root_hash) + if !transaction.blocks_dal().is_genesis_needed().await? { + tracing::debug!("genesis is not needed!"); + return Ok(transaction + .blocks_dal() + .get_l1_batch_state_root(L1BatchNumber(0)) + .await? + .context("genesis L1 batch hash is empty")?); + } + + tracing::info!("running regenesis"); + let GenesisBatchParams { + root_hash, + commitment, + rollup_last_leaf_index, + } = insert_genesis_batch(&mut transaction, genesis_params).await?; + if genesis_params.config.genesis_root_hash != root_hash { + return Err(GenesisError::RootHash( + genesis_params.config.genesis_root_hash, + root_hash, + )); + } + + if genesis_params.config.genesis_commitment != commitment { + return Err(GenesisError::Commitment( + genesis_params.config.genesis_commitment, + commitment, + )); + } + + if genesis_params.config.rollup_last_leaf_index != rollup_last_leaf_index { + return Err(GenesisError::LeafIndexes( + genesis_params.config.rollup_last_leaf_index, + rollup_last_leaf_index, + )); + } + + tracing::info!("genesis is complete"); + transaction.commit().await?; + Ok(root_hash) } // Default account and bootloader are not a regular system contracts @@ -156,24 +292,23 @@ pub async fn ensure_genesis_state( async fn insert_base_system_contracts_to_factory_deps( storage: &mut Connection<'_, Core>, contracts: &BaseSystemContracts, -) -> anyhow::Result<()> { +) -> Result<(), GenesisError> { let factory_deps = [&contracts.bootloader, &contracts.default_aa] .iter() .map(|c| (c.hash, be_words_to_bytes(&c.code))) .collect(); - storage + Ok(storage .factory_deps_dal() .insert_factory_deps(MiniblockNumber(0), &factory_deps) - .await - .context("failed inserting base system contracts to Postgres") + .await?) } async fn insert_system_contracts( storage: &mut Connection<'_, Core>, contracts: &[DeployedContract], chain_id: L2ChainId, -) -> anyhow::Result<()> { +) -> Result<(), GenesisError> { let system_context_init_logs = (H256::default(), get_system_context_init_logs(chain_id)); let storage_logs: Vec<_> = contracts @@ -193,8 +328,7 @@ async fn insert_system_contracts( transaction .storage_logs_dal() .insert_storage_logs(MiniblockNumber(0), &storage_logs) - .await - .context("failed inserting genesis storage logs")?; + .await?; // we don't produce proof for the genesis block, // but we still need to populate the table @@ -250,8 +384,7 @@ async fn insert_system_contracts( transaction .storage_logs_dedup_dal() .insert_protective_reads(L1BatchNumber(0), &protective_reads) - .await - .context("failed inserting genesis protective reads")?; + .await?; let written_storage_keys: Vec<_> = deduplicated_writes .iter() @@ -260,8 +393,7 @@ async fn insert_system_contracts( transaction .storage_logs_dedup_dal() .insert_initial_writes(L1BatchNumber(0), &written_storage_keys) - .await - .context("failed inserting genesis initial writes")?; + .await?; #[allow(deprecated)] transaction @@ -276,8 +408,7 @@ async fn insert_system_contracts( transaction .factory_deps_dal() .insert_factory_deps(MiniblockNumber(0), &factory_deps) - .await - .context("failed inserting bytecodes for genesis smart contracts")?; + .await?; transaction.commit().await?; Ok(()) @@ -292,7 +423,7 @@ pub(crate) async fn create_genesis_l1_batch( base_system_contracts: &BaseSystemContracts, system_contracts: &[DeployedContract], l1_verifier_config: L1VerifierConfig, -) -> anyhow::Result<()> { +) -> Result<(), GenesisError> { let version = ProtocolVersion { id: protocol_version, timestamp: 0, @@ -339,23 +470,18 @@ pub(crate) async fn create_genesis_l1_batch( &[], Default::default(), ) - .await - .context("failed inserting genesis L1 batch")?; + .await?; transaction .blocks_dal() .insert_miniblock(&genesis_miniblock_header) - .await - .context("failed inserting genesis miniblock")?; + .await?; transaction .blocks_dal() .mark_miniblocks_as_executed_in_l1_batch(L1BatchNumber(0)) - .await - .context("failed assigning genesis miniblock to L1 batch")?; + .await?; insert_base_system_contracts_to_factory_deps(&mut transaction, base_system_contracts).await?; - insert_system_contracts(&mut transaction, system_contracts, chain_id) - .await - .context("cannot insert system contracts")?; + insert_system_contracts(&mut transaction, system_contracts, chain_id).await?; add_eth_token(&mut transaction).await?; transaction.commit().await?; @@ -374,16 +500,11 @@ async fn add_eth_token(transaction: &mut Connection<'_, Core>) -> anyhow::Result }, }; - transaction - .tokens_dal() - .add_tokens(&[eth_token]) - .await - .context("failed adding Ether token")?; + transaction.tokens_dal().add_tokens(&[eth_token]).await?; transaction .tokens_dal() .mark_token_as_well_known(ETHEREUM_ADDRESS) - .await - .context("failed marking Ether token as well-known")?; + .await?; Ok(()) } @@ -392,7 +513,7 @@ async fn save_genesis_l1_batch_metadata( commitment: L1BatchCommitment, genesis_root_hash: H256, rollup_last_leaf_index: u64, -) -> anyhow::Result<()> { +) -> Result<(), GenesisError> { let mut transaction = storage.start_transaction().await?; let tree_data = L1BatchTreeData { @@ -402,8 +523,7 @@ async fn save_genesis_l1_batch_metadata( transaction .blocks_dal() .save_l1_batch_tree_data(L1BatchNumber(0), &tree_data) - .await - .context("failed saving tree data for genesis L1 batch")?; + .await?; let mut commitment_artifacts = commitment.artifacts(); // `l2_l1_merkle_root` for genesis batch is set to 0 on L1 contract, same must be here. @@ -412,19 +532,24 @@ async fn save_genesis_l1_batch_metadata( transaction .blocks_dal() .save_l1_batch_commitment_artifacts(L1BatchNumber(0), &commitment_artifacts) - .await - .context("failed saving commitment for genesis L1 batch")?; + .await?; transaction.commit().await?; Ok(()) } -pub(crate) async fn save_set_chain_id_tx( +// Save chain id transaction into the database +// We keep returning anyhow and will refactor it later +pub async fn save_set_chain_id_tx( eth_client_url: &str, diamond_proxy_address: Address, state_transition_manager_address: Address, - storage: &mut Connection<'_, Core>, + postgres_config: &PostgresConfig, ) -> anyhow::Result<()> { + let db_url = postgres_config.master_url()?; + let pool = ConnectionPool::::singleton(db_url).build().await?; + let mut storage = pool.connection().await?; + let eth_client = QueryClient::new(eth_client_url)?; let to = eth_client.block_number("fetch_chain_id_tx").await?.as_u64(); let from = to - PRIORITY_EXPIRATION; @@ -446,7 +571,8 @@ pub(crate) async fn save_set_chain_id_tx( logs.len(), logs ); - let (version_id, upgrade_tx) = decode_set_chain_id_event(logs.remove(0))?; + let (version_id, upgrade_tx) = + decode_set_chain_id_event(logs.remove(0)).context("Chain id event is incorrect")?; storage .protocol_versions_dal() .save_genesis_upgrade_with_tx(version_id, upgrade_tx) @@ -456,8 +582,8 @@ pub(crate) async fn save_set_chain_id_tx( #[cfg(test)] mod tests { + use zksync_config::GenesisConfig; use zksync_dal::{ConnectionPool, Core, CoreDal}; - use zksync_types::system_contracts::get_system_smart_contracts; use super::*; @@ -467,16 +593,9 @@ mod tests { let mut conn = pool.connection().await.unwrap(); conn.blocks_dal().delete_genesis().await.unwrap(); - let params = GenesisParams { - protocol_version: ProtocolVersionId::latest(), - first_validator: Address::random(), - base_system_contracts: BaseSystemContracts::load_from_disk(), - system_contracts: get_system_smart_contracts(), - first_l1_verifier_config: L1VerifierConfig::default(), - }; - ensure_genesis_state(&mut conn, L2ChainId::from(270), ¶ms) - .await - .unwrap(); + let params = GenesisParams::mock(); + + insert_genesis_batch(&mut conn, ¶ms).await.unwrap(); assert!(!conn.blocks_dal().is_genesis_needed().await.unwrap()); let metadata = conn @@ -487,10 +606,8 @@ mod tests { let root_hash = metadata.unwrap().metadata.root_hash; assert_ne!(root_hash, H256::zero()); - // Check that `ensure_genesis_state()` doesn't panic on repeated runs. - ensure_genesis_state(&mut conn, L2ChainId::from(270), ¶ms) - .await - .unwrap(); + // Check that `genesis is not needed` + assert!(!conn.blocks_dal().is_genesis_needed().await.unwrap()); } #[tokio::test] @@ -499,16 +616,12 @@ mod tests { let mut conn = pool.connection().await.unwrap(); conn.blocks_dal().delete_genesis().await.unwrap(); - let params = GenesisParams { - protocol_version: ProtocolVersionId::latest(), - first_validator: Address::random(), - base_system_contracts: BaseSystemContracts::load_from_disk(), - system_contracts: get_system_smart_contracts(), - first_l1_verifier_config: L1VerifierConfig::default(), - }; - ensure_genesis_state(&mut conn, L2ChainId::max(), ¶ms) - .await - .unwrap(); + let params = GenesisParams::load_genesis_params(GenesisConfig { + l2_chain_id: L2ChainId::max(), + ..mock_genesis_config() + }) + .unwrap(); + insert_genesis_batch(&mut conn, ¶ms).await.unwrap(); assert!(!conn.blocks_dal().is_genesis_needed().await.unwrap()); let metadata = conn @@ -523,14 +636,13 @@ mod tests { async fn running_genesis_with_non_latest_protocol_version() { let pool = ConnectionPool::::test_pool().await; let mut conn = pool.connection().await.unwrap(); - let params = GenesisParams { - protocol_version: ProtocolVersionId::Version10, - ..GenesisParams::mock() - }; + let params = GenesisParams::load_genesis_params(GenesisConfig { + protocol_version: ProtocolVersionId::Version10 as u16, + ..mock_genesis_config() + }) + .unwrap(); - ensure_genesis_state(&mut conn, L2ChainId::max(), ¶ms) - .await - .unwrap(); + insert_genesis_batch(&mut conn, ¶ms).await.unwrap(); assert!(!conn.blocks_dal().is_genesis_needed().await.unwrap()); } } diff --git a/core/lib/zksync_core/src/lib.rs b/core/lib/zksync_core/src/lib.rs index b62fa7bc1da..f1c78a90a16 100644 --- a/core/lib/zksync_core/src/lib.rs +++ b/core/lib/zksync_core/src/lib.rs @@ -29,29 +29,22 @@ use zksync_config::{ CircuitBreakerConfig, MempoolConfig, NetworkConfig, OperationsManagerConfig, StateKeeperConfig, }, - contracts::ProverAtGenesis, database::{MerkleTreeConfig, MerkleTreeMode}, }, - ApiConfig, ContractsConfig, DBConfig, ETHSenderConfig, PostgresConfig, + ApiConfig, ContractsConfig, DBConfig, GenesisConfig, PostgresConfig, }; -use zksync_contracts::{governance_contract, BaseSystemContracts}; +use zksync_contracts::governance_contract; use zksync_dal::{metrics::PostgresMetrics, ConnectionPool, Core, CoreDal}; use zksync_db_connection::healthcheck::ConnectionPoolHealthCheck; use zksync_eth_client::{ clients::{PKSigningClient, QueryClient}, - BoundEthInterface, CallFunctionArgs, EthInterface, + BoundEthInterface, }; use zksync_health_check::{AppHealthCheck, HealthStatus, ReactiveHealthCheck}; use zksync_object_store::{ObjectStore, ObjectStoreFactory}; use zksync_queued_job_processor::JobProcessor; use zksync_state::PostgresStorageCaches; -use zksync_types::{ - fee_model::FeeModelConfig, - protocol_version::{L1VerifierConfig, VerifierParams}, - system_contracts::get_system_smart_contracts, - web3::contract::tokens::Detokenize, - L2ChainId, PackedEthSignature, ProtocolVersionId, -}; +use zksync_types::{fee_model::FeeModelConfig, L2ChainId}; use crate::{ api_server::{ @@ -66,6 +59,7 @@ use crate::{ commitment_generator::CommitmentGenerator, eth_sender::{Aggregator, EthTxAggregator, EthTxManager}, eth_watch::start_eth_watch, + genesis::GenesisParams, house_keeper::{ blocks_state_reporter::L1BatchMetricsReporter, fri_proof_compressor_job_retry_manager::FriProofCompressorJobRetryManager, @@ -111,12 +105,8 @@ mod utils; /// Inserts the initial information about zkSync tokens into the database. pub async fn genesis_init( + genesis_config: GenesisConfig, postgres_config: &PostgresConfig, - eth_sender: ÐSenderConfig, - network_config: &NetworkConfig, - contracts_config: &ContractsConfig, - eth_client_url: &str, - wait_for_set_chain_id: bool, ) -> anyhow::Result<()> { let db_url = postgres_config.master_url()?; let pool = ConnectionPool::::singleton(db_url) @@ -124,82 +114,9 @@ pub async fn genesis_init( .await .context("failed to build connection_pool")?; let mut storage = pool.connection().await.context("connection()")?; - let operator_address = PackedEthSignature::address_from_private_key( - ð_sender - .sender - .private_key() - .context("Private key is required for genesis init")?, - ) - .context("Failed to restore operator address from private key")?; - - // Select the first prover to be used during genesis. - // Later we can change provers using the system upgrades, but for genesis - // we should select one using the environment config. - let first_l1_verifier_config = - if matches!(contracts_config.prover_at_genesis, ProverAtGenesis::Fri) { - let l1_verifier_config = L1VerifierConfig { - params: VerifierParams { - recursion_node_level_vk_hash: contracts_config.fri_recursion_node_level_vk_hash, - recursion_leaf_level_vk_hash: contracts_config.fri_recursion_leaf_level_vk_hash, - recursion_circuits_set_vks_hash: zksync_types::H256::zero(), - }, - recursion_scheduler_level_vk_hash: contracts_config.snark_wrapper_vk_hash, - }; - - let eth_client = QueryClient::new(eth_client_url)?; - let args = CallFunctionArgs::new("verificationKeyHash", ()).for_contract( - contracts_config.verifier_addr, - zksync_contracts::verifier_contract(), - ); - - let vk_hash = eth_client.call_contract_function(args).await?; - let vk_hash = zksync_types::H256::from_tokens(vk_hash)?; - assert_eq!( - vk_hash, l1_verifier_config.recursion_scheduler_level_vk_hash, - "L1 verifier key does not match the one in the config" - ); - - l1_verifier_config - } else { - L1VerifierConfig { - params: VerifierParams { - recursion_node_level_vk_hash: contracts_config.recursion_node_level_vk_hash, - recursion_leaf_level_vk_hash: contracts_config.recursion_leaf_level_vk_hash, - recursion_circuits_set_vks_hash: contracts_config - .recursion_circuits_set_vks_hash, - }, - recursion_scheduler_level_vk_hash: contracts_config - .recursion_scheduler_level_vk_hash, - } - }; - - genesis::ensure_genesis_state( - &mut storage, - network_config.zksync_network_id, - &genesis::GenesisParams { - // We consider the operator to be the first validator for now. - first_validator: operator_address, - protocol_version: ProtocolVersionId::latest(), - base_system_contracts: BaseSystemContracts::load_from_disk(), - system_contracts: get_system_smart_contracts(), - first_l1_verifier_config, - }, - ) - .await?; - - if wait_for_set_chain_id { - genesis::save_set_chain_id_tx( - eth_client_url, - contracts_config.diamond_proxy_addr, - contracts_config - .state_transition_proxy_addr - .context("state_transition_proxy_addr is not set, but needed for genesis")?, - &mut storage, - ) - .await - .context("Failed to save SetChainId upgrade transaction")?; - } + let params = GenesisParams::load_genesis_params(genesis_config)?; + genesis::ensure_genesis_state(&mut storage, ¶ms).await?; Ok(()) } diff --git a/core/lib/zksync_core/src/metadata_calculator/helpers.rs b/core/lib/zksync_core/src/metadata_calculator/helpers.rs index bc826682575..2745244047d 100644 --- a/core/lib/zksync_core/src/metadata_calculator/helpers.rs +++ b/core/lib/zksync_core/src/metadata_calculator/helpers.rs @@ -480,11 +480,11 @@ mod tests { use tempfile::TempDir; use zksync_dal::{ConnectionPool, Core}; use zksync_prover_interface::inputs::PrepareBasicCircuitsJob; - use zksync_types::{L2ChainId, StorageKey, StorageLog}; + use zksync_types::{StorageKey, StorageLog}; use super::*; use crate::{ - genesis::{ensure_genesis_state, GenesisParams}, + genesis::{insert_genesis_batch, GenesisParams}, metadata_calculator::tests::{extend_db_state, gen_storage_logs, reset_db_state}, }; @@ -561,9 +561,8 @@ mod tests { #[tokio::test] async fn loaded_logs_equivalence_basics() { let pool = ConnectionPool::::test_pool().await; - ensure_genesis_state( + insert_genesis_batch( &mut pool.connection().await.unwrap(), - L2ChainId::from(270), &GenesisParams::mock(), ) .await @@ -587,7 +586,7 @@ mod tests { async fn loaded_logs_equivalence_with_zero_no_op_logs() { let pool = ConnectionPool::::test_pool().await; let mut storage = pool.connection().await.unwrap(); - ensure_genesis_state(&mut storage, L2ChainId::from(270), &GenesisParams::mock()) + insert_genesis_batch(&mut storage, &GenesisParams::mock()) .await .unwrap(); @@ -678,7 +677,7 @@ mod tests { async fn loaded_logs_equivalence_with_non_zero_no_op_logs() { let pool = ConnectionPool::::test_pool().await; let mut storage = pool.connection().await.unwrap(); - ensure_genesis_state(&mut storage, L2ChainId::from(270), &GenesisParams::mock()) + insert_genesis_batch(&mut storage, &GenesisParams::mock()) .await .unwrap(); @@ -725,7 +724,7 @@ mod tests { async fn loaded_logs_equivalence_with_protective_reads() { let pool = ConnectionPool::::test_pool().await; let mut storage = pool.connection().await.unwrap(); - ensure_genesis_state(&mut storage, L2ChainId::from(270), &GenesisParams::mock()) + insert_genesis_batch(&mut storage, &GenesisParams::mock()) .await .unwrap(); diff --git a/core/lib/zksync_core/src/metadata_calculator/recovery/tests.rs b/core/lib/zksync_core/src/metadata_calculator/recovery/tests.rs index 8145cfe8c25..8ff5421ae9d 100644 --- a/core/lib/zksync_core/src/metadata_calculator/recovery/tests.rs +++ b/core/lib/zksync_core/src/metadata_calculator/recovery/tests.rs @@ -13,11 +13,11 @@ use zksync_config::configs::{ use zksync_dal::CoreDal; use zksync_health_check::{CheckHealth, HealthStatus, ReactiveHealthCheck}; use zksync_merkle_tree::{domain::ZkSyncTree, TreeInstruction}; -use zksync_types::{L1BatchNumber, L2ChainId, ProtocolVersionId, StorageLog}; +use zksync_types::{L1BatchNumber, ProtocolVersionId, StorageLog}; use super::*; use crate::{ - genesis::{ensure_genesis_state, GenesisParams}, + genesis::{insert_genesis_batch, GenesisParams}, metadata_calculator::{ helpers::create_db, tests::{ @@ -98,7 +98,7 @@ async fn prepare_recovery_snapshot_with_genesis( temp_dir: &TempDir, ) -> SnapshotRecoveryStatus { let mut storage = pool.connection().await.unwrap(); - ensure_genesis_state(&mut storage, L2ChainId::from(270), &GenesisParams::mock()) + insert_genesis_batch(&mut storage, &GenesisParams::mock()) .await .unwrap(); let mut logs = gen_storage_logs(100..300, 1).pop().unwrap(); diff --git a/core/lib/zksync_core/src/metadata_calculator/tests.rs b/core/lib/zksync_core/src/metadata_calculator/tests.rs index 29096380b18..e85b23eba7c 100644 --- a/core/lib/zksync_core/src/metadata_calculator/tests.rs +++ b/core/lib/zksync_core/src/metadata_calculator/tests.rs @@ -16,14 +16,14 @@ use zksync_merkle_tree::domain::ZkSyncTree; use zksync_object_store::{ObjectStore, ObjectStoreFactory}; use zksync_prover_interface::inputs::PrepareBasicCircuitsJob; use zksync_types::{ - block::L1BatchHeader, AccountTreeId, Address, L1BatchNumber, L2ChainId, MiniblockNumber, - StorageKey, StorageLog, H256, + block::L1BatchHeader, AccountTreeId, Address, L1BatchNumber, MiniblockNumber, StorageKey, + StorageLog, H256, }; use zksync_utils::u32_to_h256; use super::{GenericAsyncTree, L1BatchWithLogs, MetadataCalculator, MetadataCalculatorConfig}; use crate::{ - genesis::{ensure_genesis_state, GenesisParams}, + genesis::{insert_genesis_batch, GenesisParams}, utils::testonly::{create_l1_batch, create_miniblock}, }; @@ -403,7 +403,7 @@ async fn setup_calculator_with_options( let mut storage = pool.connection().await.unwrap(); if storage.blocks_dal().is_genesis_needed().await.unwrap() { - ensure_genesis_state(&mut storage, L2ChainId::from(270), &GenesisParams::mock()) + insert_genesis_batch(&mut storage, &GenesisParams::mock()) .await .unwrap(); } @@ -634,7 +634,7 @@ async fn remove_l1_batches( async fn deduplication_works_as_expected() { let pool = ConnectionPool::::test_pool().await; let mut storage = pool.connection().await.unwrap(); - ensure_genesis_state(&mut storage, L2ChainId::from(270), &GenesisParams::mock()) + insert_genesis_batch(&mut storage, &GenesisParams::mock()) .await .unwrap(); diff --git a/core/lib/zksync_core/src/reorg_detector/tests.rs b/core/lib/zksync_core/src/reorg_detector/tests.rs index af3c62eb81b..a9fc2ee83a7 100644 --- a/core/lib/zksync_core/src/reorg_detector/tests.rs +++ b/core/lib/zksync_core/src/reorg_detector/tests.rs @@ -11,13 +11,13 @@ use tokio::sync::mpsc; use zksync_dal::{Connection, CoreDal}; use zksync_types::{ block::{MiniblockHasher, MiniblockHeader}, - L2ChainId, ProtocolVersion, + ProtocolVersion, }; use zksync_web3_decl::jsonrpsee::core::ClientError as RpcError; use super::*; use crate::{ - genesis::{ensure_genesis_state, GenesisParams}, + genesis::{insert_genesis_batch, GenesisParams}, utils::testonly::{create_l1_batch, create_miniblock}, }; @@ -175,17 +175,16 @@ async fn normal_reorg_function(snapshot_recovery: bool, with_transient_errors: b .save_protocol_version_with_tx(ProtocolVersion::default()) .await; } else { - let genesis_root_hash = - ensure_genesis_state(&mut storage, L2ChainId::default(), &GenesisParams::mock()) - .await - .unwrap(); + let genesis_batch = insert_genesis_batch(&mut storage, &GenesisParams::mock()) + .await + .unwrap(); client.miniblock_hashes.insert( MiniblockNumber(0), MiniblockHasher::legacy_hash(MiniblockNumber(0)), ); client .l1_batch_root_hashes - .insert(L1BatchNumber(0), genesis_root_hash); + .insert(L1BatchNumber(0), genesis_batch.root_hash); } let l1_batch_numbers = if snapshot_recovery { @@ -252,7 +251,7 @@ async fn normal_reorg_function(snapshot_recovery: bool, with_transient_errors: b async fn detector_stops_on_fatal_rpc_error() { let pool = ConnectionPool::::test_pool().await; let mut storage = pool.connection().await.unwrap(); - ensure_genesis_state(&mut storage, L2ChainId::default(), &GenesisParams::mock()) + insert_genesis_batch(&mut storage, &GenesisParams::mock()) .await .unwrap(); @@ -269,10 +268,9 @@ async fn detector_stops_on_fatal_rpc_error() { async fn reorg_is_detected_on_batch_hash_mismatch() { let pool = ConnectionPool::::test_pool().await; let mut storage = pool.connection().await.unwrap(); - let genesis_root_hash = - ensure_genesis_state(&mut storage, L2ChainId::default(), &GenesisParams::mock()) - .await - .unwrap(); + let genesis_batch = insert_genesis_batch(&mut storage, &GenesisParams::mock()) + .await + .unwrap(); let mut client = MockMainNodeClient::default(); client.miniblock_hashes.insert( MiniblockNumber(0), @@ -280,7 +278,7 @@ async fn reorg_is_detected_on_batch_hash_mismatch() { ); client .l1_batch_root_hashes - .insert(L1BatchNumber(0), genesis_root_hash); + .insert(L1BatchNumber(0), genesis_batch.root_hash); let miniblock_hash = H256::from_low_u64_be(23); client @@ -316,17 +314,16 @@ async fn reorg_is_detected_on_miniblock_hash_mismatch() { let pool = ConnectionPool::::test_pool().await; let mut storage = pool.connection().await.unwrap(); let mut client = MockMainNodeClient::default(); - let genesis_root_hash = - ensure_genesis_state(&mut storage, L2ChainId::default(), &GenesisParams::mock()) - .await - .unwrap(); + let genesis_batch = insert_genesis_batch(&mut storage, &GenesisParams::mock()) + .await + .unwrap(); client.miniblock_hashes.insert( MiniblockNumber(0), MiniblockHasher::legacy_hash(MiniblockNumber(0)), ); client .l1_batch_root_hashes - .insert(L1BatchNumber(0), genesis_root_hash); + .insert(L1BatchNumber(0), genesis_batch.root_hash); let miniblock_hash = H256::from_low_u64_be(23); client @@ -480,11 +477,10 @@ async fn stopping_reorg_detector_while_waiting_for_l1_batch() { async fn detector_errors_on_earliest_batch_hash_mismatch() { let pool = ConnectionPool::::test_pool().await; let mut storage = pool.connection().await.unwrap(); - let genesis_root_hash = - ensure_genesis_state(&mut storage, L2ChainId::default(), &GenesisParams::mock()) - .await - .unwrap(); - assert_ne!(genesis_root_hash, H256::zero()); + let genesis_batch = insert_genesis_batch(&mut storage, &GenesisParams::mock()) + .await + .unwrap(); + assert_ne!(genesis_batch.root_hash, H256::zero()); let mut client = MockMainNodeClient::default(); client @@ -534,10 +530,9 @@ async fn detector_errors_on_earliest_batch_hash_mismatch_with_snapshot_recovery( async fn reorg_is_detected_without_waiting_for_main_node_to_catch_up() { let pool = ConnectionPool::::test_pool().await; let mut storage = pool.connection().await.unwrap(); - let genesis_root_hash = - ensure_genesis_state(&mut storage, L2ChainId::default(), &GenesisParams::mock()) - .await - .unwrap(); + let genesis_batch = insert_genesis_batch(&mut storage, &GenesisParams::mock()) + .await + .unwrap(); // Fill in local storage with some data, so that it's ahead of the main node. for number in 1..5 { store_miniblock(&mut storage, number, H256::zero()).await; @@ -548,7 +543,7 @@ async fn reorg_is_detected_without_waiting_for_main_node_to_catch_up() { let mut client = MockMainNodeClient::default(); client .l1_batch_root_hashes - .insert(L1BatchNumber(0), genesis_root_hash); + .insert(L1BatchNumber(0), genesis_batch.root_hash); for number in 1..3 { client .miniblock_hashes diff --git a/core/lib/zksync_core/src/state_keeper/io/common/tests.rs b/core/lib/zksync_core/src/state_keeper/io/common/tests.rs index 3ca2d2aa015..6509eae3b62 100644 --- a/core/lib/zksync_core/src/state_keeper/io/common/tests.rs +++ b/core/lib/zksync_core/src/state_keeper/io/common/tests.rs @@ -7,6 +7,7 @@ use std::{collections::HashMap, ops}; use futures::FutureExt; use vm_utils::storage::L1BatchParamsProvider; +use zksync_config::GenesisConfig; use zksync_contracts::BaseSystemContractsHashes; use zksync_dal::{ConnectionPool, Core}; use zksync_types::{ @@ -16,7 +17,7 @@ use zksync_types::{ use super::*; use crate::{ - genesis::{ensure_genesis_state, GenesisParams}, + genesis::{insert_genesis_batch, mock_genesis_config, GenesisParams}, utils::testonly::{ create_l1_batch, create_l2_transaction, create_miniblock, execute_l2_transaction, prepare_recovery_snapshot, @@ -37,7 +38,7 @@ fn test_poll_iters() { async fn creating_io_cursor_with_genesis() { let pool = ConnectionPool::::test_pool().await; let mut storage = pool.connection().await.unwrap(); - ensure_genesis_state(&mut storage, L2ChainId::default(), &GenesisParams::mock()) + insert_genesis_batch(&mut storage, &GenesisParams::mock()) .await .unwrap(); @@ -102,17 +103,16 @@ async fn creating_io_cursor_with_snapshot_recovery() { async fn waiting_for_l1_batch_params_with_genesis() { let pool = ConnectionPool::::test_pool().await; let mut storage = pool.connection().await.unwrap(); - let genesis_root_hash = - ensure_genesis_state(&mut storage, L2ChainId::default(), &GenesisParams::mock()) - .await - .unwrap(); + let genesis_batch = insert_genesis_batch(&mut storage, &GenesisParams::mock()) + .await + .unwrap(); let provider = L1BatchParamsProvider::new(&mut storage).await.unwrap(); let (hash, timestamp) = provider .wait_for_l1_batch_params(&mut storage, L1BatchNumber(0)) .await .unwrap(); - assert_eq!(hash, genesis_root_hash); + assert_eq!(hash, genesis_batch.root_hash); assert_eq!(timestamp, 0); let new_l1_batch = create_l1_batch(1); @@ -190,7 +190,7 @@ async fn waiting_for_l1_batch_params_after_snapshot_recovery() { async fn getting_first_miniblock_in_batch_with_genesis() { let pool = ConnectionPool::::test_pool().await; let mut storage = pool.connection().await.unwrap(); - ensure_genesis_state(&mut storage, L2ChainId::default(), &GenesisParams::mock()) + insert_genesis_batch(&mut storage, &GenesisParams::mock()) .await .unwrap(); @@ -311,13 +311,13 @@ async fn loading_pending_batch_with_genesis() { let pool = ConnectionPool::::test_pool().await; let mut storage = pool.connection().await.unwrap(); let genesis_params = GenesisParams::mock(); - ensure_genesis_state(&mut storage, L2ChainId::default(), &genesis_params) + insert_genesis_batch(&mut storage, &genesis_params) .await .unwrap(); store_pending_miniblocks( &mut storage, 1..=2, - genesis_params.base_system_contracts.hashes(), + genesis_params.base_system_contracts().hashes(), ) .await; @@ -391,7 +391,7 @@ async fn loading_pending_batch_after_snapshot_recovery() { store_pending_miniblocks( &mut storage, starting_miniblock_number..=starting_miniblock_number + 1, - GenesisParams::mock().base_system_contracts.hashes(), + GenesisParams::mock().base_system_contracts().hashes(), ) .await; @@ -444,9 +444,13 @@ async fn loading_pending_batch_after_snapshot_recovery() { async fn getting_batch_version_with_genesis() { let pool = ConnectionPool::::test_pool().await; let mut storage = pool.connection().await.unwrap(); - let mut genesis_params = GenesisParams::mock(); - genesis_params.protocol_version = ProtocolVersionId::Version5; - ensure_genesis_state(&mut storage, L2ChainId::default(), &genesis_params) + let genesis_params = GenesisParams::load_genesis_params(GenesisConfig { + protocol_version: ProtocolVersionId::Version5 as u16, + ..mock_genesis_config() + }) + .unwrap(); + + insert_genesis_batch(&mut storage, &genesis_params) .await .unwrap(); @@ -455,7 +459,7 @@ async fn getting_batch_version_with_genesis() { .load_l1_batch_protocol_version(&mut storage, L1BatchNumber(0)) .await .unwrap(); - assert_eq!(version, Some(genesis_params.protocol_version)); + assert_eq!(version, Some(genesis_params.protocol_version())); assert!(provider .load_l1_batch_protocol_version(&mut storage, L1BatchNumber(1)) diff --git a/core/lib/zksync_core/src/state_keeper/mempool_actor.rs b/core/lib/zksync_core/src/state_keeper/mempool_actor.rs index 59a6dac6a06..c456a7eccf4 100644 --- a/core/lib/zksync_core/src/state_keeper/mempool_actor.rs +++ b/core/lib/zksync_core/src/state_keeper/mempool_actor.rs @@ -161,14 +161,14 @@ async fn get_transaction_nonces( #[cfg(test)] mod tests { use zksync_types::{ - fee::TransactionExecutionMetrics, L2ChainId, MiniblockNumber, PriorityOpId, - ProtocolVersionId, StorageLog, H256, + fee::TransactionExecutionMetrics, MiniblockNumber, PriorityOpId, ProtocolVersionId, + StorageLog, H256, }; use zksync_utils::u256_to_h256; use super::*; use crate::{ - genesis::{ensure_genesis_state, GenesisParams}, + genesis::{insert_genesis_batch, GenesisParams}, utils::testonly::{create_l2_transaction, MockBatchFeeParamsProvider}, }; @@ -219,7 +219,7 @@ mod tests { async fn syncing_mempool_basics() { let pool = ConnectionPool::::constrained_test_pool(1).await; let mut storage = pool.connection().await.unwrap(); - ensure_genesis_state(&mut storage, L2ChainId::default(), &GenesisParams::mock()) + insert_genesis_batch(&mut storage, &GenesisParams::mock()) .await .unwrap(); drop(storage); @@ -277,7 +277,7 @@ mod tests { async fn ignoring_transaction_with_insufficient_fee() { let pool = ConnectionPool::::constrained_test_pool(1).await; let mut storage = pool.connection().await.unwrap(); - ensure_genesis_state(&mut storage, L2ChainId::default(), &GenesisParams::mock()) + insert_genesis_batch(&mut storage, &GenesisParams::mock()) .await .unwrap(); drop(storage); @@ -318,7 +318,7 @@ mod tests { async fn ignoring_transaction_with_old_nonce() { let pool = ConnectionPool::::constrained_test_pool(1).await; let mut storage = pool.connection().await.unwrap(); - ensure_genesis_state(&mut storage, L2ChainId::default(), &GenesisParams::mock()) + insert_genesis_batch(&mut storage, &GenesisParams::mock()) .await .unwrap(); drop(storage); diff --git a/core/lib/zksync_core/src/sync_layer/batch_status_updater/tests.rs b/core/lib/zksync_core/src/sync_layer/batch_status_updater/tests.rs index 7d4a34f333f..949645427ab 100644 --- a/core/lib/zksync_core/src/sync_layer/batch_status_updater/tests.rs +++ b/core/lib/zksync_core/src/sync_layer/batch_status_updater/tests.rs @@ -6,12 +6,11 @@ use chrono::TimeZone; use test_casing::{test_casing, Product}; use tokio::sync::{watch, Mutex}; use zksync_contracts::BaseSystemContractsHashes; -use zksync_dal::Connection; -use zksync_types::{Address, L2ChainId, ProtocolVersionId}; +use zksync_types::{Address, ProtocolVersionId}; use super::*; use crate::{ - genesis::{ensure_genesis_state, GenesisParams}, + genesis::{insert_genesis_batch, GenesisParams}, sync_layer::metrics::L1BatchStage, utils::testonly::{create_l1_batch, create_miniblock, prepare_recovery_snapshot}, }; @@ -225,9 +224,9 @@ fn mock_updater( #[tokio::test] async fn updater_cursor_for_storage_with_genesis_block() { - let pool = ConnectionPool::::test_pool().await; + let pool = ConnectionPool::test_pool().await; let mut storage = pool.connection().await.unwrap(); - ensure_genesis_state(&mut storage, L2ChainId::default(), &GenesisParams::mock()) + insert_genesis_batch(&mut storage, &GenesisParams::mock()) .await .unwrap(); for number in [1, 2] { @@ -279,7 +278,7 @@ async fn normal_updater_operation(snapshot_recovery: bool, async_batches: bool) prepare_recovery_snapshot(&mut storage, L1BatchNumber(23), MiniblockNumber(42), &[]).await; L1BatchNumber(24) } else { - ensure_genesis_state(&mut storage, L2ChainId::default(), &GenesisParams::mock()) + insert_genesis_batch(&mut storage, &GenesisParams::mock()) .await .unwrap(); L1BatchNumber(1) @@ -351,7 +350,7 @@ async fn updater_with_gradual_main_node_updates(snapshot_recovery: bool) { prepare_recovery_snapshot(&mut storage, L1BatchNumber(23), MiniblockNumber(42), &[]).await; L1BatchNumber(24) } else { - ensure_genesis_state(&mut storage, L2ChainId::default(), &GenesisParams::mock()) + insert_genesis_batch(&mut storage, &GenesisParams::mock()) .await .unwrap(); L1BatchNumber(1) diff --git a/core/lib/zksync_core/src/sync_layer/client.rs b/core/lib/zksync_core/src/sync_layer/client.rs index 3528b526097..4d8827e7ce5 100644 --- a/core/lib/zksync_core/src/sync_layer/client.rs +++ b/core/lib/zksync_core/src/sync_layer/client.rs @@ -3,10 +3,11 @@ use std::fmt; use async_trait::async_trait; +use zksync_config::GenesisConfig; use zksync_system_constants::ACCOUNT_CODE_STORAGE_ADDRESS; use zksync_types::{ api::{self, en}, - get_code_key, Address, L1BatchNumber, MiniblockNumber, ProtocolVersionId, H256, U64, + get_code_key, Address, MiniblockNumber, ProtocolVersionId, H256, U64, }; use zksync_web3_decl::{ error::{ClientRpcContext, EnrichedClientError, EnrichedClientResult}, @@ -32,8 +33,6 @@ pub trait MainNodeClient: 'static + Send + Sync + fmt::Debug { protocol_version: ProtocolVersionId, ) -> EnrichedClientResult>; - async fn fetch_genesis_l1_batch_hash(&self) -> EnrichedClientResult; - async fn fetch_l2_block_number(&self) -> EnrichedClientResult; async fn fetch_l2_block( @@ -43,6 +42,8 @@ pub trait MainNodeClient: 'static + Send + Sync + fmt::Debug { ) -> EnrichedClientResult>; async fn fetch_consensus_genesis(&self) -> EnrichedClientResult>; + + async fn fetch_genesis_config(&self) -> EnrichedClientResult; } impl dyn MainNodeClient { @@ -110,20 +111,8 @@ impl MainNodeClient for HttpClient { .await } - async fn fetch_genesis_l1_batch_hash(&self) -> EnrichedClientResult { - let genesis_l1_batch = self - .get_l1_batch_details(L1BatchNumber(0)) - .rpc_context("get_l1_batch_details") - .await? - .ok_or_else(|| { - EnrichedClientError::custom( - "main node did not return genesis block", - "get_l1_batch_details", - ) - })?; - genesis_l1_batch.base.root_hash.ok_or_else(|| { - EnrichedClientError::custom("missing genesis L1 batch hash", "get_l1_batch_details") - }) + async fn fetch_genesis_config(&self) -> EnrichedClientResult { + self.genesis_config().rpc_context("genesis_config").await } async fn fetch_l2_block_number(&self) -> EnrichedClientResult { diff --git a/core/lib/zksync_core/src/sync_layer/genesis.rs b/core/lib/zksync_core/src/sync_layer/genesis.rs index 2e31d45b18f..2af6e9158b9 100644 --- a/core/lib/zksync_core/src/sync_layer/genesis.rs +++ b/core/lib/zksync_core/src/sync_layer/genesis.rs @@ -2,8 +2,7 @@ use anyhow::Context as _; use zksync_contracts::{BaseSystemContracts, BaseSystemContractsHashes, SystemContractCode}; use zksync_dal::{Connection, Core, CoreDal}; use zksync_types::{ - block::DeployedContract, protocol_version::L1VerifierConfig, - system_contracts::get_system_smart_contracts, AccountTreeId, L1BatchNumber, L2ChainId, H256, + block::DeployedContract, system_contracts::get_system_smart_contracts, AccountTreeId, L2ChainId, }; use super::client::MainNodeClient; @@ -17,32 +16,29 @@ pub async fn perform_genesis_if_needed( let mut transaction = storage.start_transaction().await?; // We want to check whether the genesis is needed before we create genesis params to not // make the node startup slower. - let genesis_block_hash = if transaction.blocks_dal().is_genesis_needed().await? { - let genesis_params = create_genesis_params(client).await?; - ensure_genesis_state(&mut transaction, zksync_chain_id, &genesis_params) + if transaction.blocks_dal().is_genesis_needed().await? { + let genesis_params = create_genesis_params(client, zksync_chain_id).await?; + ensure_genesis_state(&mut transaction, &genesis_params) .await - .context("ensure_genesis_state")? - } else { - transaction - .blocks_dal() - .get_l1_batch_state_root(L1BatchNumber(0)) - .await? - .context("genesis block hash is empty")? - }; - - validate_genesis_state(client, genesis_block_hash).await?; + .context("ensure_genesis_state")?; + } transaction.commit().await?; Ok(()) } -async fn create_genesis_params(client: &dyn MainNodeClient) -> anyhow::Result { - let genesis_miniblock = client - .fetch_l2_block(zksync_types::MiniblockNumber(0), false) - .await? - .context("No genesis block on the main node")?; - let first_validator = genesis_miniblock.operator_address; - let base_system_contracts_hashes = genesis_miniblock.base_system_contracts_hashes; - let protocol_version = genesis_miniblock.protocol_version; +async fn create_genesis_params( + client: &dyn MainNodeClient, + zksync_chain_id: L2ChainId, +) -> anyhow::Result { + let config = client.fetch_genesis_config().await?; + let base_system_contracts_hashes = BaseSystemContractsHashes { + bootloader: config.bootloader_hash, + default_aa: config.default_aa_hash, + }; + + if zksync_chain_id != config.l2_chain_id { + anyhow::bail!("L2 chain id from server and locally doesn't match"); + } // Load the list of addresses that are known to contain system contracts at any point in time. // Not every of these addresses is guaranteed to be present in the genesis state, but we'll iterate through @@ -84,15 +80,11 @@ async fn create_genesis_params(client: &dyn MainNodeClient) -> anyhow::Result anyhow::Result<()> { - let genesis_l1_batch_hash = client.fetch_genesis_l1_batch_hash().await?; - anyhow::ensure!( - genesis_l1_batch_hash == root_hash, - "Genesis L1 batch root hash mismatch with main node: expected {root_hash}, got {genesis_l1_batch_hash}" - ); - Ok(()) -} diff --git a/core/lib/zksync_core/src/sync_layer/tests.rs b/core/lib/zksync_core/src/sync_layer/tests.rs index 2f04aacaa81..55f3d74a45f 100644 --- a/core/lib/zksync_core/src/sync_layer/tests.rs +++ b/core/lib/zksync_core/src/sync_layer/tests.rs @@ -21,7 +21,7 @@ use zksync_types::{ use super::{fetcher::FetchedTransaction, sync_action::SyncAction, *}; use crate::{ consensus::testonly::MockMainNodeClient, - genesis::{ensure_genesis_state, GenesisParams}, + genesis::{insert_genesis_batch, GenesisParams}, state_keeper::{ seal_criteria::NoopSealer, tests::TestBatchExecutorBuilder, MiniblockSealer, ZkSyncStateKeeper, @@ -127,7 +127,7 @@ impl StateKeeperHandles { async fn ensure_genesis(storage: &mut Connection<'_, Core>) { if storage.blocks_dal().is_genesis_needed().await.unwrap() { - ensure_genesis_state(storage, L2ChainId::default(), &GenesisParams::mock()) + insert_genesis_batch(storage, &GenesisParams::mock()) .await .unwrap(); } diff --git a/core/lib/zksync_core/src/utils/mod.rs b/core/lib/zksync_core/src/utils/mod.rs index 645d7422ff7..820dbbd8463 100644 --- a/core/lib/zksync_core/src/utils/mod.rs +++ b/core/lib/zksync_core/src/utils/mod.rs @@ -165,10 +165,9 @@ pub(crate) async fn pending_protocol_version( #[cfg(test)] mod tests { - use zksync_types::L2ChainId; use super::*; - use crate::genesis::{ensure_genesis_state, GenesisParams}; + use crate::genesis::{insert_genesis_batch, GenesisParams}; #[tokio::test] async fn test_binary_search() { @@ -188,7 +187,7 @@ mod tests { tokio::spawn(async move { tokio::time::sleep(Duration::from_millis(25)).await; let mut storage = pool_copy.connection().await.unwrap(); - ensure_genesis_state(&mut storage, L2ChainId::default(), &GenesisParams::mock()) + insert_genesis_batch(&mut storage, &GenesisParams::mock()) .await .unwrap(); }); diff --git a/core/lib/zksync_core/src/utils/testonly.rs b/core/lib/zksync_core/src/utils/testonly.rs index 202b50515e9..63de2dc6000 100644 --- a/core/lib/zksync_core/src/utils/testonly.rs +++ b/core/lib/zksync_core/src/utils/testonly.rs @@ -164,12 +164,12 @@ impl Snapshot { storage_logs: &[StorageLog], ) -> Self { let genesis_params = GenesisParams::mock(); - let contracts = &genesis_params.base_system_contracts; + let contracts = genesis_params.base_system_contracts(); let l1_batch = L1BatchHeader::new( l1_batch, l1_batch.0.into(), contracts.hashes(), - genesis_params.protocol_version, + genesis_params.protocol_version(), ); let miniblock = MiniblockHeader { number: miniblock, @@ -181,10 +181,10 @@ impl Snapshot { batch_fee_input: BatchFeeInput::l1_pegged(100, 100), fee_account_address: Address::zero(), gas_per_pubdata_limit: get_max_gas_per_pubdata_byte( - genesis_params.protocol_version.into(), + genesis_params.protocol_version().into(), ), base_system_contracts_hashes: contracts.hashes(), - protocol_version: Some(genesis_params.protocol_version), + protocol_version: Some(genesis_params.protocol_version()), virtual_blocks: 1, }; Snapshot { @@ -272,7 +272,6 @@ pub(crate) async fn recover( .collect(); let l1_batch_root_hash = ZkSyncTree::process_genesis_batch(&tree_instructions).root_hash; - // Store factory deps for the base system contracts. let protocol_version = storage .protocol_versions_dal() .get_protocol_version(snapshot.l1_batch.protocol_version.unwrap()) diff --git a/etc/env/base/chain.toml b/etc/env/base/chain.toml index b6c7b5093ba..6aa4f1ba0c1 100644 --- a/etc/env/base/chain.toml +++ b/etc/env/base/chain.toml @@ -2,74 +2,74 @@ [chain.eth] # Name of the used Ethereum network -network="localhost" +network = "localhost" # Name of current zkSync network # Used for Sentry environment -zksync_network="localhost" +zksync_network = "localhost" # ID of current zkSync network treated as ETH network ID. # Used to distinguish zkSync from other Web3-capable networks. -zksync_network_id=270 +zksync_network_id = 270 [chain.state_keeper] -fee_account_addr="0xde03a0B5963f75f1C8485B355fF6D30f3093BDE7" +fee_account_addr = "0xde03a0B5963f75f1C8485B355fF6D30f3093BDE7" # Denotes the amount of slots for transactions in the block. -transaction_slots=250 +transaction_slots = 250 -max_allowed_l2_tx_gas_limit=4000000000 -block_commit_deadline_ms=2500 -miniblock_commit_deadline_ms=1000 -miniblock_seal_queue_capacity=10 +max_allowed_l2_tx_gas_limit = 4000000000 +block_commit_deadline_ms = 2500 +miniblock_commit_deadline_ms = 1000 +miniblock_seal_queue_capacity = 10 # Max gas that can used to include single block in aggregated operation -max_single_tx_gas=6000000 +max_single_tx_gas = 6000000 # Configuration option for block to be sealed in case # it takes more percentage of the max block capacity than this value. -close_block_at_geometry_percentage=0.95 +close_block_at_geometry_percentage = 0.95 # Configuration option for block to be sealed in case # it takes more percentage of the max block capacity than this value. -close_block_at_eth_params_percentage=0.95 +close_block_at_eth_params_percentage = 0.95 # Configuration option for block to be sealed in case # it takes more percentage of the max block capacity than this value. -close_block_at_gas_percentage=0.95 +close_block_at_gas_percentage = 0.95 # Configuration option for tx to be rejected in case # it takes more percentage of the block capacity than this value. -reject_tx_at_geometry_percentage=0.95 +reject_tx_at_geometry_percentage = 0.95 # Configuration option for block to be sealed in case # it takes more percentage of the max block capacity than this value. -reject_tx_at_eth_params_percentage=0.95 +reject_tx_at_eth_params_percentage = 0.95 # Configuration option for block to be sealed in case # it takes more percentage of the max block gas capacity than this value. -reject_tx_at_gas_percentage=0.95 +reject_tx_at_gas_percentage = 0.95 # The minimal acceptable L2 gas price, i.e. the price that should include the cost of computation/proving as well # as potentially premium for congestion. -minimal_l2_gas_price=100000000 +minimal_l2_gas_price = 100000000 # The constant that represents the possibility that a batch can be sealed because of overuse of computation resources. # It has range from 0 to 1. If it is 0, the compute will not depend on the cost for closing the batch. # If it is 1, the gas limit per batch will have to cover the entire cost of closing the batch. -compute_overhead_part=0.0 +compute_overhead_part = 0.0 # The constant that represents the possibility that a batch can be sealed because of overuse of pubdata. # It has range from 0 to 1. If it is 0, the pubdata will not depend on the cost for closing the batch. # If it is 1, the pubdata limit per batch will have to cover the entire cost of closing the batch. -pubdata_overhead_part=1.0 +pubdata_overhead_part = 1.0 # The constant amount of L1 gas that is used as the overhead for the batch. It includes the price for batch verification, etc. -batch_overhead_l1_gas=800000 +batch_overhead_l1_gas = 800000 # The maximum amount of gas that can be used by the batch. This value is derived from the circuits limitation per batch. -max_gas_per_batch=200000000 +max_gas_per_batch = 200000000 # This will also determine how many blobs are used, when enabled. # If the value is less than 126 kb -> Calldata or 1 Blob # If the value is > 126 kb and < 252 kb then 2 blobs are used. # Note, the max at this moment is 252 kb -max_pubdata_per_batch=100000 +max_pubdata_per_batch = 100000 # The version of the fee model to use. # - `V1`, the first model that was used in zkSync Era. In this fee model, the pubdata price must be pegged to the L1 gas price. @@ -78,33 +78,36 @@ max_pubdata_per_batch=100000 # - `V2`, the second model that was used in zkSync Era. There the pubdata price might be independent from the L1 gas price. Also, # The fair L2 gas price is expected to both the proving/computation price for the operator and the costs that come from # processing the batch on L1. -fee_model_version="V1" +fee_model_version = "V1" # Max number of computational gas that validation step is allowed to take. -validation_computational_gas_limit=300000 -save_call_traces=true +validation_computational_gas_limit = 300000 +save_call_traces = true -virtual_blocks_interval=1 -virtual_blocks_per_miniblock=1 +virtual_blocks_interval = 1 +virtual_blocks_per_miniblock = 1 # WARNING! This slows down the statekeeper, forcing mempool to upload to GCS # It is meant as a validation flag to be used in STAGING only. # This variable should not be set to true in any customer facing environment. -upload_witness_inputs_to_gcs=false +upload_witness_inputs_to_gcs = false + +bootloader_hash = "0x010007ede999d096c84553fb514d3d6ca76fbf39789dda76bfeda9f3ae06236e" +default_aa_hash = "0x0100055b041eb28aff6e3a6e0f37c31fd053fc9ef142683b05e5f0aee6934066" [chain.operations_manager] # Sleep time when there is no new input data -delay_interval=100 +delay_interval = 100 [chain.mempool] -delay_interval=100 -sync_interval_ms=10 +delay_interval = 100 +sync_interval_ms = 10 sync_batch_size = 1000 -capacity=10_000_000 -stuck_tx_timeout=86400 # 1 day in seconds -remove_stuck_txs=true +capacity = 10_000_000 +stuck_tx_timeout = 86400 # 1 day in seconds +remove_stuck_txs = true [chain.circuit_breaker] -sync_interval_ms=30000 -http_req_max_retry_number=5 -http_req_retry_interval_sec=2 +sync_interval_ms = 30000 +http_req_max_retry_number = 5 +http_req_retry_interval_sec = 2 diff --git a/etc/env/base/contracts.toml b/etc/env/base/contracts.toml index a9d802aaaf4..c2168900d7d 100644 --- a/etc/env/base/contracts.toml +++ b/etc/env/base/contracts.toml @@ -2,52 +2,50 @@ # Values of this file are updated automatically by the contract deploy script. [contracts] -ADMIN_FACET_ADDR="0x5E6D086F5eC079ADFF4FB3774CDf3e8D6a34F7E9" -DIAMOND_INIT_ADDR="0x5E6D086F5eC079ADFF4FB3774CDf3e8D6a34F7E9" -DIAMOND_UPGRADE_INIT_ADDR="0x5E6D086F5eC079ADFF4FB3774CDf3e8D6a34F7E9" -DEFAULT_UPGRADE_ADDR="0x5E6D086F5eC079ADFF4FB3774CDf3e8D6a34F7E9" -MAILBOX_FACET_ADDR="0x5E6D086F5eC079ADFF4FB3774CDf3e8D6a34F7E9" -EXECUTOR_FACET_ADDR="0x5E6D086F5eC079ADFF4FB3774CDf3e8D6a34F7E9" -GOVERNANCE_ADDR="0x5E6D086F5eC079ADFF4FB3774CDf3e8D6a34F7E9" -GETTERS_FACET_ADDR="0x5E6D086F5eC079ADFF4FB3774CDf3e8D6a34F7E9" -VERIFIER_ADDR="0xDAbb67b676F5b01FcC8997Cc8439846D0d8078ca" -DIAMOND_PROXY_ADDR="0xFC073319977e314F251EAE6ae6bE76B0B3BAeeCF" -L1_MULTICALL3_ADDR="0xcA11bde05977b3631167028862bE2a173976CA11" -L1_ERC20_BRIDGE_PROXY_ADDR="0xFC073319977e314F251EAE6ae6bE76B0B3BAeeCF" -L1_ERC20_BRIDGE_IMPL_ADDR="0xFC073319977e314F251EAE6ae6bE76B0B3BAeeCF" -L2_ERC20_BRIDGE_ADDR="0xFC073319977e314F251EAE6ae6bE76B0B3BAeeCF" -L2_TESTNET_PAYMASTER_ADDR="0xFC073319977e314F251EAE6ae6bE76B0B3BAeeCF" -L1_ALLOW_LIST_ADDR="0xFC073319977e314F251EAE6ae6bE76B0B3BAeeCF" -CREATE2_FACTORY_ADDR="0xce0042B868300000d44A59004Da54A005ffdcf9f" -VALIDATOR_TIMELOCK_ADDR="0xFC073319977e314F251EAE6ae6bE76B0B3BAeeCF" -VALIDATOR_TIMELOCK_EXECUTION_DELAY=0 -RECURSION_SCHEDULER_LEVEL_VK_HASH="0x18518ce15be02847459f304b1567cb914ae357eca82af07c09582e78592b987b" -RECURSION_NODE_LEVEL_VK_HASH="0x1186ec268d49f1905f8d9c1e9d39fc33e98c74f91d91a21b8f7ef78bd09a8db8" -RECURSION_LEAF_LEVEL_VK_HASH="0x101e08b00193e529145ee09823378ef51a3bc8966504064f1f6ba3f1ba863210" -RECURSION_CIRCUITS_SET_VKS_HASH="0x18c1639094f58177409186e8c48d9f577c9410901d2f1d486b3e7d6cf553ae4c" -GENESIS_TX_HASH="0xb99ebfea46cbe05a21cd80fe5597d97b204befc52a16303f579c607dc1ac2e2e" -GENESIS_ROOT="0x2d5ab622df708ab44944bb02377be85b6f27812e9ae520734873b7a193898ba4" -PRIORITY_TX_MAX_GAS_LIMIT=72000000 -DEPLOY_L2_BRIDGE_COUNTERPART_GAS_LIMIT=10000000 -GENESIS_BATCH_COMMITMENT="0x6c7f89335e3ade24a7768ed73c425afd9fac92a094e0681f76cb6feabf8b6223" +ADMIN_FACET_ADDR = "0x5E6D086F5eC079ADFF4FB3774CDf3e8D6a34F7E9" +DIAMOND_INIT_ADDR = "0x5E6D086F5eC079ADFF4FB3774CDf3e8D6a34F7E9" +DIAMOND_UPGRADE_INIT_ADDR = "0x5E6D086F5eC079ADFF4FB3774CDf3e8D6a34F7E9" +DEFAULT_UPGRADE_ADDR = "0x5E6D086F5eC079ADFF4FB3774CDf3e8D6a34F7E9" +MAILBOX_FACET_ADDR = "0x5E6D086F5eC079ADFF4FB3774CDf3e8D6a34F7E9" +EXECUTOR_FACET_ADDR = "0x5E6D086F5eC079ADFF4FB3774CDf3e8D6a34F7E9" +GOVERNANCE_ADDR = "0x5E6D086F5eC079ADFF4FB3774CDf3e8D6a34F7E9" +GETTERS_FACET_ADDR = "0x5E6D086F5eC079ADFF4FB3774CDf3e8D6a34F7E9" +VERIFIER_ADDR = "0xDAbb67b676F5b01FcC8997Cc8439846D0d8078ca" +DIAMOND_PROXY_ADDR = "0xFC073319977e314F251EAE6ae6bE76B0B3BAeeCF" +L1_MULTICALL3_ADDR = "0xcA11bde05977b3631167028862bE2a173976CA11" +L1_ERC20_BRIDGE_PROXY_ADDR = "0xFC073319977e314F251EAE6ae6bE76B0B3BAeeCF" +L1_ERC20_BRIDGE_IMPL_ADDR = "0xFC073319977e314F251EAE6ae6bE76B0B3BAeeCF" +L2_ERC20_BRIDGE_ADDR = "0xFC073319977e314F251EAE6ae6bE76B0B3BAeeCF" +L2_TESTNET_PAYMASTER_ADDR = "0xFC073319977e314F251EAE6ae6bE76B0B3BAeeCF" +L1_ALLOW_LIST_ADDR = "0xFC073319977e314F251EAE6ae6bE76B0B3BAeeCF" +CREATE2_FACTORY_ADDR = "0xce0042B868300000d44A59004Da54A005ffdcf9f" +VALIDATOR_TIMELOCK_ADDR = "0xFC073319977e314F251EAE6ae6bE76B0B3BAeeCF" +VALIDATOR_TIMELOCK_EXECUTION_DELAY = 0 +RECURSION_SCHEDULER_LEVEL_VK_HASH = "0x18518ce15be02847459f304b1567cb914ae357eca82af07c09582e78592b987b" +RECURSION_NODE_LEVEL_VK_HASH = "0x1186ec268d49f1905f8d9c1e9d39fc33e98c74f91d91a21b8f7ef78bd09a8db8" +RECURSION_LEAF_LEVEL_VK_HASH = "0x101e08b00193e529145ee09823378ef51a3bc8966504064f1f6ba3f1ba863210" +RECURSION_CIRCUITS_SET_VKS_HASH = "0x18c1639094f58177409186e8c48d9f577c9410901d2f1d486b3e7d6cf553ae4c" +GENESIS_TX_HASH = "0xb99ebfea46cbe05a21cd80fe5597d97b204befc52a16303f579c607dc1ac2e2e" +GENESIS_ROOT = "0x436cf80dd02a7e1a1df65be6ec9ea231ccec97c44f4c8c9cd2aa26c2feb074cd" +PRIORITY_TX_MAX_GAS_LIMIT = 72000000 +DEPLOY_L2_BRIDGE_COUNTERPART_GAS_LIMIT = 10000000 +GENESIS_BATCH_COMMITMENT = "0x938016208176c5a49d47c8aa582b5d18afc4f159dfa099087770e0796948fd1a" # Current rollup leaf index after genesis -GENESIS_ROLLUP_LEAF_INDEX="21" -L1_WETH_BRIDGE_IMPL_ADDR="0x5E6D086F5eC079ADFF4FB3774CDf3e8D6a34F7E9" -L1_WETH_BRIDGE_PROXY_ADDR="0x5E6D086F5eC079ADFF4FB3774CDf3e8D6a34F7E9" -L1_WETH_TOKEN_ADDR="0x5E6D086F5eC079ADFF4FB3774CDf3e8D6a34F7E9" -L2_WETH_BRIDGE_ADDR="0x5E6D086F5eC079ADFF4FB3774CDf3e8D6a34F7E9" -L2_WETH_TOKEN_IMPL_ADDR="0x5E6D086F5eC079ADFF4FB3774CDf3e8D6a34F7E9" -L2_WETH_TOKEN_PROXY_ADDR="0x5E6D086F5eC079ADFF4FB3774CDf3e8D6a34F7E9" -FRI_RECURSION_LEAF_LEVEL_VK_HASH ="0x400a4b532c6f072c00d1806ef299300d4c104f4ac55bd8698ade78894fcadc0a" -FRI_RECURSION_NODE_LEVEL_VK_HASH ="0x5a3ef282b21e12fe1f4438e5bb158fc5060b160559c5158c6389d62d9fe3d080" -FRI_RECURSION_SCHEDULER_LEVEL_VK_HASH ="0x1405880dc3317d635bddb0ab62bf5d013e5d1f462161c1f7ac3289c7fef956da" -SNARK_WRAPPER_VK_HASH ="0x063c6fb5c70404c2867f413a8e35563ad3d040b1ad8c11786231bfdba7b472c7" -BLOB_VERSIONED_HASH_RETRIEVER_ADDR="0x0000000000000000000000000000000000000000" +GENESIS_ROLLUP_LEAF_INDEX = "26" +GENESIS_PROTOCOL_VERSION = "22" +L1_WETH_BRIDGE_IMPL_ADDR = "0x5E6D086F5eC079ADFF4FB3774CDf3e8D6a34F7E9" +L1_WETH_BRIDGE_PROXY_ADDR = "0x5E6D086F5eC079ADFF4FB3774CDf3e8D6a34F7E9" +L1_WETH_TOKEN_ADDR = "0x5E6D086F5eC079ADFF4FB3774CDf3e8D6a34F7E9" +L2_WETH_BRIDGE_ADDR = "0x5E6D086F5eC079ADFF4FB3774CDf3e8D6a34F7E9" +L2_WETH_TOKEN_IMPL_ADDR = "0x5E6D086F5eC079ADFF4FB3774CDf3e8D6a34F7E9" +L2_WETH_TOKEN_PROXY_ADDR = "0x5E6D086F5eC079ADFF4FB3774CDf3e8D6a34F7E9" +FRI_RECURSION_LEAF_LEVEL_VK_HASH = "0x400a4b532c6f072c00d1806ef299300d4c104f4ac55bd8698ade78894fcadc0a" +FRI_RECURSION_NODE_LEVEL_VK_HASH = "0x5a3ef282b21e12fe1f4438e5bb158fc5060b160559c5158c6389d62d9fe3d080" +FRI_RECURSION_SCHEDULER_LEVEL_VK_HASH = "0x1405880dc3317d635bddb0ab62bf5d013e5d1f462161c1f7ac3289c7fef956da" +SNARK_WRAPPER_VK_HASH = "0x063c6fb5c70404c2867f413a8e35563ad3d040b1ad8c11786231bfdba7b472c7" +BLOB_VERSIONED_HASH_RETRIEVER_ADDR = "0x0000000000000000000000000000000000000000" -# Prover that should be used at genesis. 'fri' or 'snark' -PROVER_AT_GENESIS="fri" - -INITIAL_PROTOCOL_VERSION=18 +INITIAL_PROTOCOL_VERSION = 22 # These are currently not used, but will be used once the shared bridge is up BRIDGEHUB_PROXY_ADDR = "0x0000000000000000000000000000000000000000" @@ -57,6 +55,6 @@ STATE_TRANSITION_IMPL_ADDR = "0x0000000000000000000000000000000000000000" TRANSPARENT_PROXY_ADMIN_ADDR = "0x0000000000000000000000000000000000000000" [contracts.test] -dummy_verifier=true -easy_priority_mode=false +dummy_verifier = true +easy_priority_mode = false diff --git a/etc/env/base/eth_client.toml b/etc/env/base/eth_client.toml index ef0e1015514..3bdef998877 100644 --- a/etc/env/base/eth_client.toml +++ b/etc/env/base/eth_client.toml @@ -1,4 +1,4 @@ [eth_client] -chain_id=9 +chain_id = 9 # Addresses of the Ethereum node API, separated by comma -web3_url="http://127.0.0.1:8545" +web3_url = "http://127.0.0.1:8545" diff --git a/etc/env/base/private.toml b/etc/env/base/private.toml index 2e872e0b752..1d6f8dabf82 100644 --- a/etc/env/base/private.toml +++ b/etc/env/base/private.toml @@ -1,20 +1,20 @@ # Sensitive values which MUST be different for production # Values provided here are valid for the development infrastructure only. -database_url="postgres://postgres:notsecurepassword@localhost/zksync_local" -database_prover_url="postgres://postgres:notsecurepassword@localhost/prover_local" -test_database_url="postgres://postgres:notsecurepassword@localhost:5433/zksync_local_test" -test_database_prover_url="postgres://postgres:notsecurepassword@localhost:5433/prover_local_test" +database_url = "postgres://postgres:notsecurepassword@localhost/zksync_local" +database_prover_url = "postgres://postgres:notsecurepassword@localhost/prover_local" +test_database_url = "postgres://postgres:notsecurepassword@localhost:5433/zksync_local_test" +test_database_prover_url = "postgres://postgres:notsecurepassword@localhost:5433/prover_local_test" [eth_sender.sender] # Set in env file for development, production, staging and testnet. -operator_private_key="0x27593fea79697e947890ecbecce7901b0008345e5d7259710d0dd5e500d040be" +operator_private_key = "0x27593fea79697e947890ecbecce7901b0008345e5d7259710d0dd5e500d040be" # Address to be used for zkSync account managing the interaction with a contract on Ethereum. # Derived from the `OPERATOR_PRIVATE_KEY`. -operator_commit_eth_addr="0xde03a0B5963f75f1C8485B355fF6D30f3093BDE7" +operator_commit_eth_addr = "0xde03a0B5963f75f1C8485B355fF6D30f3093BDE7" -operator_blobs_private_key="0xe667e57a9b8aaa6709e51ff7d093f1c5b73b63f9987e4ab4aa9a5c699e024ee8" -operator_blobs_eth_addr="0x4F9133D1d3F50011A6859807C837bdCB31Aaab13" +operator_blobs_private_key = "0xe667e57a9b8aaa6709e51ff7d093f1c5b73b63f9987e4ab4aa9a5c699e024ee8" +operator_blobs_eth_addr = "0x4F9133D1d3F50011A6859807C837bdCB31Aaab13" [consensus] config_path = "etc/env/consensus_config.yaml" @@ -22,4 +22,4 @@ secrets_path = "etc/env/consensus_secrets.yaml" [misc] # Private key for the fee seller account -fee_account_private_key="0x27593fea79697e947890ecbecce7901b0008345e5d7259710d0dd5e500d040be" +fee_account_private_key = "0x27593fea79697e947890ecbecce7901b0008345e5d7259710d0dd5e500d040be" diff --git a/etc/env/ext-node.toml b/etc/env/ext-node.toml index b7c728b1791..8ab989e6cf5 100644 --- a/etc/env/ext-node.toml +++ b/etc/env/ext-node.toml @@ -5,7 +5,7 @@ database_url = "postgres://postgres:notsecurepassword@localhost/zksync_local_ext_node" test_database_url = "postgres://postgres:notsecurepassword@localhost:5433/zksync_local_test_ext_node" database_pool_size = 50 -zksync_action="dont_ask" +zksync_action = "dont_ask" [en] http_port = 3060 @@ -29,29 +29,29 @@ api_namespaces = ["eth", "web3", "net", "pubsub", "zks", "en", "debug"] # Note: # `bootloader_hash` and `default_aa_hash` are overridden from the `.init.env` values by `zk` tool. -bootloader_hash="0x0100038581be3d0e201b3cc45d151ef5cc59eb3a0f146ad44f0f72abf00b594c" -default_aa_hash="0x0100038dc66b69be75ec31653c64cb931678299b9b659472772b2550b703f41c" +bootloader_hash = "0x0100038581be3d0e201b3cc45d151ef5cc59eb3a0f146ad44f0f72abf00b594c" +default_aa_hash = "0x0100038dc66b69be75ec31653c64cb931678299b9b659472772b2550b703f41c" # Should be the same as chain.state_keeper.fee_account_addr. -operator_addr="0xde03a0B5963f75f1C8485B355fF6D30f3093BDE7" +operator_addr = "0xde03a0B5963f75f1C8485B355fF6D30f3093BDE7" [en.consensus] -config_path="etc/env/en_consensus_config.yaml" -secrets_path="etc/env/en_consensus_secrets.yaml" +config_path = "etc/env/en_consensus_config.yaml" +secrets_path = "etc/env/en_consensus_secrets.yaml" [en.database] long_connection_threshold_ms = 2000 slow_query_threshold_ms = 100 [en.snapshots.object_store] -mode="FileBacked" -file_backed_base_path="artifacts" +mode = "FileBacked" +file_backed_base_path = "artifacts" # ^ Intentionally set to coincide with main node's in order to read locally produced snapshots [rust] # `RUST_LOG` environment variable for `env_logger` # Here we use TOML multiline strings: newlines will be trimmed. -log="""\ +log = """\ warn,\ zksync_consensus_bft=info,\ zksync_consensus_network=info,\ @@ -72,5 +72,5 @@ zksync_snapshots_applier=debug,\ """ # `RUST_BACKTRACE` variable -backtrace="full" -lib_backtrace="1" +backtrace = "full" +lib_backtrace = "1" diff --git a/infrastructure/zk/src/server.ts b/infrastructure/zk/src/server.ts index aa853bcdc21..859add550f5 100644 --- a/infrastructure/zk/src/server.ts +++ b/infrastructure/zk/src/server.ts @@ -1,6 +1,5 @@ import { Command } from 'commander'; import * as utils from './utils'; -import * as env from './env'; import { clean } from './clean'; import fs from 'fs'; import { unloadInit } from './env'; @@ -51,45 +50,6 @@ export async function externalNode(reinit: boolean = false, args: string[]) { async function create_genesis(cmd: string) { await utils.confirmAction(); await utils.spawn(`${cmd} | tee genesis.log`); - const genesisContents = fs.readFileSync('genesis.log').toString().split('\n'); - const genesisBlockCommitment = genesisContents.find((line) => line.includes('CONTRACTS_GENESIS_BATCH_COMMITMENT=')); - const genesisBootloaderHash = genesisContents.find((line) => line.includes('CHAIN_STATE_KEEPER_BOOTLOADER_HASH=')); - const genesisDefaultAAHash = genesisContents.find((line) => line.includes('CHAIN_STATE_KEEPER_DEFAULT_AA_HASH=')); - const genesisRoot = genesisContents.find((line) => line.includes('CONTRACTS_GENESIS_ROOT=')); - const genesisRollupLeafIndex = genesisContents.find((line) => - line.includes('CONTRACTS_GENESIS_ROLLUP_LEAF_INDEX=') - ); - if (genesisRoot == null || !/^CONTRACTS_GENESIS_ROOT=0x[a-fA-F0-9]{64}$/.test(genesisRoot)) { - throw Error(`Genesis is not needed (either Postgres DB or tree's Rocks DB is not empty)`); - } - - if ( - genesisBootloaderHash == null || - !/^CHAIN_STATE_KEEPER_BOOTLOADER_HASH=0x[a-fA-F0-9]{64}$/.test(genesisBootloaderHash) - ) { - throw Error(`Genesis is not needed (either Postgres DB or tree's Rocks DB is not empty)`); - } - - if ( - genesisDefaultAAHash == null || - !/^CHAIN_STATE_KEEPER_DEFAULT_AA_HASH=0x[a-fA-F0-9]{64}$/.test(genesisDefaultAAHash) - ) { - throw Error(`Genesis is not needed (either Postgres DB or tree's Rocks DB is not empty)`); - } - - if ( - genesisBlockCommitment == null || - !/^CONTRACTS_GENESIS_BATCH_COMMITMENT=0x[a-fA-F0-9]{64}$/.test(genesisBlockCommitment) - ) { - throw Error(`Genesis is not needed (either Postgres DB or tree's Rocks DB is not empty)`); - } - - if ( - genesisRollupLeafIndex == null || - !/^CONTRACTS_GENESIS_ROLLUP_LEAF_INDEX=([1-9]\d*|0)$/.test(genesisRollupLeafIndex) - ) { - throw Error(`Genesis is not needed (either Postgres DB or tree's Rocks DB is not empty)`); - } const date = new Date(); const [year, month, day, hour, minute, second] = [ @@ -103,11 +63,6 @@ async function create_genesis(cmd: string) { const label = `${process.env.ZKSYNC_ENV}-Genesis_gen-${year}-${month}-${day}-${hour}${minute}${second}`; fs.mkdirSync(`logs/${label}`, { recursive: true }); fs.copyFileSync('genesis.log', `logs/${label}/genesis.log`); - env.modify('CONTRACTS_GENESIS_ROOT', genesisRoot); - env.modify('CHAIN_STATE_KEEPER_BOOTLOADER_HASH', genesisBootloaderHash); - env.modify('CHAIN_STATE_KEEPER_DEFAULT_AA_HASH', genesisDefaultAAHash); - env.modify('CONTRACTS_GENESIS_BATCH_COMMITMENT', genesisBlockCommitment); - env.modify('CONTRACTS_GENESIS_ROLLUP_LEAF_INDEX', genesisRollupLeafIndex); } export async function genesisFromSources() {