From 443100a362895a95383bb12c0891a10a8699547d Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 12 Dec 2018 15:52:01 +0100 Subject: [PATCH 1/2] Add helpers for easier Transports creation --- examples/chat.rs | 14 +++---------- examples/ipfs-kad.rs | 11 +--------- src/lib.rs | 48 ++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 48 insertions(+), 25 deletions(-) diff --git a/examples/chat.rs b/examples/chat.rs index 5c2cfae2ec0..90f8c3b4dbb 100644 --- a/examples/chat.rs +++ b/examples/chat.rs @@ -56,10 +56,8 @@ extern crate tokio; use futures::prelude::*; use libp2p::{ - NetworkBehaviour, Transport, - core::upgrade::{self, OutboundUpgradeExt}, + NetworkBehaviour, secio, - mplex, tokio_codec::{FramedRead, LinesCodec} }; @@ -71,14 +69,8 @@ fn main() { let local_pub_key = local_key.to_public_key(); println!("Local peer id: {:?}", local_pub_key.clone().into_peer_id()); - // Set up a an encrypted DNS-enabled TCP Transport over the Mplex protocol - let transport = libp2p::CommonTransport::new() - .with_upgrade(secio::SecioConfig::new(local_key)) - .and_then(move |out, _| { - let peer_id = out.remote_key.into_peer_id(); - let upgrade = mplex::MplexConfig::new().map_outbound(move |muxer| (peer_id, muxer) ); - upgrade::apply_outbound(out.stream, upgrade).map_err(|e| e.into_io_error()) - }); + // Set up a an encrypted DNS-enabled TCP Transport over the Mplex and Yamux protocols + let transport = libp2p::build_development_transport(local_key); // Create a Floodsub topic let floodsub_topic = libp2p::floodsub::TopicBuilder::new("chat").build(); diff --git a/examples/ipfs-kad.rs b/examples/ipfs-kad.rs index c370f0079d0..6d8773c4c04 100644 --- a/examples/ipfs-kad.rs +++ b/examples/ipfs-kad.rs @@ -30,11 +30,8 @@ extern crate tokio; use futures::prelude::*; use libp2p::{ - Transport, core::PublicKey, - core::upgrade::{self, OutboundUpgradeExt}, secio, - mplex, }; fn main() { @@ -43,13 +40,7 @@ fn main() { let local_pub_key = local_key.to_public_key(); // Set up a an encrypted DNS-enabled TCP Transport over the Mplex protocol - let transport = libp2p::CommonTransport::new() - .with_upgrade(secio::SecioConfig::new(local_key)) - .and_then(move |out, _| { - let peer_id = out.remote_key.into_peer_id(); - let upgrade = mplex::MplexConfig::new().map_outbound(move |muxer| (peer_id, muxer) ); - upgrade::apply_outbound(out.stream, upgrade).map_err(|e| e.into_io_error()) - }); + let transport = libp2p::build_development_transport(local_key); // Create the topology of the network with the IPFS bootstrap nodes. let mut topology = libp2p::core::topology::MemoryTopology::empty(); diff --git a/src/lib.rs b/src/lib.rs index 41636cf3c8a..98bb67eaffe 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -172,22 +172,62 @@ pub use self::multiaddr::Multiaddr; pub use self::simple::SimpleProtocol; pub use self::transport_ext::TransportExt; +use futures::prelude::*; +use std::time::Duration; + +/// Builds a `Transport` that supports the most commonly-used protocols that libp2p supports. +/// +/// > **Note**: This `Transport` is not suitable for production usage, as its implementation +/// > reserves the right to support additional protocols or remove deprecated protocols. +#[inline] +pub fn build_development_transport(local_private_key: secio::SecioKeyPair) + -> impl Transport + Send + Sync), Listener = impl Send, Dial = impl Send, ListenerUpgrade = impl Send> + Clone +{ + build_tcp_ws_secio_mplex_yamux(local_private_key) +} + +/// Builds an implementation of `Transport` that is suitable for usage with the `Swarm`. +/// +/// The implementation supports TCP/IP, WebSockets over TCP/IP, secio as the encryption layer, +/// and mplex or yamux as the multiplexing layer. +/// +/// > **Note**: If you ever need to express the type of this `Transport`. +pub fn build_tcp_ws_secio_mplex_yamux(local_private_key: secio::SecioKeyPair) + -> impl Transport + Send + Sync), Listener = impl Send, Dial = impl Send, ListenerUpgrade = impl Send> + Clone +{ + CommonTransport::new() + .with_upgrade(secio::SecioConfig::new(local_private_key)) + .and_then(move |out, endpoint| { + let peer_id = out.remote_key.into_peer_id(); + let peer_id2 = peer_id.clone(); + let upgrade = core::upgrade::SelectUpgrade::new(yamux::Config::default(), mplex::MplexConfig::new()) + // TODO: use a single `.map` instead of two maps + .map_inbound(move |muxer| (peer_id, muxer)) + .map_outbound(move |muxer| (peer_id2, muxer)); + + core::upgrade::apply(out.stream, upgrade, endpoint) + .map(|(id, muxer)| (id, core::muxing::StreamMuxerBox::new(muxer))) + .map_err(|e| e.into_io_error()) + }) + .with_timeout(Duration::from_secs(20)) +} + /// Implementation of `Transport` that supports the most common protocols. /// /// The list currently is TCP/IP, DNS, and WebSockets. However this list could change in the /// future to get new transports. #[derive(Debug, Clone)] -pub struct CommonTransport { +struct CommonTransport { // The actual implementation of everything. inner: CommonTransportInner } #[cfg(all(not(target_os = "emscripten"), feature = "libp2p-websocket"))] -pub type InnerImplementation = core::transport::OrTransport, websocket::WsConfig>>; +type InnerImplementation = core::transport::OrTransport, websocket::WsConfig>>; #[cfg(all(not(target_os = "emscripten"), not(feature = "libp2p-websocket")))] -pub type InnerImplementation = dns::DnsConfig; +type InnerImplementation = dns::DnsConfig; #[cfg(target_os = "emscripten")] -pub type InnerImplementation = websocket::BrowserWsConfig; +type InnerImplementation = websocket::BrowserWsConfig; #[derive(Debug, Clone)] struct CommonTransportInner { From 732efe8c47df61d94dd045844fc44265fe393bea Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 12 Dec 2018 16:51:19 +0100 Subject: [PATCH 2/2] Fix doctests --- src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 98bb67eaffe..49d25164a44 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -53,14 +53,14 @@ //! // unless it is run through a tokio runtime. //! ``` //! -//! The easiest way to create a transport is to use the `CommonTransport` struct. This struct -//! provides support for the most common protocols. +//! The easiest way to create a transport is to use the `build_development_transport` function. +//! This function provides support for the most common protocols. //! //! Example: //! //! ```rust -//! use libp2p::CommonTransport; -//! let _transport = CommonTransport::new(); +//! let key = libp2p::secio::SecioKeyPair::ed25519_generated().unwrap(); +//! let _transport = libp2p::build_development_transport(key); //! // _transport.dial(...); //! ``` //!