From 0bd8187ff648e1eca0224a1f9d27792ce612db24 Mon Sep 17 00:00:00 2001 From: Luke Anderson Date: Wed, 11 Sep 2019 18:21:51 +1000 Subject: [PATCH] Revert most of commit ebd97730d572a80343f1cd8779d19e1b56e8a5eb. - Undoing making of the beacon chain read stuff return futures, instead dealing with it elsewhere. --- beacon_node/rest_api/src/beacon.rs | 160 +++++++++++++++------------- beacon_node/rest_api/src/helpers.rs | 2 +- beacon_node/rest_api/src/lib.rs | 1 + 3 files changed, 87 insertions(+), 76 deletions(-) diff --git a/beacon_node/rest_api/src/beacon.rs b/beacon_node/rest_api/src/beacon.rs index cf540c65a..850c77dc1 100644 --- a/beacon_node/rest_api/src/beacon.rs +++ b/beacon_node/rest_api/src/beacon.rs @@ -23,12 +23,11 @@ pub struct HeadResponse { } /// HTTP handler to return a `BeaconBlock` at a given `root` or `slot`. -pub fn get_head(req: Request) -> BoxFut { +pub fn get_head(req: Request) -> ApiResult { let beacon_chain = req .extensions() .get::>>() - .expect("BeaconChain extension must be there, because we put it there.") - .clone(); + .ok_or_else(|| ApiError::ServerError("Beacon chain extension missing".to_string()))?; let chain_head = beacon_chain.head(); @@ -56,7 +55,10 @@ pub fn get_head(req: Request) -> BoxFut { previous_justified_block_root: chain_head.beacon_state.previous_justified_checkpoint.root, }; - success_response(req, &head) + let json: String = serde_json::to_string(&head) + .map_err(|e| ApiError::ServerError(format!("Unable to serialize HeadResponse: {:?}", e)))?; + + Ok(success_response_old(Body::from(json))) } #[derive(Serialize, Encode)] @@ -67,83 +69,84 @@ pub struct BlockResponse { } /// HTTP handler to return a `BeaconBlock` at a given `root` or `slot`. -pub fn get_block(req: Request) -> BoxFut { +pub fn get_block(req: Request) -> ApiResult { let beacon_chain = req .extensions() .get::>>() - .expect("BeaconChain extension must be there, because we put it there.") - .clone(); + .ok_or_else(|| ApiError::ServerError("Beacon chain extension missing".to_string()))?; let query_params = ["root", "slot"]; - let query = try_future!(UrlQuery::from_request(&req)); - let (key, value) = try_future!(query.first_of(&query_params)); + let (key, value) = UrlQuery::from_request(&req)?.first_of(&query_params)?; let block_root = match (key.as_ref(), value) { ("slot", value) => { - let target = try_future!(parse_slot(&value)); + let target = parse_slot(&value)?; - try_future!(block_root_at_slot(&beacon_chain, target).ok_or_else(|| { + block_root_at_slot(&beacon_chain, target).ok_or_else(|| { ApiError::NotFound(format!("Unable to find BeaconBlock for slot {:?}", target)) - })) - } - ("root", value) => try_future!(parse_root(&value)), - _ => { - return Box::new(futures::future::err(ApiError::ServerError( - "Unexpected query parameter".into(), - ))) + })? } + ("root", value) => parse_root(&value)?, + _ => return Err(ApiError::ServerError("Unexpected query parameter".into())), }; - let block = try_future!(try_future!(beacon_chain + let block = beacon_chain .store - .get::>(&block_root)) - .ok_or_else(|| { - ApiError::NotFound(format!( - "Unable to find BeaconBlock for root {:?}", - block_root - )) - })); + .get::>(&block_root)? + .ok_or_else(|| { + ApiError::NotFound(format!( + "Unable to find BeaconBlock for root {:?}", + block_root + )) + })?; let response = BlockResponse { root: block_root, beacon_block: block, }; - success_response(req, &response) + ResponseBuilder::new(&req).body(&response) } /// HTTP handler to return a `BeaconBlock` root at a given `slot`. -pub fn get_block_root(req: Request) -> BoxFut { - let (beacon_chain, _head_state) = try_future!(get_beacon_chain_from_request::(&req)); +pub fn get_block_root(req: Request) -> ApiResult { + let (beacon_chain, _head_state) = get_beacon_chain_from_request::(&req)?; - let slot_string: String = - try_future!(try_future!(UrlQuery::from_request(&req)).only_one("slot")); - let target: Slot = try_future!(parse_slot(&slot_string)); + let slot_string = UrlQuery::from_request(&req)?.only_one("slot")?; + let target = parse_slot(&slot_string)?; - let root = try_future!(block_root_at_slot(&beacon_chain, target).ok_or_else(|| { + let root = block_root_at_slot(&beacon_chain, target).ok_or_else(|| { ApiError::NotFound(format!("Unable to find BeaconBlock for slot {:?}", target)) - })); + })?; - success_response(req, &root) + let json: String = serde_json::to_string(&root) + .map_err(|e| ApiError::ServerError(format!("Unable to serialize root: {:?}", e)))?; + + Ok(success_response_old(Body::from(json))) } /// HTTP handler to return the `Fork` of the current head. -pub fn get_fork(req: Request) -> BoxFut { - let (_beacon_chain, head_state) = try_future!(get_beacon_chain_from_request::(&req)); +pub fn get_fork(req: Request) -> ApiResult { + let (_beacon_chain, head_state) = get_beacon_chain_from_request::(&req)?; - success_response(req, &head_state.fork) + let json: String = serde_json::to_string(&head_state.fork).map_err(|e| { + ApiError::ServerError(format!("Unable to serialize BeaconState::Fork: {:?}", e)) + })?; + + Ok(success_response_old(Body::from(json))) } /// HTTP handler to return the set of validators for an `Epoch` /// /// The `Epoch` parameter can be any epoch number. If it is not specified, /// the current epoch is assumed. -pub fn get_validators(req: Request) -> BoxFut { - let (beacon_chain, _head_state) = try_future!(get_beacon_chain_from_request::(&req)); +pub fn get_validators(req: Request) -> ApiResult { + let (beacon_chain, _head_state) = 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 - Ok(query) => try_future!(try_future!(query.only_one("epoch")) + Ok(query) => query + .only_one("epoch")? .parse::() .map(Epoch::from) .map_err(|e| { @@ -151,11 +154,11 @@ pub fn get_validators(req: Request) -> BoxF "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(_) => try_future!(beacon_chain.epoch().map_err(|e| { + Err(_) => beacon_chain.epoch().map_err(|e| { ApiError::ServerError(format!("Unable to determine current epoch: {:?}", e)) - })), + })?, }; let all_validators = &beacon_chain.head().beacon_state.validators; @@ -165,7 +168,7 @@ pub fn get_validators(req: Request) -> BoxF .cloned() .collect(); - success_response(req, &active_vals) + ResponseBuilder::new(&req).body(&active_vals) } #[derive(Serialize, Encode)] @@ -179,42 +182,43 @@ 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) -> BoxFut { - let (beacon_chain, head_state) = try_future!(get_beacon_chain_from_request::(&req)); +pub fn get_state(req: Request) -> ApiResult { + let (beacon_chain, head_state) = get_beacon_chain_from_request::(&req)?; let (key, value) = match UrlQuery::from_request(&req) { Ok(query) => { // We have *some* parameters, just check them. let query_params = ["root", "slot"]; - try_future!(query.first_of(&query_params)) + match query.first_of(&query_params) { + Ok((k, v)) => (k, v), + Err(e) => { + // Wrong parameters provided, or another error, return the error. + return Err(e); + } + } } Err(ApiError::InvalidQueryParams(_)) => { // No parameters provided at all, use current slot. (String::from("slot"), head_state.slot.to_string()) } Err(e) => { - return Box::new(futures::future::err(e)); + return Err(e); } }; let (root, state): (Hash256, BeaconState) = match (key.as_ref(), value) { - ("slot", value) => try_future!(state_at_slot( - &beacon_chain, - try_future!(parse_slot(&value)) - )), + ("slot", value) => state_at_slot(&beacon_chain, parse_slot(&value)?)?, ("root", value) => { - let root: &Hash256 = &try_future!(parse_root(&value)); + let root = &parse_root(&value)?; - let state = try_future!(try_future!(beacon_chain.store.get(root)) - .ok_or_else(|| ApiError::NotFound(format!("No state for root: {:?}", root)))); + let state = beacon_chain + .store + .get(root)? + .ok_or_else(|| ApiError::NotFound(format!("No state for root: {:?}", root)))?; (*root, state) } - _ => { - return Box::new(futures::future::err(ApiError::ServerError( - "Unexpected query parameter".into(), - ))) - } + _ => return Err(ApiError::ServerError("Unexpected query parameter".into())), }; let response = StateResponse { @@ -222,29 +226,32 @@ pub fn get_state(req: Request) -> BoxFut { beacon_state: state, }; - success_response(req, &response) + ResponseBuilder::new(&req).body(&response) } /// HTTP handler to return a `BeaconState` root at a given `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_state_root(req: Request) -> BoxFut { - let (beacon_chain, _head_state) = try_future!(get_beacon_chain_from_request::(&req)); +pub fn get_state_root(req: Request) -> ApiResult { + let (beacon_chain, _head_state) = get_beacon_chain_from_request::(&req)?; - let slot_string = try_future!(try_future!(UrlQuery::from_request(&req)).only_one("slot")); - let slot = try_future!(parse_slot(&slot_string)); + let slot_string = UrlQuery::from_request(&req)?.only_one("slot")?; + let slot = parse_slot(&slot_string)?; - let root = try_future!(state_root_at_slot(&beacon_chain, slot)); + let root = state_root_at_slot(&beacon_chain, slot)?; - success_response(req, &root) + let json: String = serde_json::to_string(&root) + .map_err(|e| ApiError::ServerError(format!("Unable to serialize root: {:?}", e)))?; + + Ok(success_response_old(Body::from(json))) } /// HTTP handler to return the highest finalized slot. pub fn get_current_finalized_checkpoint( req: Request, -) -> BoxFut { - let (beacon_chain, _head_state) = try_future!(get_beacon_chain_from_request::(&req)); +) -> ApiResult { + let (beacon_chain, _head_state) = get_beacon_chain_from_request::(&req)?; let checkpoint = beacon_chain .head() @@ -252,14 +259,17 @@ pub fn get_current_finalized_checkpoint( .finalized_checkpoint .clone(); - success_response(req, &checkpoint) + let json: String = serde_json::to_string(&checkpoint) + .map_err(|e| ApiError::ServerError(format!("Unable to serialize checkpoint: {:?}", e)))?; + + Ok(success_response_old(Body::from(json))) } /// HTTP handler to return a `BeaconState` at the genesis block. -pub fn get_genesis_state(req: Request) -> BoxFut { - let (beacon_chain, _head_state) = try_future!(get_beacon_chain_from_request::(&req)); +pub fn get_genesis_state(req: Request) -> ApiResult { + let (beacon_chain, _head_state) = get_beacon_chain_from_request::(&req)?; - let (_root, state) = try_future!(state_at_slot(&beacon_chain, Slot::new(0))); + let (_root, state) = state_at_slot(&beacon_chain, Slot::new(0))?; - success_response(req, &state) + ResponseBuilder::new(&req).body(&state) } diff --git a/beacon_node/rest_api/src/helpers.rs b/beacon_node/rest_api/src/helpers.rs index a3633cfec..41915138f 100644 --- a/beacon_node/rest_api/src/helpers.rs +++ b/beacon_node/rest_api/src/helpers.rs @@ -233,7 +233,7 @@ pub fn get_beacon_chain_from_request( let beacon_chain = req .extensions() .get::>>() - .expect("BeaconChain extension must be there, because we put it there."); + .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)))?; diff --git a/beacon_node/rest_api/src/lib.rs b/beacon_node/rest_api/src/lib.rs index bc3d3d159..97ed971c2 100644 --- a/beacon_node/rest_api/src/lib.rs +++ b/beacon_node/rest_api/src/lib.rs @@ -95,6 +95,7 @@ impl Service for ApiService { (&Method::GET, "/network/listen_port") => network::get_listen_port::(req), (&Method::GET, "/network/listen_addresses") => network::get_listen_addresses::(req), + /* // Methods for Beacon Node (&Method::GET, "/beacon/head") => beacon::get_head::(req), (&Method::GET, "/beacon/block") => beacon::get_block::(req),