Merge branch 'bootstrap' into interop
This commit is contained in:
commit
bb63d300f2
@ -55,7 +55,7 @@ where
|
|||||||
impl<L, E> BeaconChainTypes for CommonTypes<L, E>
|
impl<L, E> BeaconChainTypes for CommonTypes<L, E>
|
||||||
where
|
where
|
||||||
L: LmdGhost<MemoryStore, E> + 'static,
|
L: LmdGhost<MemoryStore, E> + 'static,
|
||||||
E: EthSpec + 'static,
|
E: EthSpec,
|
||||||
{
|
{
|
||||||
type Store = MemoryStore;
|
type Store = MemoryStore;
|
||||||
type SlotClock = TestingSlotClock;
|
type SlotClock = TestingSlotClock;
|
||||||
@ -70,7 +70,7 @@ where
|
|||||||
pub struct BeaconChainHarness<L, E>
|
pub struct BeaconChainHarness<L, E>
|
||||||
where
|
where
|
||||||
L: LmdGhost<MemoryStore, E> + 'static,
|
L: LmdGhost<MemoryStore, E> + 'static,
|
||||||
E: EthSpec + 'static,
|
E: EthSpec,
|
||||||
{
|
{
|
||||||
pub chain: BeaconChain<CommonTypes<L, E>>,
|
pub chain: BeaconChain<CommonTypes<L, E>>,
|
||||||
pub keypairs: Vec<Keypair>,
|
pub keypairs: Vec<Keypair>,
|
||||||
|
@ -39,7 +39,7 @@ pub struct ClientType<S: Store, E: EthSpec> {
|
|||||||
impl<S, E> BeaconChainTypes for ClientType<S, E>
|
impl<S, E> BeaconChainTypes for ClientType<S, E>
|
||||||
where
|
where
|
||||||
S: Store + 'static,
|
S: Store + 'static,
|
||||||
E: EthSpec + 'static + Clone,
|
E: EthSpec,
|
||||||
{
|
{
|
||||||
type Store = S;
|
type Store = S;
|
||||||
type SlotClock = SystemTimeSlotClock;
|
type SlotClock = SystemTimeSlotClock;
|
||||||
|
@ -3,9 +3,10 @@ use eth2_libp2p::{
|
|||||||
Enr,
|
Enr,
|
||||||
};
|
};
|
||||||
use reqwest::{Error as HttpError, Url};
|
use reqwest::{Error as HttpError, Url};
|
||||||
|
use serde::Deserialize;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::net::Ipv4Addr;
|
use std::net::Ipv4Addr;
|
||||||
use types::{BeaconBlock, BeaconState, Checkpoint, EthSpec, Slot};
|
use types::{BeaconBlock, BeaconState, Checkpoint, EthSpec, Hash256, Slot};
|
||||||
use url::Host;
|
use url::Host;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -46,7 +47,7 @@ impl Bootstrapper {
|
|||||||
/// `/ipv4/192.168.0.1/tcp/9000` if the server advertises a listening address of
|
/// `/ipv4/192.168.0.1/tcp/9000` if the server advertises a listening address of
|
||||||
/// `/ipv4/172.0.0.1/tcp/9000`.
|
/// `/ipv4/172.0.0.1/tcp/9000`.
|
||||||
pub fn best_effort_multiaddr(&self) -> Option<Multiaddr> {
|
pub fn best_effort_multiaddr(&self) -> Option<Multiaddr> {
|
||||||
let tcp_port = self.first_listening_tcp_port()?;
|
let tcp_port = self.listen_port().ok()?;
|
||||||
|
|
||||||
let mut multiaddr = Multiaddr::with_capacity(2);
|
let mut multiaddr = Multiaddr::with_capacity(2);
|
||||||
|
|
||||||
@ -61,17 +62,6 @@ impl Bootstrapper {
|
|||||||
Some(multiaddr)
|
Some(multiaddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reads the server's listening libp2p addresses and returns the first TCP port protocol it
|
|
||||||
/// finds, if any.
|
|
||||||
fn first_listening_tcp_port(&self) -> Option<u16> {
|
|
||||||
self.listen_addresses().ok()?.iter().find_map(|multiaddr| {
|
|
||||||
multiaddr.iter().find_map(|protocol| match protocol {
|
|
||||||
Protocol::Tcp(port) => Some(port),
|
|
||||||
_ => None,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the IPv4 address of the server URL, unless it contains a FQDN.
|
/// Returns the IPv4 address of the server URL, unless it contains a FQDN.
|
||||||
pub fn server_ipv4_addr(&self) -> Option<Ipv4Addr> {
|
pub fn server_ipv4_addr(&self) -> Option<Ipv4Addr> {
|
||||||
match self.url.host()? {
|
match self.url.host()? {
|
||||||
@ -86,9 +76,8 @@ impl Bootstrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the servers listening libp2p addresses.
|
/// Returns the servers listening libp2p addresses.
|
||||||
pub fn listen_addresses(&self) -> Result<Vec<Multiaddr>, String> {
|
pub fn listen_port(&self) -> Result<u16, String> {
|
||||||
get_listen_addresses(self.url.clone())
|
get_listen_port(self.url.clone()).map_err(|e| format!("Unable to get listen port: {:?}", e))
|
||||||
.map_err(|e| format!("Unable to get listen addresses: {:?}", e))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the genesis block and state.
|
/// Returns the genesis block and state.
|
||||||
@ -96,9 +85,11 @@ impl Bootstrapper {
|
|||||||
let genesis_slot = Slot::new(0);
|
let genesis_slot = Slot::new(0);
|
||||||
|
|
||||||
let block = get_block(self.url.clone(), genesis_slot)
|
let block = get_block(self.url.clone(), genesis_slot)
|
||||||
.map_err(|e| format!("Unable to get genesis block: {:?}", e))?;
|
.map_err(|e| format!("Unable to get genesis block: {:?}", e))?
|
||||||
|
.beacon_block;
|
||||||
let state = get_state(self.url.clone(), genesis_slot)
|
let state = get_state(self.url.clone(), genesis_slot)
|
||||||
.map_err(|e| format!("Unable to get genesis state: {:?}", e))?;
|
.map_err(|e| format!("Unable to get genesis state: {:?}", e))?
|
||||||
|
.beacon_state;
|
||||||
|
|
||||||
Ok((state, block))
|
Ok((state, block))
|
||||||
}
|
}
|
||||||
@ -111,9 +102,11 @@ impl Bootstrapper {
|
|||||||
.map_err(|e| format!("Unable to get finalized slot: {:?}", e))?;
|
.map_err(|e| format!("Unable to get finalized slot: {:?}", e))?;
|
||||||
|
|
||||||
let block = get_block(self.url.clone(), finalized_slot)
|
let block = get_block(self.url.clone(), finalized_slot)
|
||||||
.map_err(|e| format!("Unable to get finalized block: {:?}", e))?;
|
.map_err(|e| format!("Unable to get finalized block: {:?}", e))?
|
||||||
|
.beacon_block;
|
||||||
let state = get_state(self.url.clone(), finalized_slot)
|
let state = get_state(self.url.clone(), finalized_slot)
|
||||||
.map_err(|e| format!("Unable to get finalized state: {:?}", e))?;
|
.map_err(|e| format!("Unable to get finalized state: {:?}", e))?
|
||||||
|
.beacon_state;
|
||||||
|
|
||||||
Ok((state, block))
|
Ok((state, block))
|
||||||
}
|
}
|
||||||
@ -144,7 +137,14 @@ fn get_finalized_slot(mut url: Url, slots_per_epoch: u64) -> Result<Slot, Error>
|
|||||||
Ok(checkpoint.epoch.start_slot(slots_per_epoch))
|
Ok(checkpoint.epoch.start_slot(slots_per_epoch))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_state<T: EthSpec>(mut url: Url, slot: Slot) -> Result<BeaconState<T>, Error> {
|
#[derive(Deserialize)]
|
||||||
|
#[serde(bound = "T: EthSpec")]
|
||||||
|
pub struct StateResponse<T: EthSpec> {
|
||||||
|
pub root: Hash256,
|
||||||
|
pub beacon_state: BeaconState<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_state<T: EthSpec>(mut url: Url, slot: Slot) -> Result<StateResponse<T>, Error> {
|
||||||
url.path_segments_mut()
|
url.path_segments_mut()
|
||||||
.map(|mut url| {
|
.map(|mut url| {
|
||||||
url.push("beacon").push("state");
|
url.push("beacon").push("state");
|
||||||
@ -160,7 +160,14 @@ fn get_state<T: EthSpec>(mut url: Url, slot: Slot) -> Result<BeaconState<T>, Err
|
|||||||
.map_err(Into::into)
|
.map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_block<T: EthSpec>(mut url: Url, slot: Slot) -> Result<BeaconBlock<T>, Error> {
|
#[derive(Deserialize)]
|
||||||
|
#[serde(bound = "T: EthSpec")]
|
||||||
|
pub struct BlockResponse<T: EthSpec> {
|
||||||
|
pub root: Hash256,
|
||||||
|
pub beacon_block: BeaconBlock<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_block<T: EthSpec>(mut url: Url, slot: Slot) -> Result<BlockResponse<T>, Error> {
|
||||||
url.path_segments_mut()
|
url.path_segments_mut()
|
||||||
.map(|mut url| {
|
.map(|mut url| {
|
||||||
url.push("beacon").push("block");
|
url.push("beacon").push("block");
|
||||||
@ -179,7 +186,7 @@ fn get_block<T: EthSpec>(mut url: Url, slot: Slot) -> Result<BeaconBlock<T>, Err
|
|||||||
fn get_enr(mut url: Url) -> Result<Enr, Error> {
|
fn get_enr(mut url: Url) -> Result<Enr, Error> {
|
||||||
url.path_segments_mut()
|
url.path_segments_mut()
|
||||||
.map(|mut url| {
|
.map(|mut url| {
|
||||||
url.push("node").push("network").push("enr");
|
url.push("network").push("enr");
|
||||||
})
|
})
|
||||||
.map_err(|_| Error::InvalidUrl)?;
|
.map_err(|_| Error::InvalidUrl)?;
|
||||||
|
|
||||||
@ -189,10 +196,10 @@ fn get_enr(mut url: Url) -> Result<Enr, Error> {
|
|||||||
.map_err(Into::into)
|
.map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_listen_addresses(mut url: Url) -> Result<Vec<Multiaddr>, Error> {
|
fn get_listen_port(mut url: Url) -> Result<u16, Error> {
|
||||||
url.path_segments_mut()
|
url.path_segments_mut()
|
||||||
.map(|mut url| {
|
.map(|mut url| {
|
||||||
url.push("node").push("network").push("listen_addresses");
|
url.push("network").push("listen_port");
|
||||||
})
|
})
|
||||||
.map_err(|_| Error::InvalidUrl)?;
|
.map_err(|_| Error::InvalidUrl)?;
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ use libp2p::core::{
|
|||||||
upgrade::{InboundUpgradeExt, OutboundUpgradeExt},
|
upgrade::{InboundUpgradeExt, OutboundUpgradeExt},
|
||||||
};
|
};
|
||||||
use libp2p::{core, secio, PeerId, Swarm, Transport};
|
use libp2p::{core, secio, PeerId, Swarm, Transport};
|
||||||
use slog::{debug, info, trace, warn};
|
use slog::{crit, debug, info, trace, warn};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::io::{Error, ErrorKind};
|
use std::io::{Error, ErrorKind};
|
||||||
@ -69,10 +69,15 @@ impl Service {
|
|||||||
log_address.push(Protocol::P2p(local_peer_id.clone().into()));
|
log_address.push(Protocol::P2p(local_peer_id.clone().into()));
|
||||||
info!(log, "Listening on: {}", log_address);
|
info!(log, "Listening on: {}", log_address);
|
||||||
}
|
}
|
||||||
Err(err) => warn!(
|
Err(err) => {
|
||||||
|
crit!(
|
||||||
log,
|
log,
|
||||||
"Cannot listen on: {} because: {:?}", listen_multiaddr, err
|
"Unable to listen on libp2p address";
|
||||||
),
|
"error" => format!("{:?}", err),
|
||||||
|
"listen_multiaddr" => format!("{}", listen_multiaddr),
|
||||||
|
);
|
||||||
|
return Err("Libp2p was unable to listen on the given listen address.".into());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// attempt to connect to user-input libp2p nodes
|
// attempt to connect to user-input libp2p nodes
|
||||||
|
@ -18,6 +18,7 @@ use tokio::sync::{mpsc, oneshot};
|
|||||||
/// Service that handles communication between internal services and the eth2_libp2p network service.
|
/// Service that handles communication between internal services and the eth2_libp2p network service.
|
||||||
pub struct Service<T: BeaconChainTypes> {
|
pub struct Service<T: BeaconChainTypes> {
|
||||||
libp2p_service: Arc<Mutex<LibP2PService>>,
|
libp2p_service: Arc<Mutex<LibP2PService>>,
|
||||||
|
libp2p_port: u16,
|
||||||
_libp2p_exit: oneshot::Sender<()>,
|
_libp2p_exit: oneshot::Sender<()>,
|
||||||
_network_send: mpsc::UnboundedSender<NetworkMessage>,
|
_network_send: mpsc::UnboundedSender<NetworkMessage>,
|
||||||
_phantom: PhantomData<T>, //message_handler: MessageHandler,
|
_phantom: PhantomData<T>, //message_handler: MessageHandler,
|
||||||
@ -56,6 +57,7 @@ impl<T: BeaconChainTypes + 'static> Service<T> {
|
|||||||
)?;
|
)?;
|
||||||
let network_service = Service {
|
let network_service = Service {
|
||||||
libp2p_service,
|
libp2p_service,
|
||||||
|
libp2p_port: config.libp2p_port,
|
||||||
_libp2p_exit: libp2p_exit,
|
_libp2p_exit: libp2p_exit,
|
||||||
_network_send: network_send.clone(),
|
_network_send: network_send.clone(),
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
@ -87,6 +89,11 @@ impl<T: BeaconChainTypes + 'static> Service<T> {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the libp2p port that this node has been configured to listen using.
|
||||||
|
pub fn listen_port(&self) -> u16 {
|
||||||
|
self.libp2p_port
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the number of libp2p connected peers.
|
/// Returns the number of libp2p connected peers.
|
||||||
pub fn connected_peers(&self) -> usize {
|
pub fn connected_peers(&self) -> usize {
|
||||||
self.libp2p_service.lock().swarm.connected_peers()
|
self.libp2p_service.lock().swarm.connected_peers()
|
||||||
|
@ -8,7 +8,7 @@ use store::Store;
|
|||||||
use types::{BeaconBlock, BeaconState, EthSpec, Hash256, Slot};
|
use types::{BeaconBlock, BeaconState, EthSpec, Hash256, Slot};
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
struct HeadResponse {
|
pub struct HeadResponse {
|
||||||
pub slot: Slot,
|
pub slot: Slot,
|
||||||
pub block_root: Hash256,
|
pub block_root: Hash256,
|
||||||
pub state_root: Hash256,
|
pub state_root: Hash256,
|
||||||
@ -35,7 +35,7 @@ pub fn get_head<T: BeaconChainTypes + 'static>(req: Request<Body>) -> ApiResult
|
|||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
#[serde(bound = "T: EthSpec")]
|
#[serde(bound = "T: EthSpec")]
|
||||||
struct BlockResponse<T: EthSpec> {
|
pub struct BlockResponse<T: EthSpec> {
|
||||||
pub root: Hash256,
|
pub root: Hash256,
|
||||||
pub beacon_block: BeaconBlock<T>,
|
pub beacon_block: BeaconBlock<T>,
|
||||||
}
|
}
|
||||||
@ -106,7 +106,7 @@ pub fn get_block_root<T: BeaconChainTypes + 'static>(req: Request<Body>) -> ApiR
|
|||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
#[serde(bound = "T: EthSpec")]
|
#[serde(bound = "T: EthSpec")]
|
||||||
struct StateResponse<T: EthSpec> {
|
pub struct StateResponse<T: EthSpec> {
|
||||||
pub root: Hash256,
|
pub root: Hash256,
|
||||||
pub beacon_state: BeaconState<T>,
|
pub beacon_state: BeaconState<T>,
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,6 @@ mod url_query;
|
|||||||
|
|
||||||
use beacon_chain::{BeaconChain, BeaconChainTypes};
|
use beacon_chain::{BeaconChain, BeaconChainTypes};
|
||||||
use client_network::Service as NetworkService;
|
use client_network::Service as NetworkService;
|
||||||
pub use config::Config as ApiConfig;
|
|
||||||
use hyper::rt::Future;
|
use hyper::rt::Future;
|
||||||
use hyper::service::service_fn_ok;
|
use hyper::service::service_fn_ok;
|
||||||
use hyper::{Body, Method, Response, Server, StatusCode};
|
use hyper::{Body, Method, Response, Server, StatusCode};
|
||||||
@ -24,6 +23,9 @@ use std::sync::Arc;
|
|||||||
use tokio::runtime::TaskExecutor;
|
use tokio::runtime::TaskExecutor;
|
||||||
use url_query::UrlQuery;
|
use url_query::UrlQuery;
|
||||||
|
|
||||||
|
pub use beacon::{BlockResponse, HeadResponse, StateResponse};
|
||||||
|
pub use config::Config as ApiConfig;
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
pub enum ApiError {
|
pub enum ApiError {
|
||||||
MethodNotAllowed(String),
|
MethodNotAllowed(String),
|
||||||
@ -134,6 +136,7 @@ pub fn start_server<T: BeaconChainTypes>(
|
|||||||
(&Method::GET, "/network/peer_count") => network::get_peer_count::<T>(req),
|
(&Method::GET, "/network/peer_count") => network::get_peer_count::<T>(req),
|
||||||
(&Method::GET, "/network/peer_id") => network::get_peer_id::<T>(req),
|
(&Method::GET, "/network/peer_id") => network::get_peer_id::<T>(req),
|
||||||
(&Method::GET, "/network/peers") => network::get_peer_list::<T>(req),
|
(&Method::GET, "/network/peers") => network::get_peer_list::<T>(req),
|
||||||
|
(&Method::GET, "/network/listen_port") => network::get_listen_port::<T>(req),
|
||||||
(&Method::GET, "/network/listen_addresses") => {
|
(&Method::GET, "/network/listen_addresses") => {
|
||||||
network::get_listen_addresses::<T>(req)
|
network::get_listen_addresses::<T>(req)
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,21 @@ pub fn get_listen_addresses<T: BeaconChainTypes>(req: Request<Body>) -> ApiResul
|
|||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// HTTP handle to return the list of libp2p multiaddr the client is listening on.
|
||||||
|
///
|
||||||
|
/// Returns a list of `Multiaddr`, serialized according to their `serde` impl.
|
||||||
|
pub fn get_listen_port<T: BeaconChainTypes>(req: Request<Body>) -> ApiResult {
|
||||||
|
let network = req
|
||||||
|
.extensions()
|
||||||
|
.get::<Arc<NetworkService<T>>>()
|
||||||
|
.ok_or_else(|| ApiError::ServerError("NetworkService extension missing".to_string()))?;
|
||||||
|
|
||||||
|
Ok(success_response(Body::from(
|
||||||
|
serde_json::to_string(&network.listen_port())
|
||||||
|
.map_err(|e| ApiError::ServerError(format!("Unable to serialize port: {:?}", e)))?,
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
|
||||||
/// HTTP handle to return the Discv5 ENR from the client's libp2p service.
|
/// HTTP handle to return the Discv5 ENR from the client's libp2p service.
|
||||||
///
|
///
|
||||||
/// ENR is encoded as base64 string.
|
/// ENR is encoded as base64 string.
|
||||||
|
Loading…
Reference in New Issue
Block a user