diff --git a/beacon_node/rest_api/src/helpers.rs b/beacon_node/rest_api/src/helpers.rs
index 2477884c4..98293e75c 100644
--- a/beacon_node/rest_api/src/helpers.rs
+++ b/beacon_node/rest_api/src/helpers.rs
@@ -5,6 +5,7 @@ use hex;
use hyper::{Body, Request};
use store::{iter::AncestorIter, Store};
use types::{BeaconState, EthSpec, Hash256, RelativeEpoch, Slot};
+use std::sync::Arc;
/// Parse a slot from a `0x` preixed string.
///
@@ -169,6 +170,18 @@ pub fn implementation_pending_response(_req: Request
) -> ApiResult {
))
}
+pub fn get_beacon_chain_from_request(req: &Request) -> Result>, ApiError> {
+ // Get beacon state
+ let beacon_chain = req
+ .extensions()
+ .get::>>()
+ .ok_or_else(|| ApiError::ServerError("Request is missing the beacon chain extension".into()))?;
+ let _ = beacon_chain
+ .ensure_state_caches_are_built()
+ .map_err(|e| ApiError::ServerError(format!("Unable to build state caches: {:?}", e)))?;
+ Ok(beacon_chain.clone())
+}
+
#[cfg(test)]
mod test {
use super::*;
diff --git a/beacon_node/rest_api/src/lib.rs b/beacon_node/rest_api/src/lib.rs
index 2c7b90e3f..2c9c4011a 100644
--- a/beacon_node/rest_api/src/lib.rs
+++ b/beacon_node/rest_api/src/lib.rs
@@ -172,9 +172,9 @@ pub fn start_server(
(&Method::POST, "/beacon/validator/block") => {
helpers::implementation_pending_response(req)
}
- (&Method::GET, "/beacon/validator/attestation") => {
+ /*(&Method::GET, "/beacon/validator/attestation") => {
validator::get_new_attestation::(req)
- }
+ }*/
(&Method::POST, "/beacon/validator/attestation") => {
helpers::implementation_pending_response(req)
}
diff --git a/beacon_node/rest_api/src/validator.rs b/beacon_node/rest_api/src/validator.rs
index 1c72874f2..f60acbad8 100644
--- a/beacon_node/rest_api/src/validator.rs
+++ b/beacon_node/rest_api/src/validator.rs
@@ -5,6 +5,7 @@ use bls::{AggregateSignature, PublicKey, Signature};
use hyper::{Body, Request};
use serde::{Deserialize, Serialize};
use std::sync::Arc;
+use std::borrow::Borrow;
use types::beacon_state::EthSpec;
use types::{Attestation, BitList, Epoch, RelativeEpoch, Shard, Slot};
@@ -33,15 +34,7 @@ impl ValidatorDuty {
/// HTTP Handler to retrieve a the duties for a set of validators during a particular epoch
pub fn get_validator_duties(req: Request) -> ApiResult {
- // Get beacon state
- let beacon_chain = req
- .extensions()
- .get::>>()
- .ok_or_else(|| ApiError::ServerError("Beacon chain extension missing".to_string()))?;
- //TODO Surely this state_cache thing is not necessary?
- let _ = beacon_chain
- .ensure_state_caches_are_built()
- .map_err(|e| ApiError::ServerError(format!("Unable to build state caches: {:?}", e)))?;
+ let beacon_chain = get_beacon_chain_from_request::(&req)?;
let head_state = &beacon_chain.head().beacon_state;
// Parse and check query parameters
@@ -146,15 +139,8 @@ 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 {
- // Get beacon state
- let beacon_chain = req
- .extensions()
- .get::>>()
- .ok_or_else(|| ApiError::ServerError("Beacon chain extension missing".to_string()))?;
- //TODO Surely this state_cache thing is not necessary?
- let _ = beacon_chain
- .ensure_state_caches_are_built()
- .map_err(|e| ApiError::ServerError(format!("Unable to build state caches: {:?}", e)))?;
+ let beacon_chain = get_beacon_chain_from_request::(&req)?;
+ let head_state = &beacon_chain.head().beacon_state;
let query = UrlQuery::from_request(&req)?;
let slot = match query.first_of(&["slot"]) {
@@ -201,17 +187,60 @@ pub fn get_new_beacon_block(req: Request) -
Ok(success_response(body))
}
+/// HTTP Handler to accept a validator-signed BeaconBlock, and publish it to the network.
+pub fn publish_beacon_block(req: Request) -> ApiResult {
+ let beacon_chain = get_beacon_chain_from_request::(&req)?;
+ let head_state = &beacon_chain.head().beacon_state;
+
+ let query = UrlQuery::from_request(&req)?;
+ let slot = match query.first_of(&["slot"]) {
+ Ok((_, v)) => Slot::new(v.parse::().map_err(|e| {
+ ApiError::InvalidQueryParams(format!("Invalid slot parameter, must be a u64. {:?}", e))
+ })?),
+ Err(e) => {
+ return Err(e);
+ }
+ };
+ 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| {
+ ApiError::InvalidQueryParams(format!("randao_reveal is not a valid signature: {:?}", e))
+ })?,
+ Err(e) => {
+ return Err(e);
+ }
+ };
+
+ let new_block = match beacon_chain.produce_block(randao_reveal, slot) {
+ Ok((block, _state)) => block,
+ Err(e) => {
+ return Err(ApiError::ServerError(format!(
+ "Beacon node is not able to produce a block: {:?}",
+ e
+ )));
+ }
+ };
+
+ let body = Body::from(
+ serde_json::to_string(&new_block)
+ .expect("We should always be able to serialize a new block that we produced."),
+ );
+ Ok(success_response(body))
+}
+
+/*
/// 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 {
- // Get beacon state
- let beacon_chain = req
- .extensions()
- .get::>>()
- .ok_or_else(|| ApiError::ServerError("Beacon chain extension missing".to_string()))?;
- //TODO Surely this state_cache thing is not necessary?
- let _ = beacon_chain
- .ensure_state_caches_are_built()
- .map_err(|e| ApiError::ServerError(format!("Unable to build state caches: {:?}", e)))?;
+ let beacon_chain = get_beacon_chain_from_request(req)?;
let head_state = &beacon_chain.head().beacon_state;
let query = UrlQuery::from_request(&req)?;
@@ -340,3 +369,4 @@ pub fn get_new_attestation(req: Request) ->
);
Ok(success_response(body))
}
+*/