2019-12-19 00:45:28 +00:00
|
|
|
use crate::helpers::*;
|
|
|
|
use crate::response_builder::ResponseBuilder;
|
2020-05-17 11:16:48 +00:00
|
|
|
use crate::{ApiError, ApiResult, UrlQuery};
|
2019-12-19 00:45:28 +00:00
|
|
|
use beacon_chain::{BeaconChain, BeaconChainTypes};
|
|
|
|
use hyper::{Body, Request};
|
2020-04-08 06:46:37 +00:00
|
|
|
use rest_types::{IndividualVotesRequest, IndividualVotesResponse};
|
2019-12-19 00:45:28 +00:00
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use ssz_derive::{Decode, Encode};
|
2020-04-08 06:46:37 +00:00
|
|
|
use state_processing::per_epoch_processing::{TotalBalances, ValidatorStatuses};
|
2019-12-19 00:45:28 +00:00
|
|
|
use std::sync::Arc;
|
2020-04-08 06:46:37 +00:00
|
|
|
use types::EthSpec;
|
2019-12-19 00:45:28 +00:00
|
|
|
|
|
|
|
/// The results of validators voting during an epoch.
|
|
|
|
///
|
|
|
|
/// Provides information about the current and previous epochs.
|
|
|
|
#[derive(Serialize, Deserialize, Encode, Decode)]
|
|
|
|
pub struct VoteCount {
|
|
|
|
/// The total effective balance of all active validators during the _current_ epoch.
|
|
|
|
pub current_epoch_active_gwei: u64,
|
|
|
|
/// The total effective balance of all active validators during the _previous_ epoch.
|
|
|
|
pub previous_epoch_active_gwei: u64,
|
|
|
|
/// The total effective balance of all validators who attested during the _current_ epoch.
|
|
|
|
pub current_epoch_attesting_gwei: u64,
|
|
|
|
/// The total effective balance of all validators who attested during the _current_ epoch and
|
|
|
|
/// agreed with the state about the beacon block at the first slot of the _current_ epoch.
|
|
|
|
pub current_epoch_target_attesting_gwei: u64,
|
|
|
|
/// The total effective balance of all validators who attested during the _previous_ epoch.
|
|
|
|
pub previous_epoch_attesting_gwei: u64,
|
|
|
|
/// The total effective balance of all validators who attested during the _previous_ epoch and
|
|
|
|
/// agreed with the state about the beacon block at the first slot of the _previous_ epoch.
|
|
|
|
pub previous_epoch_target_attesting_gwei: u64,
|
|
|
|
/// The total effective balance of all validators who attested during the _previous_ epoch and
|
|
|
|
/// agreed with the state about the beacon block at the time of attestation.
|
|
|
|
pub previous_epoch_head_attesting_gwei: u64,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Into<VoteCount> for TotalBalances {
|
|
|
|
fn into(self) -> VoteCount {
|
|
|
|
VoteCount {
|
2020-04-01 11:03:03 +00:00
|
|
|
current_epoch_active_gwei: self.current_epoch(),
|
|
|
|
previous_epoch_active_gwei: self.previous_epoch(),
|
|
|
|
current_epoch_attesting_gwei: self.current_epoch_attesters(),
|
|
|
|
current_epoch_target_attesting_gwei: self.current_epoch_target_attesters(),
|
|
|
|
previous_epoch_attesting_gwei: self.previous_epoch_attesters(),
|
|
|
|
previous_epoch_target_attesting_gwei: self.previous_epoch_target_attesters(),
|
|
|
|
previous_epoch_head_attesting_gwei: self.previous_epoch_head_attesters(),
|
2019-12-19 00:45:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// HTTP handler return a `VoteCount` for some given `Epoch`.
|
|
|
|
pub fn get_vote_count<T: BeaconChainTypes>(
|
|
|
|
req: Request<Body>,
|
|
|
|
beacon_chain: Arc<BeaconChain<T>>,
|
|
|
|
) -> ApiResult {
|
|
|
|
let query = UrlQuery::from_request(&req)?;
|
|
|
|
|
|
|
|
let epoch = query.epoch()?;
|
|
|
|
// This is the last slot of the given epoch (one prior to the first slot of the next epoch).
|
|
|
|
let target_slot = (epoch + 1).start_slot(T::EthSpec::slots_per_epoch()) - 1;
|
|
|
|
|
|
|
|
let (_root, state) = state_at_slot(&beacon_chain, target_slot)?;
|
|
|
|
let spec = &beacon_chain.spec;
|
|
|
|
|
|
|
|
let mut validator_statuses = ValidatorStatuses::new(&state, spec)?;
|
|
|
|
validator_statuses.process_attestations(&state, spec)?;
|
|
|
|
|
|
|
|
let report: VoteCount = validator_statuses.total_balances.into();
|
|
|
|
|
|
|
|
ResponseBuilder::new(&req)?.body(&report)
|
|
|
|
}
|
|
|
|
|
2020-05-17 11:16:48 +00:00
|
|
|
pub async fn post_individual_votes<T: BeaconChainTypes>(
|
2019-12-19 00:45:28 +00:00
|
|
|
req: Request<Body>,
|
|
|
|
beacon_chain: Arc<BeaconChain<T>>,
|
2020-05-17 11:16:48 +00:00
|
|
|
) -> ApiResult {
|
2019-12-19 00:45:28 +00:00
|
|
|
let response_builder = ResponseBuilder::new(&req);
|
|
|
|
|
2020-05-17 11:16:48 +00:00
|
|
|
let body = req.into_body();
|
|
|
|
let chunks = hyper::body::to_bytes(body)
|
|
|
|
.await
|
|
|
|
.map_err(|e| ApiError::ServerError(format!("Unable to get request body: {:?}", e)))?;
|
|
|
|
|
|
|
|
serde_json::from_slice::<IndividualVotesRequest>(&chunks)
|
|
|
|
.map_err(|e| {
|
|
|
|
ApiError::BadRequest(format!(
|
|
|
|
"Unable to parse JSON into ValidatorDutiesRequest: {:?}",
|
|
|
|
e
|
|
|
|
))
|
2019-12-19 00:45:28 +00:00
|
|
|
})
|
|
|
|
.and_then(move |body| {
|
|
|
|
let epoch = body.epoch;
|
|
|
|
|
|
|
|
// This is the last slot of the given epoch (one prior to the first slot of the next epoch).
|
|
|
|
let target_slot = (epoch + 1).start_slot(T::EthSpec::slots_per_epoch()) - 1;
|
|
|
|
|
2020-04-01 06:39:28 +00:00
|
|
|
let (_root, mut state) = state_at_slot(&beacon_chain, target_slot)?;
|
2019-12-19 00:45:28 +00:00
|
|
|
let spec = &beacon_chain.spec;
|
|
|
|
|
|
|
|
let mut validator_statuses = ValidatorStatuses::new(&state, spec)?;
|
|
|
|
validator_statuses.process_attestations(&state, spec)?;
|
|
|
|
|
2020-04-01 06:39:28 +00:00
|
|
|
state.update_pubkey_cache().map_err(|e| {
|
|
|
|
ApiError::ServerError(format!("Unable to build pubkey cache: {:?}", e))
|
|
|
|
})?;
|
|
|
|
|
2019-12-19 00:45:28 +00:00
|
|
|
body.pubkeys
|
|
|
|
.into_iter()
|
|
|
|
.map(|pubkey| {
|
|
|
|
let validator_index_opt = state.get_validator_index(&pubkey).map_err(|e| {
|
|
|
|
ApiError::ServerError(format!("Unable to read pubkey cache: {:?}", e))
|
|
|
|
})?;
|
|
|
|
|
|
|
|
if let Some(validator_index) = validator_index_opt {
|
|
|
|
let vote = validator_statuses
|
|
|
|
.statuses
|
|
|
|
.get(validator_index)
|
|
|
|
.cloned()
|
|
|
|
.map(Into::into);
|
|
|
|
|
|
|
|
Ok(IndividualVotesResponse {
|
|
|
|
epoch,
|
|
|
|
pubkey,
|
|
|
|
validator_index: Some(validator_index),
|
|
|
|
vote,
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
Ok(IndividualVotesResponse {
|
|
|
|
epoch,
|
|
|
|
pubkey,
|
|
|
|
validator_index: None,
|
|
|
|
vote: None,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.collect::<Result<Vec<_>, _>>()
|
|
|
|
})
|
2020-05-17 11:16:48 +00:00
|
|
|
.and_then(|votes| response_builder?.body_no_ssz(&votes))
|
2019-12-19 00:45:28 +00:00
|
|
|
}
|