From 18c9be595dbeca3ba9528a907939d2d00b81a9d4 Mon Sep 17 00:00:00 2001 From: Mac L Date: Thu, 1 Dec 2022 06:03:53 +0000 Subject: [PATCH] Add API endpoint to count statuses of all validators (#3756) ## Issue Addressed #3724 ## Proposed Changes Adds an endpoint to quickly count the number of occurances of each status in the validator set. ## Usage ```bash curl -X GET "http://localhost:5052/lighthouse/ui/validator_count" -H "accept: application/json" | jq ``` ```json { "data": { "active_ongoing":479508, "active_exiting":0, "active_slashed":0, "pending_initialized":28, "pending_queued":0, "withdrawal_possible":933, "withdrawal_done":0, "exited_unslashed":0, "exited_slashed":3 } } ``` --- beacon_node/http_api/src/lib.rs | 14 +++++++ beacon_node/http_api/src/ui.rs | 71 +++++++++++++++++++++++++++++++++ book/src/api-lighthouse.md | 22 ++++++++++ 3 files changed, 107 insertions(+) create mode 100644 beacon_node/http_api/src/ui.rs diff --git a/beacon_node/http_api/src/lib.rs b/beacon_node/http_api/src/lib.rs index 7f6852f36..645c4ccfa 100644 --- a/beacon_node/http_api/src/lib.rs +++ b/beacon_node/http_api/src/lib.rs @@ -17,6 +17,7 @@ mod proposer_duties; mod publish_blocks; mod state_id; mod sync_committees; +mod ui; mod validator_inclusion; mod version; @@ -2886,6 +2887,18 @@ pub fn serve( }, ); + // GET lighthouse/ui/validator_count + let get_lighthouse_ui_validator_count = warp::path("lighthouse") + .and(warp::path("ui")) + .and(warp::path("validator_count")) + .and(warp::path::end()) + .and(chain_filter.clone()) + .and_then(|chain: Arc>| { + blocking_json_task(move || { + ui::get_validator_count(chain).map(api_types::GenericResponse::from) + }) + }); + // GET lighthouse/syncing let get_lighthouse_syncing = warp::path("lighthouse") .and(warp::path("syncing")) @@ -3353,6 +3366,7 @@ pub fn serve( .or(get_lighthouse_attestation_performance.boxed()) .or(get_lighthouse_block_packing_efficiency.boxed()) .or(get_lighthouse_merge_readiness.boxed()) + .or(get_lighthouse_ui_validator_count.boxed()) .or(get_events.boxed()), ) .boxed() diff --git a/beacon_node/http_api/src/ui.rs b/beacon_node/http_api/src/ui.rs new file mode 100644 index 000000000..8f9400dbb --- /dev/null +++ b/beacon_node/http_api/src/ui.rs @@ -0,0 +1,71 @@ +use beacon_chain::{BeaconChain, BeaconChainError, BeaconChainTypes}; +use eth2::types::ValidatorStatus; +use serde::{Deserialize, Serialize}; +use std::sync::Arc; +use warp_utils::reject::beacon_chain_error; + +#[derive(Debug, Default, PartialEq, Clone, Serialize, Deserialize)] +pub struct ValidatorCountResponse { + pub active_ongoing: u64, + pub active_exiting: u64, + pub active_slashed: u64, + pub pending_initialized: u64, + pub pending_queued: u64, + pub withdrawal_possible: u64, + pub withdrawal_done: u64, + pub exited_unslashed: u64, + pub exited_slashed: u64, +} + +pub fn get_validator_count( + chain: Arc>, +) -> Result { + let spec = &chain.spec; + let mut active_ongoing = 0; + let mut active_exiting = 0; + let mut active_slashed = 0; + let mut pending_initialized = 0; + let mut pending_queued = 0; + let mut withdrawal_possible = 0; + let mut withdrawal_done = 0; + let mut exited_unslashed = 0; + let mut exited_slashed = 0; + + chain + .with_head(|head| { + let state = &head.beacon_state; + let epoch = state.current_epoch(); + for validator in state.validators() { + let status = + ValidatorStatus::from_validator(validator, epoch, spec.far_future_epoch); + + match status { + ValidatorStatus::ActiveOngoing => active_ongoing += 1, + ValidatorStatus::ActiveExiting => active_exiting += 1, + ValidatorStatus::ActiveSlashed => active_slashed += 1, + ValidatorStatus::PendingInitialized => pending_initialized += 1, + ValidatorStatus::PendingQueued => pending_queued += 1, + ValidatorStatus::WithdrawalPossible => withdrawal_possible += 1, + ValidatorStatus::WithdrawalDone => withdrawal_done += 1, + ValidatorStatus::ExitedUnslashed => exited_unslashed += 1, + ValidatorStatus::ExitedSlashed => exited_slashed += 1, + // Since we are not invoking `superset`, all other variants will be 0. + _ => (), + } + } + Ok::<(), BeaconChainError>(()) + }) + .map_err(beacon_chain_error)?; + + Ok(ValidatorCountResponse { + active_ongoing, + active_exiting, + active_slashed, + pending_initialized, + pending_queued, + withdrawal_possible, + withdrawal_done, + exited_unslashed, + exited_slashed, + }) +} diff --git a/book/src/api-lighthouse.md b/book/src/api-lighthouse.md index c1ba6a2dc..763372692 100644 --- a/book/src/api-lighthouse.md +++ b/book/src/api-lighthouse.md @@ -99,6 +99,28 @@ curl -X GET "http://localhost:5052/lighthouse/ui/health" -H "accept: applicatio } ``` +### `/lighthouse/ui/validator_count` + +```bash +curl -X GET "http://localhost:5052/lighthouse/ui/validator_count" -H "accept: application/json" | jq +``` + +```json +{ + "data": { + "active_ongoing":479508, + "active_exiting":0, + "active_slashed":0, + "pending_initialized":28, + "pending_queued":0, + "withdrawal_possible":933, + "withdrawal_done":0, + "exited_unslashed":0, + "exited_slashed":3 + } +} +``` + ### `/lighthouse/syncing` ```bash