From c254ac8c2ecd2816959d23a829dc628f4a713a0a Mon Sep 17 00:00:00 2001 From: Luke Anderson Date: Thu, 12 Sep 2019 01:44:45 +1000 Subject: [PATCH] Separated acquisition of BeaconChain and BeaconState. --- beacon_node/rest_api/src/beacon.rs | 23 +++++++++++------------ beacon_node/rest_api/src/helpers.rs | 19 +++++++++++-------- beacon_node/rest_api/src/metrics.rs | 2 +- beacon_node/rest_api/src/node.rs | 5 +++-- beacon_node/rest_api/src/spec.rs | 2 +- beacon_node/rest_api/src/validator.rs | 20 +++++--------------- 6 files changed, 32 insertions(+), 39 deletions(-) diff --git a/beacon_node/rest_api/src/beacon.rs b/beacon_node/rest_api/src/beacon.rs index 66f5e7731..3b9b2a008 100644 --- a/beacon_node/rest_api/src/beacon.rs +++ b/beacon_node/rest_api/src/beacon.rs @@ -109,7 +109,7 @@ pub fn get_block(req: Request) -> ApiResult /// HTTP handler to return a `BeaconBlock` root at a given `slot`. pub fn get_block_root(req: Request) -> ApiResult { - let (beacon_chain, _head_state) = get_beacon_chain_from_request::(&req)?; + let beacon_chain = get_beacon_chain_from_request::(&req)?; let slot_string = UrlQuery::from_request(&req)?.only_one("slot")?; let target = parse_slot(&slot_string)?; @@ -126,7 +126,8 @@ pub fn get_block_root(req: Request) -> ApiR /// HTTP handler to return the `Fork` of the current head. pub fn get_fork(req: Request) -> ApiResult { - let (_beacon_chain, head_state) = get_beacon_chain_from_request::(&req)?; + let beacon_chain = get_beacon_chain_from_request::(&req)?; + let head_state = get_head_state(beacon_chain)?; let json: String = serde_json::to_string(&head_state.fork).map_err(|e| { ApiError::ServerError(format!("Unable to serialize BeaconState::Fork: {:?}", e)) @@ -140,7 +141,7 @@ pub fn get_fork(req: Request) -> ApiResult /// The `Epoch` parameter can be any epoch number. If it is not specified, /// the current epoch is assumed. pub fn get_validators(req: Request) -> ApiResult { - let (beacon_chain, _head_state) = get_beacon_chain_from_request::(&req)?; + let beacon_chain = get_beacon_chain_from_request::(&req)?; let epoch = match UrlQuery::from_request(&req) { // We have some parameters, so make sure it's the epoch one and parse it @@ -182,7 +183,8 @@ pub struct StateResponse { /// 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_state(req: Request) -> ApiResult { - let (beacon_chain, head_state) = get_beacon_chain_from_request::(&req)?; + let beacon_chain = get_beacon_chain_from_request::(&req)?; + let head_state = get_head_state(beacon_chain.clone())?; let (key, value) = match UrlQuery::from_request(&req) { Ok(query) => { @@ -233,7 +235,7 @@ pub fn get_state(req: Request) -> ApiResult /// 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_state_root(req: Request) -> ApiResult { - let (beacon_chain, _head_state) = get_beacon_chain_from_request::(&req)?; + let beacon_chain = get_beacon_chain_from_request::(&req)?; let slot_string = UrlQuery::from_request(&req)?.only_one("slot")?; let slot = parse_slot(&slot_string)?; @@ -250,13 +252,10 @@ pub fn get_state_root(req: Request) -> ApiR pub fn get_current_finalized_checkpoint( req: Request, ) -> ApiResult { - let (beacon_chain, _head_state) = get_beacon_chain_from_request::(&req)?; + let beacon_chain = get_beacon_chain_from_request::(&req)?; + let head_state = get_head_state(beacon_chain)?; - let checkpoint = beacon_chain - .head() - .beacon_state - .finalized_checkpoint - .clone(); + let checkpoint = head_state.finalized_checkpoint.clone(); let json: String = serde_json::to_string(&checkpoint) .map_err(|e| ApiError::ServerError(format!("Unable to serialize checkpoint: {:?}", e)))?; @@ -266,7 +265,7 @@ pub fn get_current_finalized_checkpoint( /// HTTP handler to return a `BeaconState` at the genesis block. pub fn get_genesis_state(req: Request) -> ApiResult { - let (beacon_chain, _head_state) = get_beacon_chain_from_request::(&req)?; + let beacon_chain = get_beacon_chain_from_request::(&req)?; let (_root, state) = state_at_slot(&beacon_chain, Slot::new(0))?; diff --git a/beacon_node/rest_api/src/helpers.rs b/beacon_node/rest_api/src/helpers.rs index 76fc78750..4dd8a475d 100644 --- a/beacon_node/rest_api/src/helpers.rs +++ b/beacon_node/rest_api/src/helpers.rs @@ -172,21 +172,24 @@ pub fn implementation_pending_response(_req: Request) -> ApiResult { pub fn get_beacon_chain_from_request( req: &Request, -) -> Result<(Arc>, BeaconState), ApiError> { +) -> Result<(Arc>), ApiError> { // Get beacon state let beacon_chain = req .extensions() .get::>>() .ok_or_else(|| ApiError::ServerError("Beacon chain extension missing".into()))?; - let mut head_state = beacon_chain - .state_now() - .map_err(|e| ApiError::ServerError(format!("Unable to get current BeaconState {:?}", e)))?; - if let Some(s) = head_state.maybe_as_mut_ref() { - s.build_all_caches(&beacon_chain.spec).ok(); - } + Ok(beacon_chain.clone()) +} - Ok((beacon_chain.clone(), head_state.clone())) +pub fn get_head_state( + bc: Arc>, +) -> Result, ApiError> { + let mut head_state = bc.head().beacon_state; + head_state + .build_all_caches(&bc.spec) + .map_err(|e| ApiError::ServerError(format!("Unable to build state cache: {:?}", e)))?; + Ok(head_state) } pub fn get_logger_from_request(req: &Request) -> slog::Logger { diff --git a/beacon_node/rest_api/src/metrics.rs b/beacon_node/rest_api/src/metrics.rs index 62a769de1..01dc4d22d 100644 --- a/beacon_node/rest_api/src/metrics.rs +++ b/beacon_node/rest_api/src/metrics.rs @@ -30,7 +30,7 @@ pub fn get_prometheus(req: Request) -> ApiR let mut buffer = vec![]; let encoder = TextEncoder::new(); - let (beacon_chain, _head_state) = get_beacon_chain_from_request::(&req)?; + let beacon_chain = get_beacon_chain_from_request::(&req)?; let db_path = req .extensions() .get::() diff --git a/beacon_node/rest_api/src/node.rs b/beacon_node/rest_api/src/node.rs index c75d3ba20..4a9f11be0 100644 --- a/beacon_node/rest_api/src/node.rs +++ b/beacon_node/rest_api/src/node.rs @@ -1,4 +1,4 @@ -use crate::helpers::get_beacon_chain_from_request; +use crate::helpers::*; use crate::{success_response, ApiResult}; use beacon_chain::BeaconChainTypes; use hyper::{Body, Request}; @@ -15,7 +15,8 @@ pub fn get_version(_req: Request) -> ApiResult { /// Read the genesis time from the current beacon chain state. pub fn get_genesis_time(req: Request) -> ApiResult { - let (_beacon_chain, head_state) = get_beacon_chain_from_request::(&req)?; + let beacon_chain = get_beacon_chain_from_request::(&req)?; + let head_state = get_head_state(beacon_chain)?; let gen_time: u64 = head_state.genesis_time; let body = Body::from( serde_json::to_string(&gen_time) diff --git a/beacon_node/rest_api/src/spec.rs b/beacon_node/rest_api/src/spec.rs index ad168faf1..a353b3833 100644 --- a/beacon_node/rest_api/src/spec.rs +++ b/beacon_node/rest_api/src/spec.rs @@ -9,7 +9,7 @@ use types::EthSpec; /// HTTP handler to return the full spec object. pub fn get_spec(req: Request) -> ApiResult { - let (beacon_chain, _head_state) = get_beacon_chain_from_request::(&req)?; + let beacon_chain = get_beacon_chain_from_request::(&req)?; let json: String = serde_json::to_string(&beacon_chain.spec) .map_err(|e| ApiError::ServerError(format!("Unable to serialize spec: {:?}", e)))?; diff --git a/beacon_node/rest_api/src/validator.rs b/beacon_node/rest_api/src/validator.rs index 49b4c0441..84cb7a308 100644 --- a/beacon_node/rest_api/src/validator.rs +++ b/beacon_node/rest_api/src/validator.rs @@ -34,7 +34,8 @@ impl ValidatorDuty { pub fn get_validator_duties(req: Request) -> ApiResult { let log = get_logger_from_request(&req); slog::trace!(log, "Validator duties requested of API: {:?}", &req); - let (beacon_chain, head_state) = get_beacon_chain_from_request::(&req)?; + let beacon_chain = get_beacon_chain_from_request::(&req)?; + let head_state = get_head_state(beacon_chain.clone())?; slog::trace!(log, "Got head state from request."); // Parse and check query parameters @@ -71,18 +72,6 @@ pub fn get_validator_duties(req: Request) - .collect::, _>>()?; let mut duties: Vec = 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 let validator_proposers: Vec = epoch .slot_iter(T::EthSpec::slots_per_epoch()) @@ -157,7 +146,7 @@ pub fn get_validator_duties(req: Request) - /// HTTP Handler to produce a new BeaconBlock from the current state, ready to be signed by a validator. pub fn get_new_beacon_block(req: Request) -> ApiResult { - let (beacon_chain, _head_state) = get_beacon_chain_from_request::(&req)?; + let beacon_chain = get_beacon_chain_from_request::(&req)?; let query = UrlQuery::from_request(&req)?; let slot = query @@ -197,7 +186,8 @@ pub fn get_new_beacon_block(req: Request) - /// HTTP Handler to produce a new Attestation from the current state, ready to be signed by a validator. pub fn get_new_attestation(req: Request) -> ApiResult { - let (beacon_chain, head_state) = get_beacon_chain_from_request::(&req)?; + let beacon_chain = get_beacon_chain_from_request::(&req)?; + let head_state = get_head_state(beacon_chain.clone())?; let query = UrlQuery::from_request(&req)?; let val_pk_str = query