Validator API (#504)

* Implemented more REST API endpoints.
 - Added many of the endpoints, which return 501 - Not Implemented
 - Created helper function to return a not implemented error
 - Created a parse_pubkey function to get a PublicKey from a hex string
 - Created a HTTP handler for the validator endpoints
 - Started implementing validator/duties endpoint.

* Fleshed out get validator duties.
 - Re-implemented the get validator duties function for the REST API
 - Added an 'as_hex_string' function to FakePublicKey, beacuse it was missing.

* Fixed small caching/state bug.

* Extended to array of API inputs.
 - Created  function for getting arrays from GET parameters.
 - Extended get validator duties function to support array of validator duties.

* Tidy API to be more consistent with recent decisions

* Addressing Paul's comments.
 - Cleaning up function to get list of proposers.
 - Removing unnecessary serde annotations
 - Clarifying error messages
 - Only accept pubkeys if they are '0x' prefixed.

* Fixed formatting with rustfmt.
This commit is contained in:
Luke Anderson
2019-08-28 00:40:35 +10:00
parent ce43a59fff
commit 328f11d564
7 changed files with 253 additions and 6 deletions

View File

@@ -1,5 +1,10 @@
use crate::ApiError;
use crate::{ApiError, ApiResult};
use beacon_chain::{BeaconChain, BeaconChainTypes};
use bls::PublicKey;
use hex;
use hyper::{Body, Request, StatusCode};
use serde::de::value::StringDeserializer;
use serde_json::Deserializer;
use store::{iter::AncestorIter, Store};
use types::{BeaconState, EthSpec, Hash256, RelativeEpoch, Slot};
@@ -31,6 +36,23 @@ pub fn parse_root(string: &str) -> Result<Hash256, ApiError> {
}
}
/// Parse a PublicKey from a `0x` prefixed hex string
pub fn parse_pubkey(string: &str) -> Result<PublicKey, ApiError> {
const PREFIX: &str = "0x";
if string.starts_with(PREFIX) {
let pubkey_bytes = hex::decode(string.trim_start_matches(PREFIX))
.map_err(|e| ApiError::InvalidQueryParams(format!("Invalid hex string: {:?}", e)))?;
let pubkey = PublicKey::from_bytes(pubkey_bytes.as_slice()).map_err(|e| {
ApiError::InvalidQueryParams(format!("Unable to deserialize public key: {:?}.", e))
})?;
return Ok(pubkey);
} else {
return Err(ApiError::InvalidQueryParams(
"Public key must have a '0x' prefix".to_string(),
));
}
}
/// Returns the root of the `BeaconBlock` in the canonical chain of `beacon_chain` at the given
/// `slot`, if possible.
///
@@ -143,6 +165,12 @@ pub fn state_root_at_slot<T: BeaconChainTypes>(
}
}
pub fn implementation_pending_response(_req: Request<Body>) -> ApiResult {
Err(ApiError::NotImplemented(
"API endpoint has not yet been implemented, but is planned to be soon.".to_owned(),
))
}
#[cfg(test)]
mod test {
use super::*;