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
  }
}
```
This commit is contained in:
Mac L 2022-12-01 06:03:53 +00:00
parent 22115049ee
commit 18c9be595d
3 changed files with 107 additions and 0 deletions

View File

@ -17,6 +17,7 @@ mod proposer_duties;
mod publish_blocks; mod publish_blocks;
mod state_id; mod state_id;
mod sync_committees; mod sync_committees;
mod ui;
mod validator_inclusion; mod validator_inclusion;
mod version; mod version;
@ -2886,6 +2887,18 @@ pub fn serve<T: BeaconChainTypes>(
}, },
); );
// 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<BeaconChain<T>>| {
blocking_json_task(move || {
ui::get_validator_count(chain).map(api_types::GenericResponse::from)
})
});
// GET lighthouse/syncing // GET lighthouse/syncing
let get_lighthouse_syncing = warp::path("lighthouse") let get_lighthouse_syncing = warp::path("lighthouse")
.and(warp::path("syncing")) .and(warp::path("syncing"))
@ -3353,6 +3366,7 @@ pub fn serve<T: BeaconChainTypes>(
.or(get_lighthouse_attestation_performance.boxed()) .or(get_lighthouse_attestation_performance.boxed())
.or(get_lighthouse_block_packing_efficiency.boxed()) .or(get_lighthouse_block_packing_efficiency.boxed())
.or(get_lighthouse_merge_readiness.boxed()) .or(get_lighthouse_merge_readiness.boxed())
.or(get_lighthouse_ui_validator_count.boxed())
.or(get_events.boxed()), .or(get_events.boxed()),
) )
.boxed() .boxed()

View File

@ -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<T: BeaconChainTypes>(
chain: Arc<BeaconChain<T>>,
) -> Result<ValidatorCountResponse, warp::Rejection> {
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,
})
}

View File

@ -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` ### `/lighthouse/syncing`
```bash ```bash