Addressed Paul's suggestions.

- Updated some comments.
 - Replaced match statements with map functions.
This commit is contained in:
Luke Anderson 2019-09-04 13:43:45 +10:00
parent b432c8c58c
commit 0c1ceab527
No known key found for this signature in database
GPG Key ID: 44408169EC61E228
3 changed files with 74 additions and 104 deletions

View File

@ -67,7 +67,7 @@ pub fn get_prometheus<T: BeaconChainTypes + 'static>(req: Request<Body>) -> ApiR
String::from_utf8(buffer) String::from_utf8(buffer)
.map(|string| { .map(|string| {
let mut response = success_response(Body::from(string)); let mut response = success_response(Body::from(string));
// Need to change the header to text/plain for prometheius // Need to change the header to text/plain for prometheus
response.headers_mut().insert( response.headers_mut().insert(
"content-type", "content-type",
HeaderValue::from_static("text/plain; charset=utf-8"), HeaderValue::from_static("text/plain; charset=utf-8"),

View File

@ -4,7 +4,7 @@ use eth2_libp2p::{Enr, Multiaddr, PeerId};
use hyper::{Body, Request}; use hyper::{Body, Request};
use std::sync::Arc; use std::sync::Arc;
/// HTTP handle to return the list of libp2p multiaddr the client is listening on. /// HTTP handler to return the list of libp2p multiaddr the client is listening on.
/// ///
/// Returns a list of `Multiaddr`, serialized according to their `serde` impl. /// Returns a list of `Multiaddr`, serialized according to their `serde` impl.
pub fn get_listen_addresses<T: BeaconChainTypes>(req: Request<Body>) -> ApiResult { pub fn get_listen_addresses<T: BeaconChainTypes>(req: Request<Body>) -> ApiResult {
@ -21,9 +21,9 @@ pub fn get_listen_addresses<T: BeaconChainTypes>(req: Request<Body>) -> ApiResul
))) )))
} }
/// HTTP handle to return network port the client is listening on. /// HTTP handler to return the network port the client is listening on.
/// ///
/// Returns a list of `Multiaddr`, serialized according to their `serde` impl. /// Returns the TCP port number in its plain form (which is also valid JSON serialization)
pub fn get_listen_port<T: BeaconChainTypes>(req: Request<Body>) -> ApiResult { pub fn get_listen_port<T: BeaconChainTypes>(req: Request<Body>) -> ApiResult {
let network = req let network = req
.extensions() .extensions()
@ -36,7 +36,7 @@ pub fn get_listen_port<T: BeaconChainTypes>(req: Request<Body>) -> ApiResult {
))) )))
} }
/// HTTP handle to return the Discv5 ENR from the client's libp2p service. /// HTTP handler to return the Discv5 ENR from the client's libp2p service.
/// ///
/// ENR is encoded as base64 string. /// ENR is encoded as base64 string.
pub fn get_enr<T: BeaconChainTypes>(req: Request<Body>) -> ApiResult { pub fn get_enr<T: BeaconChainTypes>(req: Request<Body>) -> ApiResult {
@ -53,7 +53,7 @@ pub fn get_enr<T: BeaconChainTypes>(req: Request<Body>) -> ApiResult {
))) )))
} }
/// HTTP handle to return the `PeerId` from the client's libp2p service. /// HTTP handler to return the `PeerId` from the client's libp2p service.
/// ///
/// PeerId is encoded as base58 string. /// PeerId is encoded as base58 string.
pub fn get_peer_id<T: BeaconChainTypes>(req: Request<Body>) -> ApiResult { pub fn get_peer_id<T: BeaconChainTypes>(req: Request<Body>) -> ApiResult {
@ -70,7 +70,7 @@ pub fn get_peer_id<T: BeaconChainTypes>(req: Request<Body>) -> ApiResult {
))) )))
} }
/// HTTP handle to return the number of peers connected in the client's libp2p service. /// HTTP handler to return the number of peers connected in the client's libp2p service.
pub fn get_peer_count<T: BeaconChainTypes>(req: Request<Body>) -> ApiResult { pub fn get_peer_count<T: BeaconChainTypes>(req: Request<Body>) -> ApiResult {
let network = req let network = req
.extensions() .extensions()
@ -85,7 +85,7 @@ pub fn get_peer_count<T: BeaconChainTypes>(req: Request<Body>) -> ApiResult {
))) )))
} }
/// HTTP handle to return the list of peers connected to the client's libp2p service. /// HTTP handler to return the list of peers connected to the client's libp2p service.
/// ///
/// Peers are presented as a list of `PeerId::to_string()`. /// Peers are presented as a list of `PeerId::to_string()`.
pub fn get_peer_list<T: BeaconChainTypes>(req: Request<Body>) -> ApiResult { pub fn get_peer_list<T: BeaconChainTypes>(req: Request<Body>) -> ApiResult {

View File

@ -136,32 +136,24 @@ pub fn get_new_beacon_block<T: BeaconChainTypes + 'static>(req: Request<Body>) -
let beacon_chain = get_beacon_chain_from_request::<T>(&req)?; let beacon_chain = get_beacon_chain_from_request::<T>(&req)?;
let query = UrlQuery::from_request(&req)?; let query = UrlQuery::from_request(&req)?;
let slot = match query.first_of(&["slot"]) { let slot = query
Ok((_, v)) => Slot::new(v.parse::<u64>().map_err(|e| { .first_of(&["slot"])
.map(|(_key, value)| value)?
.parse::<u64>()
.map(Slot::from)
.map_err(|e| {
ApiError::InvalidQueryParams(format!("Invalid slot parameter, must be a u64. {:?}", e)) ApiError::InvalidQueryParams(format!("Invalid slot parameter, must be a u64. {:?}", e))
})?), })?;
Err(e) => { let randao_bytes = query
return Err(e); .first_of(&["randao_reveal"])
} .map(|(_key, value)| value)
}; .map(hex::decode)?
let randao_reveal = match query.first_of(&["randao_reveal"]) {
Ok((_, v)) => Signature::from_bytes(
hex::decode(&v)
.map_err(|e| {
ApiError::InvalidQueryParams(format!(
"Invalid hex string for randao_reveal: {:?}",
e
))
})?
.as_slice(),
)
.map_err(|e| { .map_err(|e| {
ApiError::InvalidQueryParams(format!("Invalid hex string for randao_reveal: {:?}", e))
})?;
let randao_reveal = Signature::from_bytes(randao_bytes.as_slice()).map_err(|e| {
ApiError::InvalidQueryParams(format!("randao_reveal is not a valid signature: {:?}", e)) ApiError::InvalidQueryParams(format!("randao_reveal is not a valid signature: {:?}", e))
})?, })?;
Err(e) => {
return Err(e);
}
};
let (new_block, _state) = beacon_chain let (new_block, _state) = beacon_chain
.produce_block(randao_reveal, slot) .produce_block(randao_reveal, slot)
@ -185,43 +177,33 @@ pub fn get_new_attestation<T: BeaconChainTypes + 'static>(req: Request<Body>) ->
let head_state = &beacon_chain.head().beacon_state; let head_state = &beacon_chain.head().beacon_state;
let query = UrlQuery::from_request(&req)?; let query = UrlQuery::from_request(&req)?;
let val_pk: PublicKey = match query.first_of(&["validator_pubkey"]) { let val_pk_str = query
Ok((_, v)) => parse_pubkey(v.as_str())?, .first_of(&["validator_pubkey"])
Err(e) => { .map(|(_key, value)| value)?;
return Err(e); let val_pk = parse_pubkey(val_pk_str.as_str())?;
}
};
// Get the validator index from the supplied public key // Get the validator index from the supplied public key
// If it does not exist in the index, we cannot continue. // If it does not exist in the index, we cannot continue.
let val_index: usize = match head_state.get_validator_index(&val_pk) { let val_index = head_state
Ok(Some(i)) => i, .get_validator_index(&val_pk)
Ok(None) => { .map_err(|e| {
return Err(ApiError::InvalidQueryParams( ApiError::ServerError(format!("Unable to read validator index cache. {:?}", e))
"The provided validator public key does not correspond to a validator index." })?
.into(), .ok_or(ApiError::InvalidQueryParams(
)); "The provided validator public key does not correspond to a validator index.".into(),
} ))?;
Err(e) => {
return Err(ApiError::ServerError(format!(
"Unable to read validator index cache. {:?}",
e
)));
}
};
// Get the duties of the validator, to make sure they match up. // Get the duties of the validator, to make sure they match up.
// If they don't have duties this epoch, then return an error // If they don't have duties this epoch, then return an error
let val_duty = match head_state.get_attestation_duties(val_index, RelativeEpoch::Current) { let val_duty = head_state
Ok(Some(d)) => d, .get_attestation_duties(val_index, RelativeEpoch::Current)
Ok(None) => { .map_err(|e| {
return Err(ApiError::InvalidQueryParams("No validator duties could be found for the requested validator. Cannot provide valid attestation.".into())); ApiError::ServerError(format!(
}
Err(e) => {
return Err(ApiError::ServerError(format!(
"unable to read cache for attestation duties: {:?}", "unable to read cache for attestation duties: {:?}",
e e
))) ))
} })?
}; .ok_or(ApiError::InvalidQueryParams("No validator duties could be found for the requested validator. Cannot provide valid attestation.".into()))?;
// Check that we are requesting an attestation during the slot where it is relevant. // Check that we are requesting an attestation during the slot where it is relevant.
let present_slot = beacon_chain.read_slot_clock().ok_or(ApiError::ServerError( let present_slot = beacon_chain.read_slot_clock().ok_or(ApiError::ServerError(
@ -232,14 +214,14 @@ pub fn get_new_attestation<T: BeaconChainTypes + 'static>(req: Request<Body>) ->
} }
// Parse the POC bit and insert it into the aggregation bits // Parse the POC bit and insert it into the aggregation bits
let poc_bit: bool = match query.first_of(&["poc_bit"]) { let poc_bit = query
Ok((_, v)) => v.parse::<bool>().map_err(|e| { .first_of(&["poc_bit"])
ApiError::InvalidQueryParams(format!("poc_bit is not a valid boolean value: {:?}", e)) .map(|(_key, value)| value)?
})?, .parse::<bool>()
Err(e) => { .map_err(|e| {
return Err(e); ApiError::InvalidQueryParams(format!("Invalid slot parameter, must be a u64. {:?}", e))
} })?;
};
let mut aggregation_bits = BitList::with_capacity(val_duty.committee_len) let mut aggregation_bits = BitList::with_capacity(val_duty.committee_len)
.expect("An empty BitList should always be created, or we have bigger problems."); .expect("An empty BitList should always be created, or we have bigger problems.");
aggregation_bits aggregation_bits
@ -251,41 +233,29 @@ pub fn get_new_attestation<T: BeaconChainTypes + 'static>(req: Request<Body>) ->
)) ))
})?; })?;
// Allow a provided slot parameter to check against the expected slot as a sanity check. // Allow a provided slot parameter to check against the expected slot as a sanity check only.
// Presently, we don't support attestations at future or past slots. // Presently, we don't support attestations at future or past slots.
let _slot = match query.first_of(&["slot"]) { let requested_slot = query
Ok((_, v)) => { .first_of(&["slot"])
let requested_slot = v.parse::<u64>().map_err(|e| { .map(|(_key, value)| value)?
ApiError::InvalidQueryParams(format!( .parse::<u64>()
"Invalid slot parameter, must be a u64. {:?}", .map(Slot::from)
e .map_err(|e| {
)) ApiError::InvalidQueryParams(format!("Invalid slot parameter, must be a u64. {:?}", e))
})?; })?;
let current_slot = beacon_chain.head().beacon_state.slot.as_u64(); let current_slot = beacon_chain.head().beacon_state.slot.as_u64();
if requested_slot != current_slot { if requested_slot != current_slot {
return Err(ApiError::InvalidQueryParams(format!("Attestation data can only be requested for the current slot ({:?}), not your requested slot ({:?})", current_slot, requested_slot))); return Err(ApiError::InvalidQueryParams(format!("Attestation data can only be requested for the current slot ({:?}), not your requested slot ({:?})", current_slot, requested_slot)));
} }
Slot::new(requested_slot)
}
Err(ApiError::InvalidQueryParams(_)) => {
// Just fill _slot with a dummy value for now, making the slot parameter optional
// We'll get the real slot from the ValidatorDuty
Slot::new(0)
}
Err(e) => {
return Err(e);
}
};
let shard: Shard = match query.first_of(&["shard"]) { let shard = query
Ok((_, v)) => v.parse::<u64>().map_err(|e| { .first_of(&["shard"])
.map(|(_key, value)| value)?
.parse::<u64>()
.map_err(|e| {
ApiError::InvalidQueryParams(format!("Shard is not a valid u64 value: {:?}", e)) ApiError::InvalidQueryParams(format!("Shard is not a valid u64 value: {:?}", e))
})?, })?;
Err(e) => {
// This is a mandatory parameter, return the error
return Err(e);
}
};
let attestation_data = beacon_chain let attestation_data = beacon_chain
.produce_attestation_data(shard) .produce_attestation_data(shard)
.map_err(|e| ApiError::ServerError(format!("Could not produce an attestation: {:?}", e)))?; .map_err(|e| ApiError::ServerError(format!("Could not produce an attestation: {:?}", e)))?;