mirror of
https://github.com/sigp/lighthouse.git
synced 2026-07-03 12:54:27 +00:00
Extended API
- Added a /beacon/validators function, to list all validators active in a particular epoch - Moved 'get_genesis_state' function, to align with router. - Added content-type for error responses - Tried adding a cache update call to fix issue getting validator duties (this is WIP)
This commit is contained in:
@@ -6,7 +6,7 @@ use serde::Serialize;
|
|||||||
use ssz_derive::Encode;
|
use ssz_derive::Encode;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use store::Store;
|
use store::Store;
|
||||||
use types::{BeaconBlock, BeaconState, EthSpec, Hash256, Slot};
|
use types::{BeaconBlock, BeaconState, Epoch, EthSpec, Hash256, Slot};
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
pub struct HeadResponse {
|
pub struct HeadResponse {
|
||||||
@@ -136,16 +136,47 @@ pub fn get_fork<T: BeaconChainTypes + 'static>(req: Request<Body>) -> ApiResult
|
|||||||
Ok(success_response(Body::from(json)))
|
Ok(success_response(Body::from(json)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// HTTP handler to return a `BeaconState` at a given `root` or `slot`.
|
/// HTTP handler to return the set of validators for an `Epoch`
|
||||||
///
|
///
|
||||||
/// Will not return a state if the request slot is in the future. Will return states higher than
|
/// The `Epoch` parameter can be any epoch number. If it is not specified,
|
||||||
/// the current head by skipping slots.
|
/// the current epoch is assumed.
|
||||||
pub fn get_genesis_state<T: BeaconChainTypes + 'static>(req: Request<Body>) -> ApiResult {
|
pub fn get_validators<T: BeaconChainTypes + 'static>(req: Request<Body>) -> ApiResult {
|
||||||
let beacon_chain = get_beacon_chain_from_request::<T>(&req)?;
|
let beacon_chain = get_beacon_chain_from_request::<T>(&req)?;
|
||||||
|
|
||||||
let (_root, state) = state_at_slot(&beacon_chain, Slot::new(0))?;
|
let epoch = match UrlQuery::from_request(&req) {
|
||||||
|
// We have some parameters, so make sure it's the epoch one and parse it
|
||||||
|
Ok(query) => query
|
||||||
|
.only_one("epoch")?
|
||||||
|
.parse::<u64>()
|
||||||
|
.map(Epoch::from)
|
||||||
|
.map_err(|e| {
|
||||||
|
ApiError::InvalidQueryParams(format!(
|
||||||
|
"Invalid epoch parameter, must be a u64. {:?}",
|
||||||
|
e
|
||||||
|
))
|
||||||
|
})?,
|
||||||
|
// In this case, our url query did not contain any parameters, so we take the default
|
||||||
|
Err(_) => beacon_chain.epoch().map_err(|e| {
|
||||||
|
ApiError::ServerError(format!("Unable to determine current epoch: {:?}", e))
|
||||||
|
})?,
|
||||||
|
};
|
||||||
|
|
||||||
ResponseBuilder::new(&req).body(&state)
|
let all_validators = &beacon_chain.head().beacon_state.validators;
|
||||||
|
let mut active_validators = Vec::with_capacity(all_validators.len());
|
||||||
|
for (_index, validator) in all_validators.iter().enumerate() {
|
||||||
|
if validator.is_active_at(epoch) {
|
||||||
|
active_validators.push(validator)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
active_validators.shrink_to_fit();
|
||||||
|
let json: String = serde_json::to_string(&active_validators).map_err(|e| {
|
||||||
|
ApiError::ServerError(format!(
|
||||||
|
"Unable to serialize list of active validators: {:?}",
|
||||||
|
e
|
||||||
|
))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(success_response(Body::from(json)))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Encode)]
|
#[derive(Serialize, Encode)]
|
||||||
@@ -244,3 +275,15 @@ pub fn get_current_finalized_checkpoint<T: BeaconChainTypes + 'static>(
|
|||||||
|
|
||||||
Ok(success_response(Body::from(json)))
|
Ok(success_response(Body::from(json)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// HTTP handler to return a `BeaconState` at a given `root` or `slot`.
|
||||||
|
///
|
||||||
|
/// Will not return a state if the request slot is in the future. Will return states higher than
|
||||||
|
/// the current head by skipping slots.
|
||||||
|
pub fn get_genesis_state<T: BeaconChainTypes + 'static>(req: Request<Body>) -> ApiResult {
|
||||||
|
let beacon_chain = get_beacon_chain_from_request::<T>(&req)?;
|
||||||
|
|
||||||
|
let (_root, state) = state_at_slot(&beacon_chain, Slot::new(0))?;
|
||||||
|
|
||||||
|
ResponseBuilder::new(&req).body(&state)
|
||||||
|
}
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ impl Into<Response<Body>> for ApiError {
|
|||||||
};
|
};
|
||||||
Response::builder()
|
Response::builder()
|
||||||
.status(status_code.0)
|
.status(status_code.0)
|
||||||
|
.header("content-type", "text/plain")
|
||||||
.body(Body::from(status_code.1))
|
.body(Body::from(status_code.1))
|
||||||
.expect("Response should always be created.")
|
.expect("Response should always be created.")
|
||||||
}
|
}
|
||||||
@@ -160,9 +161,7 @@ pub fn start_server<T: BeaconChainTypes>(
|
|||||||
helpers::implementation_pending_response(req)
|
helpers::implementation_pending_response(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
(&Method::GET, "/beacon/validators") => {
|
(&Method::GET, "/beacon/validators") => beacon::get_validators::<T>(req),
|
||||||
helpers::implementation_pending_response(req)
|
|
||||||
}
|
|
||||||
(&Method::GET, "/beacon/validators/indicies") => {
|
(&Method::GET, "/beacon/validators/indicies") => {
|
||||||
helpers::implementation_pending_response(req)
|
helpers::implementation_pending_response(req)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,18 @@ pub fn get_validator_duties<T: BeaconChainTypes + 'static>(req: Request<Body>) -
|
|||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
let mut duties: Vec<ValidatorDuty> = Vec::new();
|
let mut duties: Vec<ValidatorDuty> = Vec::new();
|
||||||
|
|
||||||
|
// Update the committee cache
|
||||||
|
// TODO: Do we need to update the cache on the state, for the epoch which has been specified?
|
||||||
|
beacon_chain
|
||||||
|
.state_now()
|
||||||
|
.map_err(|e| ApiError::ServerError(format!("Unable to get current BeaconState {:?}", e)))?
|
||||||
|
.maybe_as_mut_ref()
|
||||||
|
.ok_or(ApiError::ServerError(
|
||||||
|
"Unable to get mutable BeaconState".into(),
|
||||||
|
))?
|
||||||
|
.build_committee_cache(relative_epoch, &beacon_chain.spec)
|
||||||
|
.map_err(|e| ApiError::ServerError(format!("Unable to build state caches: {:?}", e)))?;
|
||||||
|
|
||||||
// Get a list of all validators for this epoch
|
// Get a list of all validators for this epoch
|
||||||
let validator_proposers: Vec<usize> = epoch
|
let validator_proposers: Vec<usize> = epoch
|
||||||
.slot_iter(T::EthSpec::slots_per_epoch())
|
.slot_iter(T::EthSpec::slots_per_epoch())
|
||||||
@@ -67,6 +79,7 @@ pub fn get_validator_duties<T: BeaconChainTypes + 'static>(req: Request<Body>) -
|
|||||||
head_state
|
head_state
|
||||||
.get_beacon_proposer_index(slot, relative_epoch, &beacon_chain.spec)
|
.get_beacon_proposer_index(slot, relative_epoch, &beacon_chain.spec)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
|
// TODO: why are we getting an uninitialized state error here???
|
||||||
ApiError::ServerError(format!(
|
ApiError::ServerError(format!(
|
||||||
"Unable to get proposer index for validator: {:?}",
|
"Unable to get proposer index for validator: {:?}",
|
||||||
e
|
e
|
||||||
|
|||||||
Reference in New Issue
Block a user