Make bootstrapper block til connection established

This commit is contained in:
Paul Hauner 2019-09-04 13:56:30 +10:00
parent 009a7eb9c7
commit 572df4f37e
No known key found for this signature in database
GPG Key ID: 303E4494BB28068C
5 changed files with 44 additions and 11 deletions

View File

@ -87,7 +87,7 @@ impl<T: BeaconChainTypes> BeaconChainBuilder<T> {
}
pub fn http_bootstrap(server: &str, spec: ChainSpec, log: Logger) -> Result<Self, String> {
let bootstrapper = Bootstrapper::from_server_string(server.to_string())
let bootstrapper = Bootstrapper::connect(server.to_string(), &log)
.map_err(|e| format!("Failed to initialize bootstrap client: {}", e))?;
let (genesis_state, genesis_block) = bootstrapper

View File

@ -310,7 +310,7 @@ impl<'a> ConfigBuilder<'a> {
server: &str,
port: Option<u16>,
) -> Result<()> {
let bootstrapper = Bootstrapper::from_server_string(server.to_string())?;
let bootstrapper = Bootstrapper::connect(server.to_string(), &self.log)?;
if let Some(server_multiaddr) = bootstrapper.best_effort_multiaddr(port) {
info!(
@ -347,7 +347,7 @@ impl<'a> ConfigBuilder<'a> {
/// 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())?;
let bootstrapper = Bootstrapper::connect(server.to_string(), &self.log)?;
self.update_eth2_config(bootstrapper.eth2_config()?);

View File

@ -13,3 +13,4 @@ reqwest = "0.9"
url = "1.2"
types = { path = "../../types" }
serde = "1.0"
slog = { version = "^2.2.3" , features = ["max_level_trace", "release_max_level_trace"] }

View File

@ -5,11 +5,16 @@ use eth2_libp2p::{
};
use reqwest::{Error as HttpError, Url};
use serde::Deserialize;
use slog::{error, Logger};
use std::borrow::Cow;
use std::net::Ipv4Addr;
use std::time::Duration;
use types::{BeaconBlock, BeaconState, Checkpoint, EthSpec, Hash256, Slot};
use url::Host;
pub const RETRY_SLEEP_MILLIS: u64 = 100;
pub const RETRY_WARN_INTERVAL: u64 = 30;
#[derive(Debug)]
enum Error {
InvalidUrl,
@ -31,11 +36,35 @@ pub struct Bootstrapper {
}
impl Bootstrapper {
/// Parses the given `server` as a URL, instantiating `Self`.
pub fn from_server_string(server: String) -> Result<Self, String> {
Ok(Self {
/// Parses the given `server` as a URL, instantiating `Self` and blocking until a connection
/// can be made with the server.
///
/// Never times out.
pub fn connect(server: String, log: &Logger) -> Result<Self, String> {
let bootstrapper = Self {
url: Url::parse(&server).map_err(|e| format!("Invalid bootstrap server url: {}", e))?,
})
};
let mut retry_count = 0;
loop {
match bootstrapper.enr() {
Ok(_) => break,
Err(_) => {
if retry_count % RETRY_WARN_INTERVAL == 0 {
error!(
log,
"Failed to contact bootstrap server";
"retry_count" => retry_count,
"retry_delay_millis" => RETRY_SLEEP_MILLIS,
);
}
retry_count += 1;
std::thread::sleep(Duration::from_millis(RETRY_SLEEP_MILLIS));
}
}
}
Ok(bootstrapper)
}
/// Build a multiaddr using the HTTP server URL that is not guaranteed to be correct.

View File

@ -247,10 +247,13 @@ fn process_testnet_subcommand(
) -> Result<(ClientConfig, Eth2Config)> {
let eth2_config = if cli_args.is_present("bootstrap") {
info!(log, "Connecting to bootstrap server");
let bootstrapper = Bootstrapper::from_server_string(format!(
"http://{}:{}",
client_config.server, client_config.server_http_port
))?;
let bootstrapper = Bootstrapper::connect(
format!(
"http://{}:{}",
client_config.server, client_config.server_http_port
),
&log,
)?;
let eth2_config = bootstrapper.eth2_config()?;