Revert most of commit ebd97730d5.

- Undoing making of the beacon chain read stuff return futures, instead dealing with it elsewhere.
This commit is contained in:
Luke Anderson 2019-09-11 18:21:51 +10:00
parent 2739ee83f9
commit 0bd8187ff6
No known key found for this signature in database
GPG Key ID: 44408169EC61E228
3 changed files with 87 additions and 76 deletions

View File

@ -23,12 +23,11 @@ pub struct HeadResponse {
} }
/// HTTP handler to return a `BeaconBlock` at a given `root` or `slot`. /// HTTP handler to return a `BeaconBlock` at a given `root` or `slot`.
pub fn get_head<T: BeaconChainTypes + 'static>(req: Request<Body>) -> BoxFut { pub fn get_head<T: BeaconChainTypes + 'static>(req: Request<Body>) -> ApiResult {
let beacon_chain = req let beacon_chain = req
.extensions() .extensions()
.get::<Arc<BeaconChain<T>>>() .get::<Arc<BeaconChain<T>>>()
.expect("BeaconChain extension must be there, because we put it there.") .ok_or_else(|| ApiError::ServerError("Beacon chain extension missing".to_string()))?;
.clone();
let chain_head = beacon_chain.head(); let chain_head = beacon_chain.head();
@ -56,7 +55,10 @@ pub fn get_head<T: BeaconChainTypes + 'static>(req: Request<Body>) -> BoxFut {
previous_justified_block_root: chain_head.beacon_state.previous_justified_checkpoint.root, 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)] #[derive(Serialize, Encode)]
@ -67,83 +69,84 @@ pub struct BlockResponse<T: EthSpec> {
} }
/// HTTP handler to return a `BeaconBlock` at a given `root` or `slot`. /// HTTP handler to return a `BeaconBlock` at a given `root` or `slot`.
pub fn get_block<T: BeaconChainTypes + 'static>(req: Request<Body>) -> BoxFut { pub fn get_block<T: BeaconChainTypes + 'static>(req: Request<Body>) -> ApiResult {
let beacon_chain = req let beacon_chain = req
.extensions() .extensions()
.get::<Arc<BeaconChain<T>>>() .get::<Arc<BeaconChain<T>>>()
.expect("BeaconChain extension must be there, because we put it there.") .ok_or_else(|| ApiError::ServerError("Beacon chain extension missing".to_string()))?;
.clone();
let query_params = ["root", "slot"]; let query_params = ["root", "slot"];
let query = try_future!(UrlQuery::from_request(&req)); let (key, value) = UrlQuery::from_request(&req)?.first_of(&query_params)?;
let (key, value) = try_future!(query.first_of(&query_params));
let block_root = match (key.as_ref(), value) { let block_root = match (key.as_ref(), value) {
("slot", 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)) 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 .store
.get::<BeaconBlock<T::EthSpec>>(&block_root)) .get::<BeaconBlock<T::EthSpec>>(&block_root)?
.ok_or_else(|| { .ok_or_else(|| {
ApiError::NotFound(format!( ApiError::NotFound(format!(
"Unable to find BeaconBlock for root {:?}", "Unable to find BeaconBlock for root {:?}",
block_root block_root
)) ))
})); })?;
let response = BlockResponse { let response = BlockResponse {
root: block_root, root: block_root,
beacon_block: block, beacon_block: block,
}; };
success_response(req, &response) ResponseBuilder::new(&req).body(&response)
} }
/// HTTP handler to return a `BeaconBlock` root at a given `slot`. /// HTTP handler to return a `BeaconBlock` root at a given `slot`.
pub fn get_block_root<T: BeaconChainTypes + 'static>(req: Request<Body>) -> BoxFut { pub fn get_block_root<T: BeaconChainTypes + 'static>(req: Request<Body>) -> ApiResult {
let (beacon_chain, _head_state) = try_future!(get_beacon_chain_from_request::<T>(&req)); let (beacon_chain, _head_state) = get_beacon_chain_from_request::<T>(&req)?;
let slot_string: String = let slot_string = UrlQuery::from_request(&req)?.only_one("slot")?;
try_future!(try_future!(UrlQuery::from_request(&req)).only_one("slot")); let target = parse_slot(&slot_string)?;
let target: Slot = try_future!(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)) 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. /// HTTP handler to return the `Fork` of the current head.
pub fn get_fork<T: BeaconChainTypes + 'static>(req: Request<Body>) -> BoxFut { pub fn get_fork<T: BeaconChainTypes + 'static>(req: Request<Body>) -> ApiResult {
let (_beacon_chain, head_state) = try_future!(get_beacon_chain_from_request::<T>(&req)); let (_beacon_chain, head_state) = get_beacon_chain_from_request::<T>(&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` /// 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 `Epoch` parameter can be any epoch number. If it is not specified,
/// the current epoch is assumed. /// the current epoch is assumed.
pub fn get_validators<T: BeaconChainTypes + 'static>(req: Request<Body>) -> BoxFut { pub fn get_validators<T: BeaconChainTypes + 'static>(req: Request<Body>) -> ApiResult {
let (beacon_chain, _head_state) = try_future!(get_beacon_chain_from_request::<T>(&req)); let (beacon_chain, _head_state) = get_beacon_chain_from_request::<T>(&req)?;
let epoch = match UrlQuery::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 // 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::<u64>() .parse::<u64>()
.map(Epoch::from) .map(Epoch::from)
.map_err(|e| { .map_err(|e| {
@ -151,11 +154,11 @@ pub fn get_validators<T: BeaconChainTypes + 'static>(req: Request<Body>) -> BoxF
"Invalid epoch parameter, must be a u64. {:?}", "Invalid epoch parameter, must be a u64. {:?}",
e e
)) ))
})), })?,
// In this case, our url query did not contain any parameters, so we take the default // 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)) ApiError::ServerError(format!("Unable to determine current epoch: {:?}", e))
})), })?,
}; };
let all_validators = &beacon_chain.head().beacon_state.validators; let all_validators = &beacon_chain.head().beacon_state.validators;
@ -165,7 +168,7 @@ pub fn get_validators<T: BeaconChainTypes + 'static>(req: Request<Body>) -> BoxF
.cloned() .cloned()
.collect(); .collect();
success_response(req, &active_vals) ResponseBuilder::new(&req).body(&active_vals)
} }
#[derive(Serialize, Encode)] #[derive(Serialize, Encode)]
@ -179,42 +182,43 @@ pub struct StateResponse<T: EthSpec> {
/// ///
/// Will not return a state if the request slot is in the future. Will return states higher than /// Will not return a state if the request slot is in the future. Will return states higher than
/// the current head by skipping slots. /// the current head by skipping slots.
pub fn get_state<T: BeaconChainTypes + 'static>(req: Request<Body>) -> BoxFut { pub fn get_state<T: BeaconChainTypes + 'static>(req: Request<Body>) -> ApiResult {
let (beacon_chain, head_state) = try_future!(get_beacon_chain_from_request::<T>(&req)); let (beacon_chain, head_state) = get_beacon_chain_from_request::<T>(&req)?;
let (key, value) = match UrlQuery::from_request(&req) { let (key, value) = match UrlQuery::from_request(&req) {
Ok(query) => { Ok(query) => {
// We have *some* parameters, just check them. // We have *some* parameters, just check them.
let query_params = ["root", "slot"]; 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(_)) => { Err(ApiError::InvalidQueryParams(_)) => {
// No parameters provided at all, use current slot. // No parameters provided at all, use current slot.
(String::from("slot"), head_state.slot.to_string()) (String::from("slot"), head_state.slot.to_string())
} }
Err(e) => { Err(e) => {
return Box::new(futures::future::err(e)); return Err(e);
} }
}; };
let (root, state): (Hash256, BeaconState<T::EthSpec>) = match (key.as_ref(), value) { let (root, state): (Hash256, BeaconState<T::EthSpec>) = match (key.as_ref(), value) {
("slot", value) => try_future!(state_at_slot( ("slot", value) => state_at_slot(&beacon_chain, parse_slot(&value)?)?,
&beacon_chain,
try_future!(parse_slot(&value))
)),
("root", 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)) let state = beacon_chain
.ok_or_else(|| ApiError::NotFound(format!("No state for root: {:?}", root)))); .store
.get(root)?
.ok_or_else(|| ApiError::NotFound(format!("No state for root: {:?}", root)))?;
(*root, state) (*root, state)
} }
_ => { _ => return Err(ApiError::ServerError("Unexpected query parameter".into())),
return Box::new(futures::future::err(ApiError::ServerError(
"Unexpected query parameter".into(),
)))
}
}; };
let response = StateResponse { let response = StateResponse {
@ -222,29 +226,32 @@ pub fn get_state<T: BeaconChainTypes + 'static>(req: Request<Body>) -> BoxFut {
beacon_state: state, beacon_state: state,
}; };
success_response(req, &response) ResponseBuilder::new(&req).body(&response)
} }
/// HTTP handler to return a `BeaconState` root at a given `slot`. /// 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 /// Will not return a state if the request slot is in the future. Will return states higher than
/// the current head by skipping slots. /// the current head by skipping slots.
pub fn get_state_root<T: BeaconChainTypes + 'static>(req: Request<Body>) -> BoxFut { pub fn get_state_root<T: BeaconChainTypes + 'static>(req: Request<Body>) -> ApiResult {
let (beacon_chain, _head_state) = try_future!(get_beacon_chain_from_request::<T>(&req)); let (beacon_chain, _head_state) = get_beacon_chain_from_request::<T>(&req)?;
let slot_string = try_future!(try_future!(UrlQuery::from_request(&req)).only_one("slot")); let slot_string = UrlQuery::from_request(&req)?.only_one("slot")?;
let slot = try_future!(parse_slot(&slot_string)); 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. /// HTTP handler to return the highest finalized slot.
pub fn get_current_finalized_checkpoint<T: BeaconChainTypes + 'static>( pub fn get_current_finalized_checkpoint<T: BeaconChainTypes + 'static>(
req: Request<Body>, req: Request<Body>,
) -> BoxFut { ) -> ApiResult {
let (beacon_chain, _head_state) = try_future!(get_beacon_chain_from_request::<T>(&req)); let (beacon_chain, _head_state) = get_beacon_chain_from_request::<T>(&req)?;
let checkpoint = beacon_chain let checkpoint = beacon_chain
.head() .head()
@ -252,14 +259,17 @@ pub fn get_current_finalized_checkpoint<T: BeaconChainTypes + 'static>(
.finalized_checkpoint .finalized_checkpoint
.clone(); .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. /// HTTP handler to return a `BeaconState` at the genesis block.
pub fn get_genesis_state<T: BeaconChainTypes + 'static>(req: Request<Body>) -> BoxFut { pub fn get_genesis_state<T: BeaconChainTypes + 'static>(req: Request<Body>) -> ApiResult {
let (beacon_chain, _head_state) = try_future!(get_beacon_chain_from_request::<T>(&req)); let (beacon_chain, _head_state) = get_beacon_chain_from_request::<T>(&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)
} }

View File

@ -233,7 +233,7 @@ pub fn get_beacon_chain_from_request<T: BeaconChainTypes + 'static>(
let beacon_chain = req let beacon_chain = req
.extensions() .extensions()
.get::<Arc<BeaconChain<T>>>() .get::<Arc<BeaconChain<T>>>()
.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 let mut head_state = beacon_chain
.state_now() .state_now()
.map_err(|e| ApiError::ServerError(format!("Unable to get current BeaconState {:?}", e)))?; .map_err(|e| ApiError::ServerError(format!("Unable to get current BeaconState {:?}", e)))?;

View File

@ -95,6 +95,7 @@ impl<T: BeaconChainTypes> Service for ApiService<T> {
(&Method::GET, "/network/listen_port") => network::get_listen_port::<T>(req), (&Method::GET, "/network/listen_port") => network::get_listen_port::<T>(req),
(&Method::GET, "/network/listen_addresses") => network::get_listen_addresses::<T>(req), (&Method::GET, "/network/listen_addresses") => network::get_listen_addresses::<T>(req),
/*
// Methods for Beacon Node // Methods for Beacon Node
(&Method::GET, "/beacon/head") => beacon::get_head::<T>(req), (&Method::GET, "/beacon/head") => beacon::get_head::<T>(req),
(&Method::GET, "/beacon/block") => beacon::get_block::<T>(req), (&Method::GET, "/beacon/block") => beacon::get_block::<T>(req),