Pull Eth2Config during bootstrap

This commit is contained in:
Paul Hauner 2019-08-27 00:04:15 +10:00
parent 81c898586e
commit 6875ae8af5
No known key found for this signature in database
GPG Key ID: 303E4494BB28068C
7 changed files with 63 additions and 0 deletions

View File

@ -5,6 +5,7 @@ authors = ["Paul Hauner <paul@paulhauner.com>", "Age Manning <Age@AgeManning.com
edition = "2018"
[dependencies]
eth2_config = { path = "../../eth2/utils/eth2_config" }
store = { path = "../store" }
parking_lot = "0.7"
lazy_static = "1.3.0"

View File

@ -1,3 +1,4 @@
use eth2_config::Eth2Config;
use eth2_libp2p::{
multiaddr::{Multiaddr, Protocol},
Enr,
@ -74,6 +75,11 @@ impl Bootstrapper {
}
}
/// Returns the servers Eth2Config.
pub fn eth2_config(&self) -> Result<Eth2Config, String> {
get_eth2_config(self.url.clone()).map_err(|e| format!("Unable to get Eth2Config: {:?}", e))
}
/// Returns the servers ENR address.
pub fn enr(&self) -> Result<Enr, String> {
get_enr(self.url.clone()).map_err(|e| format!("Unable to get ENR: {:?}", e))
@ -129,6 +135,19 @@ fn get_slots_per_epoch(mut url: Url) -> Result<Slot, Error> {
.map_err(Into::into)
}
fn get_eth2_config(mut url: Url) -> Result<Eth2Config, Error> {
url.path_segments_mut()
.map(|mut url| {
url.push("spec").push("eth2_config");
})
.map_err(|_| Error::InvalidUrl)?;
reqwest::get(url)?
.error_for_status()?
.json()
.map_err(Into::into)
}
fn get_finalized_slot(mut url: Url, slots_per_epoch: u64) -> Result<Slot, Error> {
url.path_segments_mut()
.map(|mut url| {

View File

@ -162,6 +162,7 @@ where
beacon_chain.clone(),
network.clone(),
client_config.db_path().expect("unable to read datadir"),
eth2_config.clone(),
&log,
) {
Ok(s) => Some(s),

View File

@ -27,5 +27,6 @@ exit-future = "0.1.3"
tokio = "0.1.17"
url = "2.0"
lazy_static = "1.3.0"
eth2_config = { path = "../../eth2/utils/eth2_config" }
lighthouse_metrics = { path = "../../eth2/utils/lighthouse_metrics" }
slot_clock = { path = "../../eth2/utils/slot_clock" }

View File

@ -13,6 +13,7 @@ mod url_query;
use beacon_chain::{BeaconChain, BeaconChainTypes};
use client_network::Service as NetworkService;
use eth2_config::Eth2Config;
use hyper::rt::Future;
use hyper::service::service_fn_ok;
use hyper::{Body, Method, Response, Server, StatusCode};
@ -79,6 +80,7 @@ pub fn start_server<T: BeaconChainTypes>(
beacon_chain: Arc<BeaconChain<T>>,
network_service: Arc<NetworkService<T>>,
db_path: PathBuf,
eth2_config: Eth2Config,
log: &slog::Logger,
) -> Result<exit_future::Signal, hyper::Error> {
let log = log.new(o!("Service" => "Api"));
@ -100,12 +102,14 @@ pub fn start_server<T: BeaconChainTypes>(
// Clone our stateful objects, for use in service closure.
let server_log = log.clone();
let server_bc = beacon_chain.clone();
let eth2_config = Arc::new(eth2_config);
let service = move || {
let log = server_log.clone();
let beacon_chain = server_bc.clone();
let db_path = db_path.clone();
let network_service = network_service.clone();
let eth2_config = eth2_config.clone();
// Create a simple handler for the router, inject our stateful objects into the request.
service_fn_ok(move |mut req| {
@ -118,6 +122,8 @@ pub fn start_server<T: BeaconChainTypes>(
req.extensions_mut().insert::<DBPath>(db_path.clone());
req.extensions_mut()
.insert::<Arc<NetworkService<T>>>(network_service.clone());
req.extensions_mut()
.insert::<Arc<Eth2Config>>(eth2_config.clone());
let path = req.uri().path().to_string();
@ -144,6 +150,7 @@ pub fn start_server<T: BeaconChainTypes>(
(&Method::GET, "/node/genesis_time") => node::get_genesis_time::<T>(req),
(&Method::GET, "/spec") => spec::get_spec::<T>(req),
(&Method::GET, "/spec/slots_per_epoch") => spec::get_slots_per_epoch::<T>(req),
(&Method::GET, "/spec/eth2_config") => spec::get_eth2_config::<T>(req),
_ => Err(ApiError::MethodNotAllowed(path.clone())),
};

View File

@ -1,6 +1,7 @@
use super::{success_response, ApiResult};
use crate::ApiError;
use beacon_chain::{BeaconChain, BeaconChainTypes};
use eth2_config::Eth2Config;
use hyper::{Body, Request};
use std::sync::Arc;
use types::EthSpec;
@ -18,6 +19,19 @@ pub fn get_spec<T: BeaconChainTypes + 'static>(req: Request<Body>) -> ApiResult
Ok(success_response(Body::from(json)))
}
/// HTTP handler to return the full Eth2Config object.
pub fn get_eth2_config<T: BeaconChainTypes + 'static>(req: Request<Body>) -> ApiResult {
let eth2_config = req
.extensions()
.get::<Arc<Eth2Config>>()
.ok_or_else(|| ApiError::ServerError("Eth2Config extension missing".to_string()))?;
let json: String = serde_json::to_string(eth2_config.as_ref())
.map_err(|e| ApiError::ServerError(format!("Unable to serialize Eth2Config: {:?}", e)))?;
Ok(success_response(Body::from(json)))
}
/// HTTP handler to return the full spec object.
pub fn get_slots_per_epoch<T: BeaconChainTypes + 'static>(_req: Request<Body>) -> ApiResult {
let json: String = serde_json::to_string(&T::EthSpec::slots_per_epoch())

View File

@ -63,7 +63,13 @@ fn process_testnet_subcommand(
builder.set_random_datadir()?;
}
let is_bootstrap = cli_args.subcommand_name() == Some("bootstrap");
if let Some(path_string) = cli_args.value_of("eth2-config") {
if is_bootstrap {
return Err("Cannot supply --eth2-config when using bootsrap".to_string());
}
let path = path_string
.parse::<PathBuf>()
.map_err(|e| format!("Unable to parse eth2-config path: {:?}", e))?;
@ -100,6 +106,7 @@ fn process_testnet_subcommand(
.and_then(|s| s.parse::<u16>().ok());
builder.import_bootstrap_libp2p_address(server, port)?;
builder.import_bootstrap_eth2_config(server)?;
builder.set_beacon_chain_start_method(BeaconChainStartMethod::HttpBootstrap {
server: server.to_string(),
@ -252,6 +259,19 @@ impl<'a> ConfigBuilder<'a> {
Ok(())
}
/// Imports an `Eth2Config` from `server`, returning an error if this fails.
pub fn import_bootstrap_eth2_config(&mut self, server: &str) -> Result<()> {
let bootstrapper = Bootstrapper::from_server_string(server.to_string())?;
self.update_eth2_config(bootstrapper.eth2_config()?);
Ok(())
}
fn update_eth2_config(&mut self, eth2_config: Eth2Config) {
self.eth2_config = eth2_config;
}
/// Reads the subcommand and tries to update `self.eth2_config` based up on the `--spec` flag.
///
/// Returns an error if the `--spec` flag is not present in the given `cli_args`.