From 5053b0af158d9202b4da976c2ddf4c0e657825df Mon Sep 17 00:00:00 2001 From: Igor Aleksanov Date: Thu, 4 Jan 2024 17:51:16 +0400 Subject: [PATCH] refactor(metadata_calculator): Move ObjectStore out from MetadataCalculatorConfig (#816) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ title ## Why ❔ - There was some clunky back-and-forth for `MetadataCalculatorModeConfig` <->`MerkleTreeMode` because of the old component confuguration. - ObjectStore may not be available at time when `MetadataCalculatorModeConfig ` is created (prerequisite for ZK Stack thing). - Less code! ## Checklist - [ ] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [ ] Documentation comments have been added / updated. - [ ] Code has been formatted via `zk fmt` and `zk lint`. - [ ] Spellcheck has been run via `cargo spellcheck --cfg=./spellcheck/era.cfg --code 1`. --- core/bin/external_node/src/main.rs | 13 +++-- core/lib/zksync_core/src/lib.rs | 29 +++++------- .../src/metadata_calculator/mod.rs | 41 +++------------- .../src/metadata_calculator/recovery/tests.rs | 5 +- .../src/metadata_calculator/tests.rs | 47 +++++++++---------- 5 files changed, 49 insertions(+), 86 deletions(-) diff --git a/core/bin/external_node/src/main.rs b/core/bin/external_node/src/main.rs index d815619934f..01b3a126080 100644 --- a/core/bin/external_node/src/main.rs +++ b/core/bin/external_node/src/main.rs @@ -7,6 +7,7 @@ use metrics::EN_METRICS; use prometheus_exporter::PrometheusExporterConfig; use tokio::{sync::watch, task, time::sleep}; use zksync_basic_types::{Address, L2ChainId}; +use zksync_config::configs::database::MerkleTreeMode; use zksync_core::{ api_server::{ execution_sandbox::VmConcurrencyLimiter, @@ -17,9 +18,7 @@ use zksync_core::{ block_reverter::{BlockReverter, BlockReverterFlags, L1ExecutedBatchesRevert}, consistency_checker::ConsistencyChecker, l1_gas_price::MainNodeGasPriceFetcher, - metadata_calculator::{ - MetadataCalculator, MetadataCalculatorConfig, MetadataCalculatorModeConfig, - }, + metadata_calculator::{MetadataCalculator, MetadataCalculatorConfig}, reorg_detector::ReorgDetector, setup_sigint_handler, state_keeper::{ @@ -186,17 +185,17 @@ async fn init_tasks( stop_receiver.clone(), ); - let metadata_calculator = MetadataCalculator::new(MetadataCalculatorConfig { + let metadata_calculator_config = MetadataCalculatorConfig { db_path: config.required.merkle_tree_path.clone(), - mode: MetadataCalculatorModeConfig::Full { object_store: None }, + mode: MerkleTreeMode::Full, delay_interval: config.optional.metadata_calculator_delay(), max_l1_batches_per_iter: config.optional.max_l1_batches_per_tree_iter, multi_get_chunk_size: config.optional.merkle_tree_multi_get_chunk_size, block_cache_capacity: config.optional.merkle_tree_block_cache_size(), memtable_capacity: config.optional.merkle_tree_memtable_capacity(), stalled_writes_timeout: config.optional.merkle_tree_stalled_writes_timeout(), - }) - .await; + }; + let metadata_calculator = MetadataCalculator::new(metadata_calculator_config, None).await; healthchecks.push(Box::new(metadata_calculator.tree_health_check())); let consistency_checker = ConsistencyChecker::new( diff --git a/core/lib/zksync_core/src/lib.rs b/core/lib/zksync_core/src/lib.rs index 851b281bf8e..b3a3d2e580e 100644 --- a/core/lib/zksync_core/src/lib.rs +++ b/core/lib/zksync_core/src/lib.rs @@ -19,7 +19,7 @@ use zksync_config::{ StateKeeperConfig, }, contracts::ProverAtGenesis, - database::MerkleTreeMode, + database::{MerkleTreeConfig, MerkleTreeMode}, }, ApiConfig, ContractsConfig, DBConfig, ETHSenderConfig, PostgresConfig, }; @@ -65,9 +65,7 @@ use crate::{ waiting_to_queued_fri_witness_job_mover::WaitingToQueuedFriWitnessJobMover, }, l1_gas_price::{GasAdjusterSingleton, L1GasPriceProvider}, - metadata_calculator::{ - MetadataCalculator, MetadataCalculatorConfig, MetadataCalculatorModeConfig, - }, + metadata_calculator::{MetadataCalculator, MetadataCalculatorConfig}, metrics::{InitStage, APP_METRICS}, state_keeper::{ create_state_keeper, MempoolFetcher, MempoolGuard, MiniblockSealer, SequencerSealer, @@ -768,21 +766,19 @@ async fn add_trees_to_task_futures( .contains(&Component::TreeApi) .then_some(&api_config); - let mode = match db_config.merkle_tree.mode { - MerkleTreeMode::Lightweight => MetadataCalculatorModeConfig::Lightweight, - MerkleTreeMode::Full => MetadataCalculatorModeConfig::Full { - object_store: Some(store_factory.create_store().await), - }, + let object_store = match db_config.merkle_tree.mode { + MerkleTreeMode::Lightweight => None, + MerkleTreeMode::Full => Some(store_factory.create_store().await), }; run_tree( task_futures, healthchecks, &postgres_config, - &db_config, + &db_config.merkle_tree, api_config, &operation_config, - mode, + object_store, stop_receiver, ) .await @@ -794,23 +790,22 @@ async fn run_tree( task_futures: &mut Vec>>, healthchecks: &mut Vec>, postgres_config: &PostgresConfig, - db_config: &DBConfig, + merkle_tree_config: &MerkleTreeConfig, api_config: Option<&MerkleTreeApiConfig>, operation_manager: &OperationsManagerConfig, - mode: MetadataCalculatorModeConfig, + object_store: Option>, stop_receiver: watch::Receiver, ) -> anyhow::Result<()> { let started_at = Instant::now(); - let mode_str = if matches!(mode, MetadataCalculatorModeConfig::Full { .. }) { + let mode_str = if matches!(merkle_tree_config.mode, MerkleTreeMode::Full) { "full" } else { "lightweight" }; tracing::info!("Initializing Merkle tree in {mode_str} mode"); - let config = - MetadataCalculatorConfig::for_main_node(&db_config.merkle_tree, operation_manager, mode); - let metadata_calculator = MetadataCalculator::new(config).await; + let config = MetadataCalculatorConfig::for_main_node(merkle_tree_config, operation_manager); + let metadata_calculator = MetadataCalculator::new(config, object_store).await; if let Some(api_config) = api_config { let address = (Ipv4Addr::UNSPECIFIED, api_config.port).into(); let tree_reader = metadata_calculator.tree_reader(); diff --git a/core/lib/zksync_core/src/metadata_calculator/mod.rs b/core/lib/zksync_core/src/metadata_calculator/mod.rs index c0fb5142eb6..0244094be66 100644 --- a/core/lib/zksync_core/src/metadata_calculator/mod.rs +++ b/core/lib/zksync_core/src/metadata_calculator/mod.rs @@ -36,36 +36,13 @@ mod recovery; pub(crate) mod tests; mod updater; -/// Part of [`MetadataCalculator`] related to the operation mode of the Merkle tree. -#[derive(Debug)] -pub enum MetadataCalculatorModeConfig { - /// In this mode, `MetadataCalculator` computes Merkle tree root hashes and some auxiliary information - /// for L1 batches, but not witness inputs. - Lightweight, - /// In this mode, `MetadataCalculator` will compute commitments and witness inputs for all storage operations - /// and optionally put witness inputs into the object store (e.g., GCS). - Full { - object_store: Option>, - }, -} - -impl MetadataCalculatorModeConfig { - fn to_mode(&self) -> MerkleTreeMode { - if matches!(self, Self::Full { .. }) { - MerkleTreeMode::Full - } else { - MerkleTreeMode::Lightweight - } - } -} - /// Configuration of [`MetadataCalculator`]. #[derive(Debug)] pub struct MetadataCalculatorConfig { /// Filesystem path to the RocksDB instance that stores the tree. pub db_path: String, /// Configuration of the Merkle tree mode. - pub mode: MetadataCalculatorModeConfig, + pub mode: MerkleTreeMode, /// Interval between polling Postgres for updates if no progress was made by the tree. pub delay_interval: Duration, /// Maximum number of L1 batches to get from Postgres on a single update iteration. @@ -86,11 +63,10 @@ impl MetadataCalculatorConfig { pub(crate) fn for_main_node( merkle_tree_config: &MerkleTreeConfig, operation_config: &OperationsManagerConfig, - mode: MetadataCalculatorModeConfig, ) -> Self { Self { db_path: merkle_tree_config.path.clone(), - mode, + mode: merkle_tree_config.mode, delay_interval: operation_config.delay_interval(), max_l1_batches_per_iter: merkle_tree_config.max_l1_batches_per_iter, multi_get_chunk_size: merkle_tree_config.multi_get_chunk_size, @@ -113,18 +89,15 @@ pub struct MetadataCalculator { impl MetadataCalculator { /// Creates a calculator with the specified `config`. - pub async fn new(config: MetadataCalculatorConfig) -> Self { + pub async fn new( + config: MetadataCalculatorConfig, + object_store: Option>, + ) -> Self { assert!( config.max_l1_batches_per_iter > 0, "Maximum L1 batches per iteration is misconfigured to be 0; please update it to positive value" ); - let mode = config.mode.to_mode(); - let object_store = match config.mode { - MetadataCalculatorModeConfig::Full { object_store } => object_store, - MetadataCalculatorModeConfig::Lightweight => None, - }; - let db = create_db( config.db_path.clone().into(), config.block_cache_capacity, @@ -133,7 +106,7 @@ impl MetadataCalculator { config.multi_get_chunk_size, ) .await; - let tree = GenericAsyncTree::new(db, mode).await; + let tree = GenericAsyncTree::new(db, config.mode).await; let (_, health_updater) = ReactiveHealthCheck::new("tree"); Self { 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 082f684bbc9..ee2fc0bb8a7 100644 --- a/core/lib/zksync_core/src/metadata_calculator/recovery/tests.rs +++ b/core/lib/zksync_core/src/metadata_calculator/recovery/tests.rs @@ -27,7 +27,7 @@ use crate::{ extend_db_state, extend_db_state_from_l1_batch, gen_storage_logs, run_calculator, setup_calculator, }, - MetadataCalculator, MetadataCalculatorConfig, MetadataCalculatorModeConfig, + MetadataCalculator, MetadataCalculatorConfig, }, }; @@ -292,9 +292,8 @@ async fn entire_recovery_workflow(case: RecoveryWorkflowCase) { let calculator_config = MetadataCalculatorConfig::for_main_node( &merkle_tree_config, &OperationsManagerConfig { delay_interval: 50 }, - MetadataCalculatorModeConfig::Lightweight, ); - let mut calculator = MetadataCalculator::new(calculator_config).await; + let mut calculator = MetadataCalculator::new(calculator_config, None).await; let (delay_sx, mut delay_rx) = mpsc::unbounded_channel(); calculator.delayer.delay_notifier = delay_sx; diff --git a/core/lib/zksync_core/src/metadata_calculator/tests.rs b/core/lib/zksync_core/src/metadata_calculator/tests.rs index 1a5d2a6d770..b982039dbc5 100644 --- a/core/lib/zksync_core/src/metadata_calculator/tests.rs +++ b/core/lib/zksync_core/src/metadata_calculator/tests.rs @@ -6,7 +6,10 @@ use assert_matches::assert_matches; use itertools::Itertools; use tempfile::TempDir; use tokio::sync::{mpsc, watch}; -use zksync_config::configs::{chain::OperationsManagerConfig, database::MerkleTreeConfig}; +use zksync_config::configs::{ + chain::OperationsManagerConfig, + database::{MerkleTreeConfig, MerkleTreeMode}, +}; use zksync_contracts::BaseSystemContracts; use zksync_dal::{ConnectionPool, StorageProcessor}; use zksync_health_check::{CheckHealth, HealthStatus}; @@ -20,10 +23,7 @@ use zksync_types::{ }; use zksync_utils::u32_to_h256; -use super::{ - GenericAsyncTree, L1BatchWithLogs, MetadataCalculator, MetadataCalculatorConfig, - MetadataCalculatorModeConfig, -}; +use super::{GenericAsyncTree, L1BatchWithLogs, MetadataCalculator, MetadataCalculatorConfig}; use crate::genesis::{ensure_genesis_state, GenesisParams}; const RUN_TIMEOUT: Duration = Duration::from_secs(30); @@ -237,16 +237,12 @@ async fn running_metadata_calculator_with_additional_blocks() { async fn shutting_down_calculator() { let pool = ConnectionPool::test_pool().await; let temp_dir = TempDir::new().expect("failed get temporary directory for RocksDB"); - let (merkle_tree_config, mut operation_config) = create_config(temp_dir.path()); + let (merkle_tree_config, mut operation_config) = + create_config(temp_dir.path(), MerkleTreeMode::Lightweight); operation_config.delay_interval = 30_000; // ms; chosen to be larger than `RUN_TIMEOUT` - let calculator = setup_calculator_with_options( - &merkle_tree_config, - &operation_config, - &pool, - MetadataCalculatorModeConfig::Lightweight, - ) - .await; + let calculator = + setup_calculator_with_options(&merkle_tree_config, &operation_config, &pool, None).await; reset_db_state(&pool, 5).await; @@ -365,24 +361,25 @@ pub(crate) async fn setup_calculator( ) -> (MetadataCalculator, Box) { let store_factory = ObjectStoreFactory::mock(); let store = store_factory.create_store().await; - let (merkle_tree_config, operation_manager) = create_config(db_path); - let mode = MetadataCalculatorModeConfig::Full { - object_store: Some(store), - }; + let (merkle_tree_config, operation_manager) = create_config(db_path, MerkleTreeMode::Full); let calculator = - setup_calculator_with_options(&merkle_tree_config, &operation_manager, pool, mode).await; + setup_calculator_with_options(&merkle_tree_config, &operation_manager, pool, Some(store)) + .await; (calculator, store_factory.create_store().await) } async fn setup_lightweight_calculator(db_path: &Path, pool: &ConnectionPool) -> MetadataCalculator { - let mode = MetadataCalculatorModeConfig::Lightweight; - let (db_config, operation_config) = create_config(db_path); - setup_calculator_with_options(&db_config, &operation_config, pool, mode).await + let (db_config, operation_config) = create_config(db_path, MerkleTreeMode::Lightweight); + setup_calculator_with_options(&db_config, &operation_config, pool, None).await } -fn create_config(db_path: &Path) -> (MerkleTreeConfig, OperationsManagerConfig) { +fn create_config( + db_path: &Path, + mode: MerkleTreeMode, +) -> (MerkleTreeConfig, OperationsManagerConfig) { let db_config = MerkleTreeConfig { path: path_to_string(&db_path.join("new")), + mode, ..MerkleTreeConfig::default() }; @@ -396,11 +393,11 @@ async fn setup_calculator_with_options( merkle_tree_config: &MerkleTreeConfig, operation_config: &OperationsManagerConfig, pool: &ConnectionPool, - mode: MetadataCalculatorModeConfig, + object_store: Option>, ) -> MetadataCalculator { let calculator_config = - MetadataCalculatorConfig::for_main_node(merkle_tree_config, operation_config, mode); - let metadata_calculator = MetadataCalculator::new(calculator_config).await; + MetadataCalculatorConfig::for_main_node(merkle_tree_config, operation_config); + let metadata_calculator = MetadataCalculator::new(calculator_config, object_store).await; let mut storage = pool.access_storage().await.unwrap(); if storage.blocks_dal().is_genesis_needed().await.unwrap() {