mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-15 19:02:42 +00:00
Bootstrap (#501)
* Renamed fork_choice::process_attestation_from_block * Processing attestation in fork choice * Retrieving state from store and checking signature * Looser check on beacon state validity. * Cleaned up get_attestation_state * Expanded fork choice api to provide latest validator message. * Checking if the an attestation contains a latest message * Correct process_attestation error handling. * Copy paste error in comment fixed. * Tidy ancestor iterators * Getting attestation slot via helper method * Refactored attestation creation in test utils * Revert "Refactored attestation creation in test utils" This reverts commit 4d277fe4239a7194758b18fb5c00dfe0b8231306. * Integration tests for free attestation processing * Implicit conflicts resolved. * formatting * Do first pass on Grants code * Add another attestation processing test * Tidy attestation processing * Remove old code fragment * Add non-compiling half finished changes * Simplify, fix bugs, add tests for chain iters * Remove attestation processing from op pool * Fix bug with fork choice, tidy * Fix overly restrictive check in fork choice. * Ensure committee cache is build during attn proc * Ignore unknown blocks at fork choice * Various minor fixes * Make fork choice write lock in to read lock * Remove unused method * Tidy comments * Fix attestation prod. target roots change * Fix compile error in store iters * Reject any attestation prior to finalization * Begin metrics refactor * Move beacon_chain to new metrics structure. * Make metrics not panic if already defined * Use global prometheus gather at rest api * Unify common metric fns into a crate * Add heavy metering to block processing * Remove hypen from prometheus metric name * Add more beacon chain metrics * Add beacon chain persistence metric * Prune op pool on finalization * Add extra prom beacon chain metrics * Prefix BeaconChain metrics with "beacon_" * Add more store metrics * Add basic metrics to libp2p * Add metrics to HTTP server * Remove old `http_server` crate * Update metrics names to be more like standard * Fix broken beacon chain metrics, add slot clock metrics * Add lighthouse_metrics gather fn * Remove http args * Fix wrong state given to op pool prune * Make prom metric names more consistent * Add more metrics, tidy existing metrics * Fix store block read metrics * Tidy attestation metrics * Fix minor PR comments * Fix minor PR comments * Remove duplicated attestation finalization check * Remove awkward `let` statement * Add first attempts at HTTP bootstrap * Add beacon_block methods to rest api * Fix serde for block.body.grafitti * Allow travis failures on beta (see desc) There's a non-backward compatible change in `cargo fmt`. Stable and beta do not agree. * Add network routes to API * Fix rustc warnings * Add best_slot method * Add --bootstrap arg to beacon node * Get bootstrapper working for ENR address * Store intermediate states during block processing * Allow bootstrapper to scrape libp2p address * Update bootstrapper libp2p address finding * Add comments * Tidy API to be more consistent with recent decisions * Address some review comments * Make BeaconChainTypes Send + Sync + 'static * Add `/network/listen_port` API endpoint * Abandon starting the node if libp2p doesn't start * Update bootstrapper for API changes * Remove unnecessary trait bounds
This commit is contained in:
@@ -2,9 +2,114 @@ use super::{success_response, ApiResult};
|
||||
use crate::{helpers::*, ApiError, UrlQuery};
|
||||
use beacon_chain::{BeaconChain, BeaconChainTypes};
|
||||
use hyper::{Body, Request};
|
||||
use serde::Serialize;
|
||||
use std::sync::Arc;
|
||||
use store::Store;
|
||||
use types::BeaconState;
|
||||
use types::{BeaconBlock, BeaconState, EthSpec, Hash256, Slot};
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct HeadResponse {
|
||||
pub slot: Slot,
|
||||
pub block_root: Hash256,
|
||||
pub state_root: Hash256,
|
||||
}
|
||||
|
||||
/// HTTP handler to return a `BeaconBlock` at a given `root` or `slot`.
|
||||
pub fn get_head<T: BeaconChainTypes + 'static>(req: Request<Body>) -> ApiResult {
|
||||
let beacon_chain = req
|
||||
.extensions()
|
||||
.get::<Arc<BeaconChain<T>>>()
|
||||
.ok_or_else(|| ApiError::ServerError("Beacon chain extension missing".to_string()))?;
|
||||
|
||||
let head = HeadResponse {
|
||||
slot: beacon_chain.head().beacon_state.slot,
|
||||
block_root: beacon_chain.head().beacon_block_root,
|
||||
state_root: beacon_chain.head().beacon_state_root,
|
||||
};
|
||||
|
||||
let json: String = serde_json::to_string(&head)
|
||||
.map_err(|e| ApiError::ServerError(format!("Unable to serialize HeadResponse: {:?}", e)))?;
|
||||
|
||||
Ok(success_response(Body::from(json)))
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(bound = "T: EthSpec")]
|
||||
pub struct BlockResponse<T: EthSpec> {
|
||||
pub root: Hash256,
|
||||
pub beacon_block: BeaconBlock<T>,
|
||||
}
|
||||
|
||||
/// HTTP handler to return a `BeaconBlock` at a given `root` or `slot`.
|
||||
pub fn get_block<T: BeaconChainTypes + 'static>(req: Request<Body>) -> ApiResult {
|
||||
let beacon_chain = req
|
||||
.extensions()
|
||||
.get::<Arc<BeaconChain<T>>>()
|
||||
.ok_or_else(|| ApiError::ServerError("Beacon chain extension missing".to_string()))?;
|
||||
|
||||
let query_params = ["root", "slot"];
|
||||
let (key, value) = UrlQuery::from_request(&req)?.first_of(&query_params)?;
|
||||
|
||||
let block_root = match (key.as_ref(), value) {
|
||||
("slot", value) => {
|
||||
let target = parse_slot(&value)?;
|
||||
|
||||
block_root_at_slot(&beacon_chain, target).ok_or_else(|| {
|
||||
ApiError::NotFound(format!("Unable to find BeaconBlock for slot {}", target))
|
||||
})?
|
||||
}
|
||||
("root", value) => parse_root(&value)?,
|
||||
_ => return Err(ApiError::ServerError("Unexpected query parameter".into())),
|
||||
};
|
||||
|
||||
let block = beacon_chain
|
||||
.store
|
||||
.get::<BeaconBlock<T::EthSpec>>(&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,
|
||||
};
|
||||
|
||||
let json: String = serde_json::to_string(&response).map_err(|e| {
|
||||
ApiError::ServerError(format!("Unable to serialize BlockResponse: {:?}", e))
|
||||
})?;
|
||||
|
||||
Ok(success_response(Body::from(json)))
|
||||
}
|
||||
|
||||
/// HTTP handler to return a `BeaconBlock` root at a given `slot`.
|
||||
pub fn get_block_root<T: BeaconChainTypes + 'static>(req: Request<Body>) -> ApiResult {
|
||||
let beacon_chain = req
|
||||
.extensions()
|
||||
.get::<Arc<BeaconChain<T>>>()
|
||||
.ok_or_else(|| ApiError::ServerError("Beacon chain extension missing".to_string()))?;
|
||||
|
||||
let slot_string = UrlQuery::from_request(&req)?.only_one("slot")?;
|
||||
let target = parse_slot(&slot_string)?;
|
||||
|
||||
let root = block_root_at_slot(&beacon_chain, target).ok_or_else(|| {
|
||||
ApiError::NotFound(format!("Unable to find BeaconBlock for slot {}", target))
|
||||
})?;
|
||||
|
||||
let json: String = serde_json::to_string(&root)
|
||||
.map_err(|e| ApiError::ServerError(format!("Unable to serialize root: {:?}", e)))?;
|
||||
|
||||
Ok(success_response(Body::from(json)))
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(bound = "T: EthSpec")]
|
||||
pub struct StateResponse<T: EthSpec> {
|
||||
pub root: Hash256,
|
||||
pub beacon_state: BeaconState<T>,
|
||||
}
|
||||
|
||||
/// HTTP handler to return a `BeaconState` at a given `root` or `slot`.
|
||||
///
|
||||
@@ -19,26 +124,34 @@ pub fn get_state<T: BeaconChainTypes + 'static>(req: Request<Body>) -> ApiResult
|
||||
let query_params = ["root", "slot"];
|
||||
let (key, value) = UrlQuery::from_request(&req)?.first_of(&query_params)?;
|
||||
|
||||
let state: BeaconState<T::EthSpec> = match (key.as_ref(), value) {
|
||||
let (root, state): (Hash256, BeaconState<T::EthSpec>) = match (key.as_ref(), value) {
|
||||
("slot", value) => state_at_slot(&beacon_chain, parse_slot(&value)?)?,
|
||||
("root", value) => {
|
||||
let root = &parse_root(&value)?;
|
||||
|
||||
beacon_chain
|
||||
let state = beacon_chain
|
||||
.store
|
||||
.get(root)?
|
||||
.ok_or_else(|| ApiError::NotFound(format!("No state for root: {}", root)))?
|
||||
.ok_or_else(|| ApiError::NotFound(format!("No state for root: {}", root)))?;
|
||||
|
||||
(*root, state)
|
||||
}
|
||||
_ => unreachable!("Guarded by UrlQuery::from_request()"),
|
||||
_ => return Err(ApiError::ServerError("Unexpected query parameter".into())),
|
||||
};
|
||||
|
||||
let json: String = serde_json::to_string(&state)
|
||||
.map_err(|e| ApiError::ServerError(format!("Unable to serialize BeaconState: {:?}", e)))?;
|
||||
let response = StateResponse {
|
||||
root,
|
||||
beacon_state: state,
|
||||
};
|
||||
|
||||
let json: String = serde_json::to_string(&response).map_err(|e| {
|
||||
ApiError::ServerError(format!("Unable to serialize StateResponse: {:?}", e))
|
||||
})?;
|
||||
|
||||
Ok(success_response(Body::from(json)))
|
||||
}
|
||||
|
||||
/// HTTP handler to return a `BeaconState` root at a given or `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
|
||||
/// the current head by skipping slots.
|
||||
@@ -58,3 +171,24 @@ pub fn get_state_root<T: BeaconChainTypes + 'static>(req: Request<Body>) -> ApiR
|
||||
|
||||
Ok(success_response(Body::from(json)))
|
||||
}
|
||||
|
||||
/// HTTP handler to return the highest finalized slot.
|
||||
pub fn get_latest_finalized_checkpoint<T: BeaconChainTypes + 'static>(
|
||||
req: Request<Body>,
|
||||
) -> ApiResult {
|
||||
let beacon_chain = req
|
||||
.extensions()
|
||||
.get::<Arc<BeaconChain<T>>>()
|
||||
.ok_or_else(|| ApiError::ServerError("Beacon chain extension missing".to_string()))?;
|
||||
|
||||
let checkpoint = beacon_chain
|
||||
.head()
|
||||
.beacon_state
|
||||
.finalized_checkpoint
|
||||
.clone();
|
||||
|
||||
let json: String = serde_json::to_string(&checkpoint)
|
||||
.map_err(|e| ApiError::ServerError(format!("Unable to serialize checkpoint: {:?}", e)))?;
|
||||
|
||||
Ok(success_response(Body::from(json)))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user