Allow bootstrapper to scrape libp2p address

This commit is contained in:
Paul Hauner
2019-08-15 16:41:02 +10:00
parent 4678524659
commit ce37f95861
8 changed files with 107 additions and 33 deletions

View File

@@ -1,6 +1,8 @@
use eth2_libp2p::Enr;
use eth2_libp2p::{Enr, Multiaddr};
use reqwest::{Error as HttpError, Url};
use std::net::Ipv4Addr;
use types::{BeaconBlock, BeaconState, Checkpoint, EthSpec, Slot};
use url::Host;
#[derive(Debug)]
enum Error {
@@ -25,10 +27,22 @@ impl Bootstrapper {
})
}
pub fn server_ipv4_addr(&self) -> Option<Ipv4Addr> {
match self.url.host()? {
Host::Ipv4(addr) => Some(addr),
_ => None,
}
}
pub fn enr(&self) -> Result<Enr, String> {
get_enr(self.url.clone()).map_err(|e| format!("Unable to get ENR: {:?}", e))
}
pub fn listen_addresses(&self) -> Result<Vec<Multiaddr>, String> {
get_listen_addresses(self.url.clone())
.map_err(|e| format!("Unable to get listen addresses: {:?}", e))
}
pub fn genesis<T: EthSpec>(&self) -> Result<(BeaconState<T>, BeaconBlock<T>), String> {
let genesis_slot = Slot::new(0);
@@ -124,3 +138,16 @@ fn get_enr(mut url: Url) -> Result<Enr, Error> {
.json()
.map_err(Into::into)
}
fn get_listen_addresses(mut url: Url) -> Result<Vec<Multiaddr>, Error> {
url.path_segments_mut()
.map(|mut url| {
url.push("node").push("network").push("listen_addresses");
})
.map_err(|_| Error::UrlCannotBeBase)?;
reqwest::get(url)?
.error_for_status()?
.json()
.map_err(Into::into)
}

View File

@@ -1,8 +1,9 @@
use crate::Eth2Config;
use crate::{Bootstrapper, Eth2Config};
use clap::ArgMatches;
use eth2_libp2p::multiaddr::{Multiaddr, Protocol};
use network::NetworkConfig;
use serde_derive::{Deserialize, Serialize};
use slog::{info, o, Drain};
use slog::{info, o, warn, Drain};
use std::fs::{self, OpenOptions};
use std::path::PathBuf;
use std::sync::Mutex;
@@ -149,6 +150,43 @@ impl Config {
self.update_logger(log)?;
};
// If the `--bootstrap` flag is provided, overwrite the default configuration.
if let Some(server) = args.value_of("bootstrap") {
do_bootstrapping(self, server.to_string(), &log)?;
}
Ok(())
}
}
fn do_bootstrapping(config: &mut Config, server: String, log: &slog::Logger) -> Result<(), String> {
// Set the genesis state source.
config.genesis_state = GenesisState::HttpBootstrap {
server: server.to_string(),
};
let bootstrapper = Bootstrapper::from_server_string(server.to_string())?;
config.network.boot_nodes.push(bootstrapper.enr()?);
if let Some(server_ip) = bootstrapper.server_ipv4_addr() {
let server_multiaddr: Multiaddr = bootstrapper
.listen_addresses()?
.first()
.ok_or_else(|| "Bootstrap peer returned an empty list of listen addresses")?
// Iterate through the components of the Multiaddr, replacing any Ipv4 address with the
// server address.
.iter()
.map(|protocol| match protocol {
Protocol::Ip4(_) => Protocol::Ip4(server_ip),
_ => protocol,
})
.collect::<Multiaddr>();
config.network.libp2p_nodes.push(server_multiaddr);
} else {
warn!(log, "Unable to determine bootstrap server Ipv4 address. Unable to add server as libp2p peer.");
}
Ok(())
}