diff --git a/Cargo.toml b/Cargo.toml index 65960312ffd..c034745bd3d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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] @@ -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] diff --git a/src/lib.rs b/src/lib.rs index da8316717c1..c907a2a7348 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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 @@ -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)] @@ -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; @@ -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> + Send + Sync), Error = impl error::Error + Send, Listener = impl Send, Dial = impl Send, ListenerUpgrade = impl Send> + Clone> { @@ -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> + 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())) @@ -259,10 +308,19 @@ 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> + 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)) @@ -270,68 +328,3 @@ pub fn build_tcp_ws_pnet_secio_mplex_yamux(keypair: identity::Keypair, psk: PreS .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, websocket::WsConfig>>; -#[cfg(all(not(any(target_os = "emscripten", target_os = "unknown")), not(feature = "libp2p-websocket")))] -type InnerImplementation = dns::DnsConfig; -#[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 { - 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 { - let inner = core::transport::dummy::DummyTransport::new(); - Ok(CommonTransport { - inner: CommonTransportInner { inner } - }) - } -} - -impl Transport for CommonTransport { - type Output = ::Output; - type Error = ::Error; - type Listener = ::Listener; - type ListenerUpgrade = ::ListenerUpgrade; - type Dial = ::Dial; - - fn listen_on(self, addr: Multiaddr) -> Result> { - self.inner.inner.listen_on(addr) - } - - fn dial(self, addr: Multiaddr) -> Result> { - self.inner.inner.dial(addr) - } -}