Skip to content

Commit

Permalink
Feature-gate all dependencies (#1467)
Browse files Browse the repository at this point in the history
* Feature-gate all dependencies

* Fix root doctest

* Fix WASM build
  • Loading branch information
tomaka authored Mar 11, 2020
1 parent 31271fc commit 96cd509
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 89 deletions.
74 changes: 56 additions & 18 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,45 @@ keywords = ["peer-to-peer", "libp2p", "networking"]
categories = ["network-programming", "asynchronous"]

[features]
default = ["secp256k1", "libp2p-websocket"]
default = [
"deflate",
"dns",
"floodsub",
"identify",
"kad",
"gossipsub",
"mdns",
"mplex",
"noise",
"ping",
"plaintext",
"pnet",
"secio",
"secp256k1",
"tcp",
"uds",
"wasm-ext",
"websocket",
"yamux",
]
deflate = ["libp2p-deflate"]
dns = ["libp2p-dns"]
floodsub = ["libp2p-floodsub"]
identify = ["libp2p-identify"]
kad = ["libp2p-kad"]
gossipsub = ["libp2p-gossipsub"]
mdns = ["libp2p-mdns"]
mplex = ["libp2p-mplex"]
noise = ["libp2p-noise"]
ping = ["libp2p-ping"]
plaintext = ["libp2p-plaintext"]
pnet = ["libp2p-pnet"]
secio = ["libp2p-secio"]
tcp = ["libp2p-tcp"]
uds = ["libp2p-uds"]
wasm-ext = ["libp2p-wasm-ext"]
websocket = ["libp2p-websocket"]
yamux = ["libp2p-yamux"]
secp256k1 = ["libp2p-core/secp256k1", "libp2p-secio/secp256k1"]

[dependencies]
Expand All @@ -19,32 +57,32 @@ futures = "0.3.1"
multiaddr = { package = "parity-multiaddr", version = "0.7.2", path = "misc/multiaddr" }
multihash = "0.10"
lazy_static = "1.2"
libp2p-mplex = { version = "0.16.0", path = "muxers/mplex" }
libp2p-identify = { version = "0.16.0", path = "protocols/identify" }
libp2p-kad = { version = "0.16.2", path = "protocols/kad" }
libp2p-floodsub = { version = "0.16.0", path = "protocols/floodsub" }
libp2p-gossipsub = { version = "0.16.0", path = "./protocols/gossipsub" }
libp2p-ping = { version = "0.16.0", path = "protocols/ping" }
libp2p-plaintext = { version = "0.16.0", path = "protocols/plaintext" }
libp2p-pnet = { version = "0.16.0", path = "protocols/pnet" }
libp2p-mplex = { version = "0.16.0", path = "muxers/mplex", optional = true }
libp2p-identify = { version = "0.16.0", path = "protocols/identify", optional = true }
libp2p-kad = { version = "0.16.2", path = "protocols/kad", optional = true }
libp2p-floodsub = { version = "0.16.0", path = "protocols/floodsub", optional = true }
libp2p-gossipsub = { version = "0.16.0", path = "./protocols/gossipsub", optional = true }
libp2p-ping = { version = "0.16.0", path = "protocols/ping", optional = true }
libp2p-plaintext = { version = "0.16.0", path = "protocols/plaintext", optional = true }
libp2p-pnet = { version = "0.16.0", path = "protocols/pnet", optional = true }
libp2p-core = { version = "0.16.0", path = "core" }
libp2p-core-derive = { version = "0.16.0", path = "misc/core-derive" }
libp2p-secio = { version = "0.16.1", path = "protocols/secio", default-features = false }
libp2p-secio = { version = "0.16.1", path = "protocols/secio", default-features = false, optional = true }
libp2p-swarm = { version = "0.16.1", path = "swarm" }
libp2p-uds = { version = "0.16.0", path = "transports/uds" }
libp2p-wasm-ext = { version = "0.16.2", path = "transports/wasm-ext" }
libp2p-yamux = { version = "0.16.2", path = "muxers/yamux" }
libp2p-noise = { version = "0.16.2", path = "protocols/noise" }
libp2p-uds = { version = "0.16.0", path = "transports/uds", optional = true }
libp2p-wasm-ext = { version = "0.16.2", path = "transports/wasm-ext", optional = true }
libp2p-yamux = { version = "0.16.2", path = "muxers/yamux", optional = true }
libp2p-noise = { version = "0.16.2", path = "protocols/noise", optional = true }
parking_lot = "0.10.0"
pin-project = "0.4.6"
smallvec = "1.0"
wasm-timer = "0.2.4"

[target.'cfg(not(any(target_os = "emscripten", target_os = "unknown")))'.dependencies]
libp2p-deflate = { version = "0.16.0", path = "protocols/deflate" }
libp2p-dns = { version = "0.16.0", path = "transports/dns" }
libp2p-mdns = { version = "0.16.0", path = "protocols/mdns" }
libp2p-tcp = { version = "0.16.0", path = "transports/tcp" }
libp2p-deflate = { version = "0.16.0", path = "protocols/deflate", optional = true }
libp2p-dns = { version = "0.16.0", path = "transports/dns", optional = true }
libp2p-mdns = { version = "0.16.0", path = "protocols/mdns", optional = true }
libp2p-tcp = { version = "0.16.0", path = "transports/tcp", optional = true }
libp2p-websocket = { version = "0.16.0", path = "transports/websocket", optional = true }

[dev-dependencies]
Expand Down
135 changes: 64 additions & 71 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,12 @@
//! Example ([`secio`] + [`yamux`] Protocol Upgrade):
//!
//! ```rust
//! # #[cfg(all(not(any(target_os = "emscripten", target_os = "unknown")), feature = "libp2p-secio"))] {
//! use libp2p::{Transport, tcp::TcpConfig, secio::SecioConfig, identity::Keypair, yamux};
//! # #[cfg(all(not(any(target_os = "emscripten", target_os = "unknown")), feature = "tcp", feature = "secio", feature = "yamux"))] {
//! use libp2p::{Transport, core::upgrade, tcp::TcpConfig, secio::SecioConfig, identity::Keypair, yamux};
//! let tcp = TcpConfig::new();
//! let secio = SecioConfig::new(Keypair::generate_ed25519());
//! let yamux = yamux::Config::default();
//! let transport = tcp.upgrade().authenticate(secio).multiplex(yamux);
//! let transport = tcp.upgrade(upgrade::Version::V1).authenticate(secio).multiplex(yamux);
//! # }
//! ```
//! In this example, `tcp_secio` is a new [`Transport`] that negotiates the secio protocol
Expand Down Expand Up @@ -152,7 +152,9 @@
#![doc(html_logo_url = "https://libp2p.io/img/logo_small.png")]
#![doc(html_favicon_url = "https://libp2p.io/img/favicon.png")]

#[cfg(feature = "pnet")]
use libp2p_pnet::{PnetConfig, PreSharedKey};

pub use bytes;
pub use futures;
#[doc(inline)]
Expand All @@ -162,47 +164,83 @@ pub use multihash;

#[doc(inline)]
pub use libp2p_core as core;
#[cfg(feature = "deflate")]
#[cfg_attr(docsrs, doc(cfg(feature = "deflate")))]
#[cfg(not(any(target_os = "emscripten", target_os = "unknown")))]
#[doc(inline)]
pub use libp2p_deflate as deflate;
#[cfg(feature = "dns")]
#[cfg_attr(docsrs, doc(cfg(feature = "dns")))]
#[cfg(not(any(target_os = "emscripten", target_os = "unknown")))]
#[doc(inline)]
pub use libp2p_dns as dns;
#[cfg(feature = "identify")]
#[cfg_attr(docsrs, doc(cfg(feature = "identify")))]
#[doc(inline)]
pub use libp2p_identify as identify;
#[cfg(feature = "kad")]
#[cfg_attr(docsrs, doc(cfg(feature = "kad")))]
#[doc(inline)]
pub use libp2p_kad as kad;
#[cfg(feature = "floodsub")]
#[cfg_attr(docsrs, doc(cfg(feature = "floodsub")))]
#[doc(inline)]
pub use libp2p_floodsub as floodsub;
#[cfg(feature = "gossipsub")]
#[cfg_attr(docsrs, doc(cfg(feature = "gossipsub")))]
#[doc(inline)]
pub use libp2p_gossipsub as gossipsub;
#[cfg(feature = "mplex")]
#[cfg_attr(docsrs, doc(cfg(feature = "mplex")))]
#[doc(inline)]
pub use libp2p_mplex as mplex;
#[cfg(feature = "mdns")]
#[cfg_attr(docsrs, doc(cfg(feature = "mdns")))]
#[cfg(not(any(target_os = "emscripten", target_os = "unknown")))]
#[doc(inline)]
pub use libp2p_mdns as mdns;
#[cfg(feature = "noise")]
#[cfg_attr(docsrs, doc(cfg(feature = "noise")))]
#[doc(inline)]
pub use libp2p_noise as noise;
#[cfg(feature = "ping")]
#[cfg_attr(docsrs, doc(cfg(feature = "ping")))]
#[doc(inline)]
pub use libp2p_ping as ping;
#[cfg(feature = "plaintext")]
#[cfg_attr(docsrs, doc(cfg(feature = "plaintext")))]
#[doc(inline)]
pub use libp2p_plaintext as plaintext;
#[cfg(feature = "secio")]
#[cfg_attr(docsrs, doc(cfg(feature = "secio")))]
#[doc(inline)]
pub use libp2p_secio as secio;
#[doc(inline)]
pub use libp2p_swarm as swarm;
#[cfg(feature = "tcp")]
#[cfg_attr(docsrs, doc(cfg(feature = "tcp")))]
#[cfg(not(any(target_os = "emscripten", target_os = "unknown")))]
#[doc(inline)]
pub use libp2p_tcp as tcp;
#[cfg(feature = "uds")]
#[cfg_attr(docsrs, doc(cfg(feature = "uds")))]
#[doc(inline)]
pub use libp2p_uds as uds;
#[cfg(feature = "wasm-ext")]
#[cfg_attr(docsrs, doc(cfg(feature = "wasm-ext")))]
#[doc(inline)]
pub use libp2p_wasm_ext as wasm_ext;
#[cfg(all(feature = "libp2p-websocket", not(any(target_os = "emscripten", target_os = "unknown"))))]
#[cfg(feature = "websocket")]
#[cfg_attr(docsrs, doc(cfg(feature = "websocket")))]
#[cfg(not(any(target_os = "emscripten", target_os = "unknown")))]
#[doc(inline)]
pub use libp2p_websocket as websocket;
#[cfg(feature = "yamux")]
#[cfg_attr(docsrs, doc(cfg(feature = "yamux")))]
#[doc(inline)]
pub use libp2p_yamux as yamux;
#[cfg(feature = "pnet")]
#[cfg_attr(docsrs, doc(cfg(feature = "pnet")))]
#[doc(inline)]
pub use libp2p_pnet as pnet;

Expand Down Expand Up @@ -230,6 +268,8 @@ use std::{error, io, time::Duration};
///
/// > **Note**: This `Transport` is not suitable for production usage, as its implementation
/// > reserves the right to support additional protocols or remove deprecated protocols.
#[cfg(all(not(any(target_os = "emscripten", target_os = "unknown")), feature = "tcp", feature = "websocket", feature = "secio", feature = "mplex", feature = "yamux"))]
#[cfg_attr(docsrs, doc(cfg(all(not(any(target_os = "emscripten", target_os = "unknown")), feature = "tcp", feature = "websocket", feature = "secio", feature = "mplex", feature = "yamux"))))]
pub fn build_development_transport(keypair: identity::Keypair)
-> io::Result<impl Transport<Output = (PeerId, impl core::muxing::StreamMuxer<OutboundSubstream = impl Send, Substream = impl Send, Error = impl Into<io::Error>> + Send + Sync), Error = impl error::Error + Send, Listener = impl Send, Dial = impl Send, ListenerUpgrade = impl Send> + Clone>
{
Expand All @@ -242,10 +282,19 @@ pub fn build_development_transport(keypair: identity::Keypair)
/// and mplex or yamux as the multiplexing layer.
///
/// > **Note**: If you ever need to express the type of this `Transport`.
#[cfg(all(not(any(target_os = "emscripten", target_os = "unknown")), feature = "tcp", feature = "websocket", feature = "secio", feature = "mplex", feature = "yamux"))]
#[cfg_attr(docsrs, doc(cfg(all(not(any(target_os = "emscripten", target_os = "unknown")), feature = "tcp", feature = "websocket", feature = "secio", feature = "mplex", feature = "yamux"))))]
pub fn build_tcp_ws_secio_mplex_yamux(keypair: identity::Keypair)
-> io::Result<impl Transport<Output = (PeerId, impl core::muxing::StreamMuxer<OutboundSubstream = impl Send, Substream = impl Send, Error = impl Into<io::Error>> + Send + Sync), Error = impl error::Error + Send, Listener = impl Send, Dial = impl Send, ListenerUpgrade = impl Send> + Clone>
{
Ok(CommonTransport::new()?
let transport = {
let tcp = tcp::TcpConfig::new().nodelay(true);
let transport = dns::DnsConfig::new(tcp)?;
let trans_clone = transport.clone();
transport.or_transport(websocket::WsConfig::new(trans_clone))
};

Ok(transport
.upgrade(core::upgrade::Version::V1)
.authenticate(secio::SecioConfig::new(keypair))
.multiplex(core::upgrade::SelectUpgrade::new(yamux::Config::default(), mplex::MplexConfig::new()))
Expand All @@ -259,79 +308,23 @@ pub fn build_tcp_ws_secio_mplex_yamux(keypair: identity::Keypair)
/// and mplex or yamux as the multiplexing layer.
///
/// > **Note**: If you ever need to express the type of this `Transport`.
#[cfg(all(not(any(target_os = "emscripten", target_os = "unknown")), feature = "tcp", feature = "websocket", feature = "secio", feature = "mplex", feature = "yamux", feature = "pnet"))]
#[cfg_attr(docsrs, doc(cfg(all(not(any(target_os = "emscripten", target_os = "unknown")), feature = "tcp", feature = "websocket", feature = "secio", feature = "mplex", feature = "yamux", feature = "pnet"))))]
pub fn build_tcp_ws_pnet_secio_mplex_yamux(keypair: identity::Keypair, psk: PreSharedKey)
-> io::Result<impl Transport<Output = (PeerId, impl core::muxing::StreamMuxer<OutboundSubstream = impl Send, Substream = impl Send, Error = impl Into<io::Error>> + Send + Sync), Error = impl error::Error + Send, Listener = impl Send, Dial = impl Send, ListenerUpgrade = impl Send> + Clone>
{
Ok(CommonTransport::new()?
let transport = {
let tcp = tcp::TcpConfig::new().nodelay(true);
let transport = dns::DnsConfig::new(tcp)?;
let trans_clone = transport.clone();
transport.or_transport(websocket::WsConfig::new(trans_clone))
};

Ok(transport
.and_then(move |socket, _| PnetConfig::new(psk).handshake(socket))
.upgrade(core::upgrade::Version::V1)
.authenticate(secio::SecioConfig::new(keypair))
.multiplex(core::upgrade::SelectUpgrade::new(yamux::Config::default(), mplex::MplexConfig::new()))
.map(|(peer, muxer), _| (peer, core::muxing::StreamMuxerBox::new(muxer)))
.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)]
struct CommonTransport {
// The actual implementation of everything.
inner: CommonTransportInner
}

#[cfg(all(not(any(target_os = "emscripten", target_os = "unknown")), feature = "libp2p-websocket"))]
type InnerImplementation = core::transport::OrTransport<dns::DnsConfig<tcp::TcpConfig>, websocket::WsConfig<dns::DnsConfig<tcp::TcpConfig>>>;
#[cfg(all(not(any(target_os = "emscripten", target_os = "unknown")), not(feature = "libp2p-websocket")))]
type InnerImplementation = dns::DnsConfig<tcp::TcpConfig>;
#[cfg(any(target_os = "emscripten", target_os = "unknown"))]
type InnerImplementation = core::transport::dummy::DummyTransport;

#[derive(Debug, Clone)]
struct CommonTransportInner {
inner: InnerImplementation,
}

impl CommonTransport {
/// Initializes the `CommonTransport`.
#[cfg(not(any(target_os = "emscripten", target_os = "unknown")))]
pub fn new() -> io::Result<CommonTransport> {
let tcp = tcp::TcpConfig::new().nodelay(true);
let transport = dns::DnsConfig::new(tcp)?;
#[cfg(feature = "libp2p-websocket")]
let transport = {
let trans_clone = transport.clone();
transport.or_transport(websocket::WsConfig::new(trans_clone))
};

Ok(CommonTransport {
inner: CommonTransportInner { inner: transport }
})
}

/// Initializes the `CommonTransport`.
#[cfg(any(target_os = "emscripten", target_os = "unknown"))]
pub fn new() -> io::Result<CommonTransport> {
let inner = core::transport::dummy::DummyTransport::new();
Ok(CommonTransport {
inner: CommonTransportInner { inner }
})
}
}

impl Transport for CommonTransport {
type Output = <InnerImplementation as Transport>::Output;
type Error = <InnerImplementation as Transport>::Error;
type Listener = <InnerImplementation as Transport>::Listener;
type ListenerUpgrade = <InnerImplementation as Transport>::ListenerUpgrade;
type Dial = <InnerImplementation as Transport>::Dial;

fn listen_on(self, addr: Multiaddr) -> Result<Self::Listener, TransportError<Self::Error>> {
self.inner.inner.listen_on(addr)
}

fn dial(self, addr: Multiaddr) -> Result<Self::Dial, TransportError<Self::Error>> {
self.inner.inner.dial(addr)
}
}

0 comments on commit 96cd509

Please sign in to comment.