Add libp2p transport - tcp/ws/secio and multiplexing.

This commit is contained in:
Age Manning 2019-03-06 23:31:08 +11:00
parent b68adc1ae3
commit ac639c6427
No known key found for this signature in database
GPG Key ID: 05EED64B79E06A93
8 changed files with 108 additions and 49 deletions

View File

@ -56,7 +56,7 @@ impl ClientConfig {
// TODO: Handle list of addresses
if let Some(listen_address_str) = args.value_of("listen_address") {
if let Ok(listen_address) = listen_address_str.parse::<IpAddr>() {
config.net_conf.listen_addresses = Some(vec![listen_address]);
config.net_conf.listen_addresses = vec![listen_address];
} else {
error!(log, "Invalid IP Address"; "Address" => listen_address_str);
return Err("Invalid IP Address");
@ -65,7 +65,7 @@ impl ClientConfig {
// Custom p2p listen port
if let Some(port_str) = args.value_of("port") {
if let Ok(port) = port_str.parse::<u16>() {
config.net_conf.listen_port = Some(port);
config.net_conf.listen_port = port;
} else {
error!(log, "Invalid port"; "port" => port_str);
return Err("Invalid port");

View File

@ -8,3 +8,4 @@ edition = "2018"
# SigP repository until PR is merged
libp2p = { git = "https://github.com/SigP/rust-libp2p", branch = "gossipsub" }
slog = "2.4.1"
version = { path = "../version" }

View File

@ -2,11 +2,12 @@
/// all required libp2p functionality.
///
/// This crate builds and manages the libp2p services required by the beacon node.
mod network_config;
mod service;
pub use libp2p::{
gossipsub::{GossipsubConfig, GossipsubConfigBuilder},
PeerId,
};
pub use network_config::NetworkConfig;
pub use service::Service;

View File

@ -0,0 +1,58 @@
use libp2p::gossipsub::{GossipsubConfig, GossipsubConfigBuilder};
use libp2p::secio;
use std::fmt;
use std::net::IpAddr;
#[derive(Clone)]
/// Network configuration for lighthouse.
pub struct NetworkConfig {
//TODO: stubbing networking initial params, change in the future
/// IP address to listen on.
pub listen_addresses: Vec<IpAddr>,
/// Listen port UDP/TCP.
pub listen_port: u16,
/// Gossipsub configuration parameters.
pub gs_config: GossipsubConfig,
/// List of nodes to initially connect to.
pub boot_nodes: Vec<IpAddr>,
/// Peer key related to this nodes PeerId.
pub local_private_key: secio::SecioKeyPair,
/// Client version
pub client_version: String,
}
impl Default for NetworkConfig {
/// Generate a default network configuration.
fn default() -> Self {
// hard-coded defaults
let bootnodes = ["127.0.0.1"];
let default_port = 9000;
// TODO: Currently using ed25519 key pairs. Wire protocol specifies RSA. Waiting for this
// PR to be merged to generate RSA keys: https://github.com/briansmith/ring/pull/733
NetworkConfig {
listen_addresses: vec!["127.0.0.1".parse().expect("correct IP address")],
listen_port: default_port,
gs_config: GossipsubConfigBuilder::new().build(),
boot_nodes: bootnodes
.iter()
.map(|s| s.parse().expect("Bootnodes must be IP addresses"))
.collect(),
local_private_key: secio::SecioKeyPair::ed25519_generated().unwrap(),
client_version: version::version(),
}
}
}
impl NetworkConfig {
pub fn new() -> Self {
NetworkConfig::default()
}
}
impl fmt::Debug for NetworkConfig {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "NetworkConfig: listen_addresses: {:?}, listen_port: {:?}, gs_config: {:?}, boot_nodes: {:?}, local_private_key: <Secio-PubKey {:?}>, client_version: {:?}", self.listen_addresses, self.listen_port, self.gs_config, self.boot_nodes, self.local_private_key.to_public_key(), self.client_version)
}
}

View File

@ -1,11 +1,50 @@
use crate::NetworkConfig;
use libp2p::gossipsub::GossipsubEvent;
use libp2p::PeerId;
use libp2p::{build_tcp_ws_secio_mplex_yamux, core, secio, Transport};
use slog::debug;
use std::error;
/// The configuration and state of the libp2p components for the beacon node.
pub struct Service {}
pub struct Service {
/// This node's PeerId.
peer_id: PeerId,
}
impl Service {
pub fn new(log: slog::Logger) -> Self {
debug!(log, "Service starting");
Service {}
pub fn new(config: NetworkConfig, log: slog::Logger) -> Self {
debug!(log, "Libp2p Service starting");
let local_private_key = config.local_private_key;
let peer_id = local_private_key.to_peer_id();
debug!(log, "Local peer id: {:?}", peer_id);
// Set up the transport
let transport = build_transport(local_private_key);
//let transport = libp2p::
Service { peer_id }
}
}
/// The implementation supports TCP/IP, WebSockets over TCP/IP, secio as the encryption layer, and
/// mplex or yamux as the multiplexing layer.
fn build_transport(
local_private_key: secio::SecioKeyPair,
) -> impl Transport<
Output = (
PeerId,
impl core::muxing::StreamMuxer<OutboundSubstream = impl Send, Substream = impl Send>
+ Send
+ Sync,
),
Error = impl error::Error + Send,
Listener = impl Send,
Dial = impl Send,
ListenerUpgrade = impl Send,
> + Clone {
// TODO: The Wire protocol currently doesn't specify encryption and this will need to be customised
// in the future.
build_tcp_ws_secio_mplex_yamux(local_private_key)
}

View File

@ -2,8 +2,7 @@
pub mod error;
mod message_handler;
mod messages;
mod network_config;
mod service;
pub use network_config::NetworkConfig;
pub use libp2p::NetworkConfig;
pub use service::Service;

View File

@ -1,38 +0,0 @@
use libp2p::{GossipsubConfig, GossipsubConfigBuilder};
use std::net::IpAddr;
use version;
#[derive(Debug, Clone)]
/// Network configuration for lighthouse.
pub struct NetworkConfig {
//TODO: stubbing networking initial params, change in the future
/// IP address to listen on.
pub listen_addresses: Option<Vec<IpAddr>>,
/// Listen port UDP/TCP.
pub listen_port: Option<u16>,
/// Gossipsub configuration parameters.
pub gs_config: GossipsubConfig,
/// List of nodes to initially connect to.
pub boot_nodes: Vec<String>,
/// Client version
pub client_version: String,
}
impl Default for NetworkConfig {
/// Generate a default network configuration.
fn default() -> Self {
NetworkConfig {
listen_addresses: None,
listen_port: None,
gs_config: GossipsubConfigBuilder::new().build(),
boot_nodes: Vec::new(),
client_version: version::version(),
}
}
}
impl NetworkConfig {
pub fn new() -> Self {
NetworkConfig::default()
}
}

View File

@ -30,10 +30,9 @@ impl Service {
// launch libp2p service
let libp2p_log = log.new(o!("Service" => "Libp2p"));
let libp2p_service = LibP2PService::new(libp2p_log);
let libp2p_service = LibP2PService::new(config, libp2p_log);
// TODO: Spawn thread to handle libp2p messages and pass to message handler thread.
let network = Service {};
Ok((Arc::new(network), network_send))