Skip to content

Commit 76a80eb

Browse files
authored
refactor: Reverse node framework dependency (#3986)
## What ❔ Refactors node framework as a lower-level dependency for other crates, rather than the other way around. ## Why ❔ - Simplifies maintenance on its own. - Opens room for future improvements, e.g. light structured concurrency for tasks, integration with the config system etc. ## Is this a breaking change? - [ ] Yes - [ ] No ## Operational changes No operational changes. ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [x] Tests for the changes have been added / updated. - [ ] Documentation comments have been added / updated. - [x] Code has been formatted via `zkstack dev fmt` and `zkstack dev lint`.
1 parent 56658c8 commit 76a80eb

File tree

253 files changed

+2460
-2290
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

253 files changed

+2460
-2290
lines changed

core/Cargo.lock

Lines changed: 106 additions & 51 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/Cargo.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ members = [
1414
"bin/genesis_generator",
1515
"bin/zksync_tee_prover",
1616
# Node services
17-
"node/node_framework",
1817
"node/proof_data_handler",
1918
"node/block_reverter",
2019
"node/commitment_generator",
@@ -60,7 +59,9 @@ members = [
6059
"lib/mempool",
6160
"lib/merkle_tree",
6261
"lib/mini_merkle_tree",
62+
"lib/node_framework",
6363
"lib/node_framework_derive",
64+
"lib/shared_resources",
6465
"lib/object_store",
6566
"lib/prover_interface",
6667
"lib/queued_job_processor",
@@ -317,8 +318,9 @@ zksync_task_management = { version = "28.2.0-non-semver-compat", path = "lib/tas
317318
zk_os_merkle_tree = { version = "28.2.0-non-semver-compat", path = "lib/zk_os_merkle_tree" }
318319

319320
# Framework and components
320-
zksync_node_framework = { version = "28.2.0-non-semver-compat", path = "node/node_framework" }
321+
zksync_node_framework = { version = "28.2.0-non-semver-compat", path = "lib/node_framework" }
321322
zksync_node_framework_derive = { version = "28.2.0-non-semver-compat", path = "lib/node_framework_derive" }
323+
zksync_shared_resources = { version = "28.2.0-non-semver-compat", path = "lib/shared_resources" }
322324
zksync_eth_watch = { version = "28.2.0-non-semver-compat", path = "node/eth_watch" }
323325
zksync_shared_metrics = { version = "28.2.0-non-semver-compat", path = "node/shared_metrics" }
324326
zksync_proof_data_handler = { version = "28.2.0-non-semver-compat", path = "node/proof_data_handler" }

core/bin/external_node/Cargo.toml

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,27 @@ publish = false
1414
[dependencies]
1515
zksync_core_leftovers.workspace = true
1616
zksync_commitment_generator.workspace = true
17-
zksync_dal.workspace = true
18-
zksync_db_connection.workspace = true
17+
zksync_dal = { workspace = true, features = ["node_framework"] }
1918
zksync_config.workspace = true
2019
zksync_protobuf_config.workspace = true
2120
zksync_env_config.workspace = true
22-
zksync_eth_client.workspace = true
21+
zksync_eth_client = { workspace = true, features = ["node_framework"] }
2322
zksync_storage.workspace = true
2423
zksync_state.workspace = true
2524
zksync_contracts.workspace = true
2625
zksync_l1_contract_interface.workspace = true
2726
zksync_snapshots_applier.workspace = true
28-
zksync_object_store.workspace = true
29-
zksync_health_check.workspace = true
30-
zksync_web3_decl.workspace = true
27+
zksync_object_store = { workspace = true, features = ["node_framework"] }
28+
zksync_health_check = { workspace = true, features = ["node_framework"] }
29+
zksync_web3_decl = { workspace = true, features = ["node_framework"] }
3130
zksync_types.workspace = true
3231
zksync_block_reverter.workspace = true
32+
zksync_da_clients.workspace = true
33+
zksync_gateway_migrator.workspace = true
34+
zksync_logs_bloom_backfill.workspace = true
3335
zksync_node_genesis.workspace = true
3436
zksync_node_fee_model.workspace = true
37+
zksync_node_storage_init.workspace = true
3538
zksync_node_db_pruner.workspace = true
3639
zksync_eth_sender.workspace = true
3740
zksync_state_keeper.workspace = true
@@ -42,7 +45,7 @@ zksync_node_sync.workspace = true
4245
zksync_node_api_server.workspace = true
4346
zksync_node_consensus.workspace = true
4447
zksync_node_framework.workspace = true
45-
zksync_vlog.workspace = true
48+
zksync_vlog = { workspace = true, features = ["node_framework"] }
4649

4750
zksync_concurrency.workspace = true
4851
zksync_consensus_roles.workspace = true

core/bin/external_node/src/config/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -976,9 +976,9 @@ impl OptionalENConfig {
976976
Duration::from_secs(self.pruning_data_retention_sec)
977977
}
978978

979-
pub fn bridge_addresses_refresh_interval(&self) -> Option<Duration> {
979+
pub fn bridge_addresses_refresh_interval(&self) -> Duration {
980980
self.bridge_addresses_refresh_interval_sec
981-
.map(|n| Duration::from_secs(n.get()))
981+
.map_or_else(|| Duration::from_secs(30), |n| Duration::from_secs(n.get()))
982982
}
983983

984984
#[cfg(test)]

core/bin/external_node/src/metrics/framework.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
use std::time::Duration;
22

3-
use zksync_dal::{ConnectionPool, Core, CoreDal as _};
3+
use zksync_dal::{
4+
node::{MasterPool, PoolResource},
5+
ConnectionPool, Core, CoreDal as _,
6+
};
47
use zksync_node_framework::{
5-
implementations::resources::pools::{MasterPool, PoolResource},
68
FromContext, IntoContext, StopReceiver, Task, TaskId, WiringError, WiringLayer,
79
};
810
use zksync_types::{L1ChainId, L2ChainId, SLChainId};

core/bin/external_node/src/node_builder.rs

Lines changed: 50 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
//! as well as an interface to run the node with the specified components.
33
44
use anyhow::{bail, Context as _};
5-
use zksync_block_reverter::NodeRole;
5+
use zksync_block_reverter::{node::BlockReverterLayer, NodeRole};
6+
use zksync_commitment_generator::node::CommitmentGeneratorLayer;
67
use zksync_config::{
78
configs::{
89
api::{HealthCheckConfig, MerkleTreeApiConfig},
@@ -12,59 +13,45 @@ use zksync_config::{
1213
},
1314
DAClientConfig, PostgresConfig,
1415
};
16+
use zksync_consistency_checker::node::ConsistencyCheckerLayer;
17+
use zksync_da_clients::node::{
18+
AvailWiringLayer, CelestiaWiringLayer, EigenWiringLayer, NoDAClientWiringLayer,
19+
ObjectStorageClientWiringLayer,
20+
};
21+
use zksync_dal::node::{PoolsLayerBuilder, PostgresMetricsLayer};
22+
use zksync_eth_client::node::BridgeAddressesUpdaterLayer;
23+
use zksync_gateway_migrator::node::SettlementLayerData;
24+
use zksync_logs_bloom_backfill::node::LogsBloomBackfillLayer;
1525
use zksync_metadata_calculator::{
26+
node::{MetadataCalculatorLayer, TreeApiClientLayer, TreeApiServerLayer},
1627
MerkleTreeReaderConfig, MetadataCalculatorConfig, MetadataCalculatorRecoveryConfig,
1728
};
18-
use zksync_node_api_server::web3::{state::InternalApiConfigBase, Namespace};
19-
use zksync_node_framework::{
20-
implementations::layers::{
21-
batch_status_updater::BatchStatusUpdaterLayer,
22-
block_reverter::BlockReverterLayer,
23-
commitment_generator::CommitmentGeneratorLayer,
24-
consensus::ExternalNodeConsensusLayer,
25-
consistency_checker::ConsistencyCheckerLayer,
26-
da_clients::{
27-
avail::AvailWiringLayer, celestia::CelestiaWiringLayer, eigen::EigenWiringLayer,
28-
no_da::NoDAClientWiringLayer, object_store::ObjectStorageClientWiringLayer,
29-
},
30-
data_availability_fetcher::DataAvailabilityFetcherLayer,
31-
healtcheck_server::HealthCheckLayer,
32-
logs_bloom_backfill::LogsBloomBackfillLayer,
33-
main_node_client::MainNodeClientLayer,
34-
main_node_fee_params_fetcher::MainNodeFeeParamsFetcherLayer,
35-
metadata_calculator::{MetadataCalculatorLayer, TreeApiServerLayer},
36-
node_storage_init::{
37-
external_node_strategy::{ExternalNodeInitStrategyLayer, SnapshotRecoveryConfig},
38-
NodeStorageInitializerLayer,
39-
},
40-
pools_layer::PoolsLayerBuilder,
41-
postgres::PostgresLayer,
42-
prometheus_exporter::PrometheusExporterLayer,
43-
pruning::PruningLayer,
44-
query_eth_client::QueryEthClientLayer,
45-
reorg_detector::ReorgDetectorLayer,
46-
settlement_layer_client::SettlementLayerClientLayer,
47-
settlement_layer_data,
48-
settlement_layer_data::SettlementLayerData,
49-
sigint::SigintHandlerLayer,
50-
state_keeper::{
51-
external_io::ExternalIOLayer, main_batch_executor::MainBatchExecutorLayer,
52-
output_handler::OutputHandlerLayer, StateKeeperLayer,
53-
},
54-
sync_state_updater::SyncStateUpdaterLayer,
55-
tree_data_fetcher::TreeDataFetcherLayer,
56-
validate_chain_ids::ValidateChainIdsLayer,
57-
web3_api::{
58-
caches::MempoolCacheLayer,
59-
server::{Web3ServerLayer, Web3ServerOptionalConfig},
60-
tree_api_client::TreeApiClientLayer,
61-
tx_sender::{PostgresStorageCachesConfig, TxSenderLayer},
62-
tx_sink::ProxySinkLayer,
63-
},
29+
use zksync_node_api_server::{
30+
node::{
31+
HealthCheckLayer, MempoolCacheLayer, PostgresStorageCachesConfig, ProxySinkLayer,
32+
TxSenderLayer, Web3ServerLayer, Web3ServerOptionalConfig,
6433
},
65-
service::{ZkStackService, ZkStackServiceBuilder},
34+
web3::{state::InternalApiConfigBase, Namespace},
35+
};
36+
use zksync_node_consensus::node::ExternalNodeConsensusLayer;
37+
use zksync_node_db_pruner::node::PruningLayer;
38+
use zksync_node_fee_model::node::MainNodeFeeParamsFetcherLayer;
39+
use zksync_node_framework::service::{ZkStackService, ZkStackServiceBuilder};
40+
use zksync_node_storage_init::{
41+
node::{external_node_strategy::ExternalNodeInitStrategyLayer, NodeStorageInitializerLayer},
42+
SnapshotRecoveryConfig,
6643
};
44+
use zksync_node_sync::node::{
45+
BatchStatusUpdaterLayer, DataAvailabilityFetcherLayer, ExternalIOLayer, SyncStateUpdaterLayer,
46+
TreeDataFetcherLayer, ValidateChainIdsLayer,
47+
};
48+
use zksync_reorg_detector::node::ReorgDetectorLayer;
6749
use zksync_state::RocksdbStorageOptions;
50+
use zksync_state_keeper::node::{MainBatchExecutorLayer, OutputHandlerLayer, StateKeeperLayer};
51+
use zksync_vlog::node::{PrometheusExporterLayer, SigintHandlerLayer};
52+
use zksync_web3_decl::node::{
53+
MainNodeClientLayer, QueryEthClientLayer, SettlementLayerClientLayer,
54+
};
6855

6956
use crate::{config::ExternalNodeConfig, metrics::framework::ExternalNodeMetricsLayer, Component};
7057

@@ -131,7 +118,7 @@ impl ExternalNodeBuilder {
131118
}
132119

133120
fn add_postgres_layer(mut self) -> anyhow::Result<Self> {
134-
self.node.add_layer(PostgresLayer);
121+
self.node.add_layer(PostgresMetricsLayer);
135122
Ok(self)
136123
}
137124

@@ -150,14 +137,15 @@ impl ExternalNodeBuilder {
150137
}
151138

152139
fn add_settlement_layer_data(mut self) -> anyhow::Result<Self> {
153-
self.node
154-
.add_layer(SettlementLayerData::new(settlement_layer_data::ENConfig {
140+
self.node.add_layer(SettlementLayerData::new(
141+
zksync_gateway_migrator::node::ENConfig {
155142
l1_specific_contracts: self.config.l1_specific_contracts(),
156143
l1_chain_contracts: self.config.l1_settelment_contracts(),
157144
l2_contracts: self.config.l2_contracts(),
158145
chain_id: self.config.required.l2_chain_id,
159146
gateway_rpc_url: self.config.optional.gateway_url.clone(),
160-
}));
147+
},
148+
));
161149
Ok(self)
162150
}
163151

@@ -315,8 +303,7 @@ impl ExternalNodeBuilder {
315303
}
316304

317305
fn add_batch_status_updater_layer(mut self) -> anyhow::Result<Self> {
318-
let layer = BatchStatusUpdaterLayer;
319-
self.node.add_layer(layer);
306+
self.node.add_layer(BatchStatusUpdaterLayer);
320307
Ok(self)
321308
}
322309

@@ -365,7 +352,6 @@ impl ExternalNodeBuilder {
365352

366353
fn add_data_availability_fetcher_layer(mut self) -> anyhow::Result<Self> {
367354
self.node.add_layer(DataAvailabilityFetcherLayer);
368-
369355
Ok(self)
370356
}
371357

@@ -506,6 +492,13 @@ impl ExternalNodeBuilder {
506492
Ok(self)
507493
}
508494

495+
fn add_bridge_addresses_updater_layer(mut self) -> anyhow::Result<Self> {
496+
self.node.add_layer(BridgeAddressesUpdaterLayer {
497+
refresh_interval: self.config.optional.bridge_addresses_refresh_interval(),
498+
});
499+
Ok(self)
500+
}
501+
509502
fn web3_api_optional_config(&self) -> Web3ServerOptionalConfig {
510503
// The refresh interval should be several times lower than the pruning removal delay, so that
511504
// soft-pruning will timely propagate to the API server.
@@ -519,10 +512,6 @@ impl ExternalNodeBuilder {
519512
response_body_size_limit: Some(self.config.optional.max_response_body_size()),
520513
with_extended_tracing: self.config.optional.extended_rpc_tracing,
521514
pruning_info_refresh_interval: Some(pruning_info_refresh_interval),
522-
bridge_addresses_refresh_interval: self
523-
.config
524-
.optional
525-
.bridge_addresses_refresh_interval(),
526515
polling_interval: Some(self.config.optional.polling_interval()),
527516
websocket_requests_per_minute_limit: None, // To be set by WS server layer method if required.
528517
replication_lag_limit: None, // TODO: Support replication lag limit
@@ -661,6 +650,7 @@ impl ExternalNodeBuilder {
661650
Component::HttpApi => {
662651
self = self
663652
.add_sync_state_updater_layer()?
653+
.add_bridge_addresses_updater_layer()?
664654
.add_mempool_cache_layer()?
665655
.add_tree_api_client_layer()?
666656
.add_main_node_fee_params_fetcher_layer()?
@@ -670,6 +660,7 @@ impl ExternalNodeBuilder {
670660
Component::WsApi => {
671661
self = self
672662
.add_sync_state_updater_layer()?
663+
.add_bridge_addresses_updater_layer()?
673664
.add_mempool_cache_layer()?
674665
.add_tree_api_client_layer()?
675666
.add_main_node_fee_params_fetcher_layer()?

core/bin/external_node/src/tests/framework.rs

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,20 @@
11
use std::sync::Arc;
22

33
use tokio::sync::oneshot;
4-
use zksync_health_check::AppHealthCheck;
4+
use zksync_health_check::{node::AppHealthCheckResource, AppHealthCheck};
55
use zksync_node_framework::{
6-
implementations::{
7-
layers::{
8-
main_node_client::MainNodeClientLayer, query_eth_client::QueryEthClientLayer,
9-
settlement_layer_client::SettlementLayerClientLayer, sigint::SigintHandlerLayer,
10-
},
11-
resources::{
12-
eth_interface::{
13-
EthInterfaceResource, SettlementLayerClient, SettlementLayerClientResource,
14-
},
15-
healthcheck::AppHealthCheckResource,
16-
main_node_client::MainNodeClientResource,
17-
},
18-
},
19-
service::ServiceContext,
20-
task::TaskKind,
21-
FromContext, IntoContext, StopReceiver, Task, TaskId, WiringError, WiringLayer,
6+
service::ServiceContext, task::TaskKind, FromContext, IntoContext, StopReceiver, Task, TaskId,
7+
WiringError, WiringLayer,
228
};
239
use zksync_types::{L1ChainId, L2ChainId};
24-
use zksync_web3_decl::client::{MockClient, L1, L2};
10+
use zksync_vlog::node::SigintHandlerLayer;
11+
use zksync_web3_decl::{
12+
client::{MockClient, L1, L2},
13+
node::{
14+
EthInterfaceResource, MainNodeClientLayer, MainNodeClientResource, QueryEthClientLayer,
15+
SettlementLayerClient, SettlementLayerClientLayer,
16+
},
17+
};
2518

2619
use super::ExternalNodeBuilder;
2720

@@ -174,16 +167,14 @@ struct MockSettlementLayerClientLayer {
174167
#[async_trait::async_trait]
175168
impl WiringLayer for MockSettlementLayerClientLayer {
176169
type Input = ();
177-
type Output = SettlementLayerClientResource;
170+
type Output = SettlementLayerClient;
178171

179172
fn layer_name(&self) -> &'static str {
180173
// We don't care about values, we just want to hijack the layer name.
181174
SettlementLayerClientLayer::new("https://example.com".parse().unwrap(), None).layer_name()
182175
}
183176

184177
async fn wire(self, _: Self::Input) -> Result<Self::Output, WiringError> {
185-
Ok(SettlementLayerClientResource(SettlementLayerClient::L1(
186-
Box::new(self.client),
187-
)))
178+
Ok(SettlementLayerClient::L1(Box::new(self.client)))
188179
}
189180
}

core/bin/external_node/src/tests/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ async fn external_node_basics(components_str: &'static str) {
5252
);
5353

5454
let node = node.build(env.components.0.into_iter().collect())?;
55-
node.run(None)?;
55+
node.run(())?;
5656
anyhow::Ok(())
5757
})
5858
.join()
@@ -124,7 +124,7 @@ async fn node_reacts_to_stop_signal_during_initial_reorg_detection() {
124124
);
125125

126126
let node = node.build(env.components.0.into_iter().collect())?;
127-
node.run(None)?;
127+
node.run(())?;
128128
anyhow::Ok(())
129129
})
130130
.join()

core/bin/external_node/src/tests/utils.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ use std::sync::Arc;
22

33
use tempfile::TempDir;
44
use tokio::sync::oneshot;
5-
use zksync_dal::{ConnectionPoolBuilder, Core, CoreDal};
6-
use zksync_db_connection::connection_pool::TestTemplate;
5+
use zksync_dal::{ConnectionPool, CoreDal};
76
use zksync_eth_client::clients::MockSettlementLayer;
87
use zksync_health_check::AppHealthCheck;
98
use zksync_node_genesis::{insert_genesis_batch, GenesisBatchParams, GenesisParams};
@@ -56,10 +55,7 @@ impl TestEnvironment {
5655

5756
// Simplest case to mock: the EN already has a genesis L1 batch / L2 block, and it's the only L1 batch / L2 block
5857
// in the network.
59-
let test_db: ConnectionPoolBuilder<Core> =
60-
TestTemplate::empty().unwrap().create_db(100).await.unwrap();
61-
let connection_pool = test_db.build().await.unwrap();
62-
// let singleton_pool_builder = ConnectionPool::singleton(connection_pool.database_url().clone());
58+
let connection_pool = ConnectionPool::test_pool().await;
6359
let mut storage = connection_pool.connection().await.unwrap();
6460
let genesis_params = insert_genesis_batch(&mut storage, &GenesisParams::mock())
6561
.await

0 commit comments

Comments
 (0)