Skip to content

Commit

Permalink
fix(en): Return SyncState health check (#3142)
Browse files Browse the repository at this point in the history
## What ❔

Returns `SyncState`-based health check, which was removed when
transitioning to the node framework.

## Why ❔

This health check looks useful and is used at least in some internal
automations.

## 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.
- [x] Documentation comments have been added / updated.
- [x] Code has been formatted via `zkstack dev fmt` and `zkstack dev
lint`.
  • Loading branch information
slowli authored Oct 22, 2024
1 parent 7241ae1 commit abeee81
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 3 deletions.
14 changes: 11 additions & 3 deletions core/bin/external_node/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,18 @@ const POLL_INTERVAL: Duration = Duration::from_millis(100);
#[tracing::instrument] // Add args to the test logs
async fn external_node_basics(components_str: &'static str) {
let _guard = zksync_vlog::ObservabilityBuilder::new().try_build().ok(); // Enable logging to simplify debugging

let (env, env_handles) = utils::TestEnvironment::with_genesis_block(components_str).await;

let expected_health_components = utils::expected_health_components(&env.components);
let mut expected_health_components = utils::expected_health_components(&env.components);
let expected_shutdown_components = expected_health_components.clone();
let has_core_or_api = env.components.0.iter().any(|component| {
[Component::Core, Component::HttpApi, Component::WsApi].contains(component)
});
if has_core_or_api {
// The `sync_state` component doesn't signal its shutdown, but should be present in the list of components
expected_health_components.push("sync_state");
}

let l2_client = utils::mock_l2_client(&env);
let eth_client = utils::mock_eth_client(env.config.diamond_proxy_address());

Expand Down Expand Up @@ -84,7 +92,7 @@ async fn external_node_basics(components_str: &'static str) {
let health_data = app_health.check_health().await;
tracing::info!(?health_data, "final health data");
assert_matches!(health_data.inner().status(), HealthStatus::ShutDown);
for name in expected_health_components {
for name in expected_shutdown_components {
let component_health = &health_data.components()[name];
assert_matches!(component_health.status(), HealthStatus::ShutDown);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use zksync_types::L2ChainId;
use crate::{
implementations::resources::{
action_queue::ActionQueueSenderResource,
healthcheck::AppHealthCheckResource,
main_node_client::MainNodeClientResource,
pools::{MasterPool, PoolResource},
state_keeper::{ConditionalSealerResource, StateKeeperIOResource},
Expand All @@ -26,6 +27,7 @@ pub struct ExternalIOLayer {
#[derive(Debug, FromContext)]
#[context(crate = crate)]
pub struct Input {
pub app_health: AppHealthCheckResource,
pub pool: PoolResource<MasterPool>,
pub main_node_client: MainNodeClientResource,
}
Expand Down Expand Up @@ -57,6 +59,10 @@ impl WiringLayer for ExternalIOLayer {
async fn wire(self, input: Self::Input) -> Result<Self::Output, WiringError> {
// Create `SyncState` resource.
let sync_state = SyncState::default();
let app_health = &input.app_health.0;
app_health
.insert_custom_component(Arc::new(sync_state.clone()))
.map_err(WiringError::internal)?;

// Create `ActionQueueSender` resource.
let (action_queue_sender, action_queue) = ActionQueue::new();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use std::sync::Arc;

use zksync_dal::{ConnectionPool, Core};
use zksync_node_sync::SyncState;
use zksync_web3_decl::client::{DynClient, L2};

use crate::{
implementations::resources::{
healthcheck::AppHealthCheckResource,
main_node_client::MainNodeClientResource,
pools::{MasterPool, PoolResource},
sync_state::SyncStateResource,
Expand All @@ -24,6 +27,7 @@ pub struct SyncStateUpdaterLayer;
pub struct Input {
/// Fetched to check whether the `SyncState` was already provided by another layer.
pub sync_state: Option<SyncStateResource>,
pub app_health: AppHealthCheckResource,
pub master_pool: PoolResource<MasterPool>,
pub main_node_client: MainNodeClientResource,
}
Expand Down Expand Up @@ -62,6 +66,10 @@ impl WiringLayer for SyncStateUpdaterLayer {
let MainNodeClientResource(main_node_client) = input.main_node_client;

let sync_state = SyncState::default();
let app_health = &input.app_health.0;
app_health
.insert_custom_component(Arc::new(sync_state.clone()))
.map_err(WiringError::internal)?;

Ok(Output {
sync_state: Some(sync_state.clone().into()),
Expand Down
1 change: 1 addition & 0 deletions core/node/node_sync/src/sync_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ impl CheckHealth for SyncState {
Health::from(&*self.0.borrow())
}
}

impl SyncStateInner {
fn is_synced(&self) -> (bool, Option<u32>) {
if let (Some(main_node_block), Some(local_block)) = (self.main_node_block, self.local_block)
Expand Down

0 comments on commit abeee81

Please sign in to comment.