From b24482674933406460b40f83fee00a98c6c84135 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Thu, 15 Aug 2019 13:58:04 +1000 Subject: [PATCH] Get bootstrapper working for ENR address --- beacon_node/client/src/beacon_chain_types.rs | 14 ++--- .../{local_bootstrap.rs => bootstrapper.rs} | 55 +++++++++++-------- beacon_node/client/src/lib.rs | 3 +- beacon_node/src/main.rs | 21 ++++++- 4 files changed, 62 insertions(+), 31 deletions(-) rename beacon_node/client/src/{local_bootstrap.rs => bootstrapper.rs} (64%) diff --git a/beacon_node/client/src/beacon_chain_types.rs b/beacon_node/client/src/beacon_chain_types.rs index a5b89b86a..f2f95226a 100644 --- a/beacon_node/client/src/beacon_chain_types.rs +++ b/beacon_node/client/src/beacon_chain_types.rs @@ -1,5 +1,5 @@ +use crate::bootstrapper::Bootstrapper; use crate::error::Result; -use crate::local_bootstrap::BootstrapParams; use crate::{config::GenesisState, ClientConfig}; use beacon_chain::{ lmd_ghost::{LmdGhost, ThreadSafeReducedTree}, @@ -7,7 +7,6 @@ use beacon_chain::{ store::Store, BeaconChain, BeaconChainTypes, }; -use reqwest::Url; use slog::{crit, info, Logger}; use slot_clock::SlotClock; use std::fs::File; @@ -77,13 +76,14 @@ where .map_err(|e| format!("Unable to parse YAML genesis state file: {:?}", e))? } GenesisState::HttpBootstrap { server } => { - let url: Url = - Url::parse(&server).map_err(|e| format!("Invalid bootstrap server url: {}", e))?; + let bootstrapper = Bootstrapper::from_server_string(server.to_string()) + .map_err(|e| format!("Failed to initialize bootstrap client: {}", e))?; - let params = BootstrapParams::from_http_api(url) - .map_err(|e| format!("Failed to bootstrap from HTTP server: {:?}", e))?; + let (state, _block) = bootstrapper + .genesis() + .map_err(|e| format!("Failed to bootstrap genesis state: {}", e))?; - params.genesis_state + state } }; diff --git a/beacon_node/client/src/local_bootstrap.rs b/beacon_node/client/src/bootstrapper.rs similarity index 64% rename from beacon_node/client/src/local_bootstrap.rs rename to beacon_node/client/src/bootstrapper.rs index 5fe5e1b4f..9537f6f90 100644 --- a/beacon_node/client/src/local_bootstrap.rs +++ b/beacon_node/client/src/bootstrapper.rs @@ -14,33 +14,44 @@ impl From for Error { } } -pub struct BootstrapParams { - pub finalized_block: BeaconBlock, - pub finalized_state: BeaconState, - pub genesis_block: BeaconBlock, - pub genesis_state: BeaconState, - pub enr: Enr, +pub struct Bootstrapper { + url: Url, } -impl BootstrapParams { - pub fn from_http_api(url: Url) -> Result { - let slots_per_epoch = get_slots_per_epoch(url.clone()) - .map_err(|e| format!("Unable to get slots per epoch: {:?}", e))?; +impl Bootstrapper { + pub fn from_server_string(server: String) -> Result { + Ok(Self { + url: Url::parse(&server).map_err(|e| format!("Invalid bootstrap server url: {}", e))?, + }) + } + + pub fn enr(&self) -> Result { + get_enr(self.url.clone()).map_err(|e| format!("Unable to get ENR: {:?}", e)) + } + + pub fn genesis(&self) -> Result<(BeaconState, BeaconBlock), String> { let genesis_slot = Slot::new(0); - let finalized_slot = get_finalized_slot(url.clone(), slots_per_epoch.as_u64()) + + let block = get_block(self.url.clone(), genesis_slot) + .map_err(|e| format!("Unable to get genesis block: {:?}", e))?; + let state = get_state(self.url.clone(), genesis_slot) + .map_err(|e| format!("Unable to get genesis state: {:?}", e))?; + + Ok((state, block)) + } + + pub fn finalized(&self) -> Result<(BeaconState, BeaconBlock), String> { + let slots_per_epoch = get_slots_per_epoch(self.url.clone()) + .map_err(|e| format!("Unable to get slots per epoch: {:?}", e))?; + let finalized_slot = get_finalized_slot(self.url.clone(), slots_per_epoch.as_u64()) .map_err(|e| format!("Unable to get finalized slot: {:?}", e))?; - Ok(Self { - finalized_block: get_block(url.clone(), finalized_slot) - .map_err(|e| format!("Unable to get finalized block: {:?}", e))?, - finalized_state: get_state(url.clone(), finalized_slot) - .map_err(|e| format!("Unable to get finalized state: {:?}", e))?, - genesis_block: get_block(url.clone(), genesis_slot) - .map_err(|e| format!("Unable to get genesis block: {:?}", e))?, - genesis_state: get_state(url.clone(), genesis_slot) - .map_err(|e| format!("Unable to get genesis state: {:?}", e))?, - enr: get_enr(url.clone()).map_err(|e| format!("Unable to get ENR: {:?}", e))?, - }) + let block = get_block(self.url.clone(), finalized_slot) + .map_err(|e| format!("Unable to get finalized block: {:?}", e))?; + let state = get_state(self.url.clone(), finalized_slot) + .map_err(|e| format!("Unable to get finalized state: {:?}", e))?; + + Ok((state, block)) } } diff --git a/beacon_node/client/src/lib.rs b/beacon_node/client/src/lib.rs index 44b5c0ce3..798aedec9 100644 --- a/beacon_node/client/src/lib.rs +++ b/beacon_node/client/src/lib.rs @@ -1,8 +1,8 @@ extern crate slog; mod beacon_chain_types; +mod bootstrapper; mod config; -mod local_bootstrap; pub mod error; pub mod notifier; @@ -22,6 +22,7 @@ use tokio::timer::Interval; pub use beacon_chain::BeaconChainTypes; pub use beacon_chain_types::ClientType; pub use beacon_chain_types::InitialiseBeaconChain; +pub use bootstrapper::Bootstrapper; pub use config::{Config as ClientConfig, GenesisState}; pub use eth2_config::Eth2Config; diff --git a/beacon_node/src/main.rs b/beacon_node/src/main.rs index 862ca4a90..5199bddb6 100644 --- a/beacon_node/src/main.rs +++ b/beacon_node/src/main.rs @@ -1,7 +1,7 @@ mod run; use clap::{App, Arg}; -use client::{ClientConfig, Eth2Config, GenesisState}; +use client::{Bootstrapper, ClientConfig, Eth2Config, GenesisState}; use env_logger::{Builder, Env}; use eth2_config::{read_from_file, write_to_file}; use slog::{crit, o, warn, Drain, Level}; @@ -300,9 +300,28 @@ fn main() { // If the `--bootstrap` flag is provided, overwrite the default configuration. if let Some(server) = matches.value_of("bootstrap") { + // Set the genesis state source. client_config.genesis_state = GenesisState::HttpBootstrap { server: server.to_string(), }; + + let bootstrapper = match Bootstrapper::from_server_string(server.to_string()) { + Ok(b) => b, + Err(e) => { + crit!(log, "Failed to load bootstrapper"; "error" => format!("{:?}", e)); + return; + } + }; + + let enr = match bootstrapper.enr() { + Ok(b) => b, + Err(e) => { + crit!(log, "Failed to read ENR from bootstrap server"; "error" => format!("{:?}", e)); + return; + } + }; + + client_config.network.boot_nodes.push(enr); } let eth2_config_path = data_dir.join(ETH2_CONFIG_FILENAME);