mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-12 09:31:20 +00:00
Revamp the documentation of the root of core (#684)
* Revamp the documentation of the root of core * Update core/src/lib.rs Co-Authored-By: tomaka <pierre.krieger1708@gmail.com> * Update core/src/lib.rs Co-Authored-By: tomaka <pierre.krieger1708@gmail.com> * Update core/src/lib.rs Co-Authored-By: tomaka <pierre.krieger1708@gmail.com> * Update core/src/lib.rs Co-Authored-By: tomaka <pierre.krieger1708@gmail.com> * Update core/src/lib.rs Co-Authored-By: tomaka <pierre.krieger1708@gmail.com> * Fix more concerns * Merge into one
This commit is contained in:
163
core/src/lib.rs
163
core/src/lib.rs
@ -1,4 +1,4 @@
|
||||
// Copyright 2017 Parity Technologies (UK) Ltd.
|
||||
// Copyright 2017-2018 Parity Technologies (UK) Ltd.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
@ -23,145 +23,34 @@
|
||||
//! This crate contains all the core traits and mechanisms of the transport and swarm systems
|
||||
//! of *libp2p*.
|
||||
//!
|
||||
//! # The `Transport` trait
|
||||
//! # Overview
|
||||
//!
|
||||
//! The main trait that this crate provides is `Transport`, which provides the `dial` and
|
||||
//! `listen_on` methods and can be used to dial or listen on a multiaddress. The `swarm` crate
|
||||
//! itself does not provide any concrete (i.e. non-dummy, non-adapter) implementation of this trait.
|
||||
//! It is implemented on structs that are provided by external crates, such as `TcpConfig` from
|
||||
//! `tcp-transport`, `UdpConfig`, or `WebsocketConfig` (note: as of the writing of this
|
||||
//! documentation, the last two structs don't exist yet).
|
||||
//! This documentation focuses on the concepts of *libp2p-core*, and is interesting mostly if you
|
||||
//! want to extend *libp2p* with new protocols. If you only want to use libp2p, you might find the
|
||||
//! documentation of the main *libp2p* crate more interesting.
|
||||
//!
|
||||
//! Each implementation of `Transport` only supports *some* multiaddress protocols, for example
|
||||
//! the `TcpConfig` struct only supports multiaddresses that look like `/ip*/*.*.*.*/tcp/*`. It is
|
||||
//! possible to group two implementations of `Transport` with the `or_transport` method, in order
|
||||
//! to obtain a single object that supports the protocols of both objects at once. This can be done
|
||||
//! multiple times in a row in order to chain as many implementations as you want.
|
||||
//! The main concepts of libp2p are:
|
||||
//!
|
||||
//! // TODO: right now only tcp-transport exists, we need to add an example for chaining
|
||||
//! // multiple transports once that makes sense
|
||||
//!
|
||||
//! ## The `MuxedTransport` trait
|
||||
//!
|
||||
//! The `MuxedTransport` trait is an extension to the `Transport` trait, and is implemented on
|
||||
//! transports that can receive incoming connections on streams that have been opened with `dial()`.
|
||||
//!
|
||||
//! The trait provides the `next_incoming()` method, which returns a future that will resolve to
|
||||
//! the next substream that arrives from a dialed node.
|
||||
//!
|
||||
//! > **Note**: This trait is mainly implemented for transports that provide stream muxing
|
||||
//! > capabilities, but it can also be implemented in a dummy way by returning an empty
|
||||
//! > iterator.
|
||||
//!
|
||||
//! # Connection upgrades
|
||||
//!
|
||||
//! Once a socket has been opened with a remote through a `Transport`, it can be *upgraded*. This
|
||||
//! consists in negotiating a protocol with the remote (through `multistream-select`), and applying
|
||||
//! that protocol on the socket.
|
||||
//!
|
||||
//! A potential connection upgrade is represented with the `ConnectionUpgrade` trait. The trait
|
||||
//! consists in a protocol name plus a method that turns the socket into an `Output` object whose
|
||||
//! nature and type is specific to each upgrade.
|
||||
//!
|
||||
//! There exists three kinds of connection upgrades: middlewares, muxers, and actual protocols.
|
||||
//!
|
||||
//! ## Middlewares
|
||||
//!
|
||||
//! Examples of middleware connection upgrades include `PlainTextConfig` (dummy upgrade) or
|
||||
//! `SecioConfig` (encryption layer, provided by the `secio` crate).
|
||||
//!
|
||||
//! The output of a middleware connection upgrade implements the `AsyncRead` and `AsyncWrite`
|
||||
//! traits, just like sockets do.
|
||||
//!
|
||||
//! A middleware can be applied on a transport by using the `with_upgrade` method of the
|
||||
//! `Transport` trait. The return value of this method also implements the `Transport` trait, which
|
||||
//! means that you can call `dial()` and `listen_on()` on it in order to directly obtain an
|
||||
//! upgraded connection or a listener that will yield upgraded connections. Similarly, the
|
||||
//! `next_incoming()` method will automatically apply the upgrade on both the dialer and the
|
||||
//! listener. An error is produced if the remote doesn't support the protocol corresponding to the
|
||||
//! connection upgrade.
|
||||
//!
|
||||
//! ```
|
||||
//! extern crate libp2p_core;
|
||||
//! extern crate libp2p_tcp_transport;
|
||||
//!
|
||||
//! use libp2p_core::Transport;
|
||||
//!
|
||||
//! # fn main() {
|
||||
//! let tcp_transport = libp2p_tcp_transport::TcpConfig::new();
|
||||
//! let upgraded = tcp_transport.with_upgrade(libp2p_core::upgrade::DeniedUpgrade);
|
||||
//!
|
||||
//! // upgraded.dial(...) // automatically applies the plain text protocol on the socket
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! ## Muxers
|
||||
//!
|
||||
//! The concept of *muxing* consists in using a single stream as if it was multiple substreams.
|
||||
//!
|
||||
//! If the output of the connection upgrade instead implements the `StreamMuxer` and `Clone`
|
||||
//! traits, then you can turn the `UpgradedNode` struct into a `ConnectionReuse` struct by calling
|
||||
//! `ConnectionReuse::from(upgraded_node)`.
|
||||
//!
|
||||
//! The `ConnectionReuse` struct then implements the `Transport` and `MuxedTransport` traits, and
|
||||
//! can be used to dial or listen to multiaddresses, just like any other transport. The only
|
||||
//! difference is that dialing a node will try to open a new substream on an existing connection
|
||||
//! instead of opening a new one every time.
|
||||
//!
|
||||
//! > **Note**: Right now the `ConnectionReuse` struct is not fully implemented.
|
||||
//!
|
||||
//! TODO: add an example once the multiplex pull request is merged
|
||||
//!
|
||||
//! ## Actual protocols
|
||||
//!
|
||||
//! *Actual protocols* work the same way as middlewares, except that their `Output` doesn't
|
||||
//! implement the `AsyncRead` and `AsyncWrite` traits. This means that that the return value of
|
||||
//! `with_upgrade` does **not** implement the `Transport` trait and thus cannot be used as a
|
||||
//! transport.
|
||||
//!
|
||||
//! However the `UpgradedNode` struct returned by `with_upgrade` still provides methods named
|
||||
//! `dial`, `listen_on`, and `next_incoming`, which will yield you a `Future` or a `Stream`,
|
||||
//! which you can use to obtain the `Output`. This `Output` can then be used in a protocol-specific
|
||||
//! way to use the protocol.
|
||||
//!
|
||||
//! ```no_run
|
||||
//! extern crate futures;
|
||||
//! extern crate libp2p_ping;
|
||||
//! extern crate libp2p_core;
|
||||
//! extern crate libp2p_tcp_transport;
|
||||
//! extern crate tokio;
|
||||
//!
|
||||
//! use futures::{Future, Stream};
|
||||
//! use libp2p_ping::protocol::Ping;
|
||||
//! use libp2p_core::{Transport, upgrade::apply_outbound};
|
||||
//! use tokio::runtime::current_thread::Runtime;
|
||||
//!
|
||||
//! # fn main() {
|
||||
//! let ping_dialer = libp2p_tcp_transport::TcpConfig::new()
|
||||
//! // We have a `TcpConfig` struct that implements `Dialer`, and apply a `Ping` upgrade on it.
|
||||
//! .and_then(|socket, _| {
|
||||
//! apply_outbound(socket, Ping::default()).map_err(|e| e.into_io_error())
|
||||
//! })
|
||||
//! // TODO: right now the only available protocol is ping, but we want to replace it with
|
||||
//! // something that is more simple to use
|
||||
//! .dial("/ip4/127.0.0.1/tcp/12345".parse::<libp2p_core::Multiaddr>().unwrap()).unwrap_or_else(|_| panic!())
|
||||
//! .and_then(|mut pinger| {
|
||||
//! pinger.ping(());
|
||||
//! let f = pinger.into_future().map(|_| ()).map_err(|(e, _)| e);
|
||||
//! Box::new(f) as Box<Future<Item = _, Error = _>>
|
||||
//! });
|
||||
//!
|
||||
//! // Runs until the ping arrives.
|
||||
//! let mut rt = Runtime::new().unwrap();
|
||||
//! let _ = rt.block_on(ping_dialer).unwrap();
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! ## Grouping protocols
|
||||
//!
|
||||
//! You can use the `.or_upgrade()` method to group multiple upgrades together. The return value
|
||||
//! also implements the `ConnectionUpgrade` trait and will choose one of the protocols amongst the
|
||||
//! ones supported.
|
||||
//! - A `PeerId` is a unique global identifier for a node on the network. Each node must have a
|
||||
//! different `PeerId`. Normally, a `PeerId` is the hash of the public key used to negotiate
|
||||
//! encryption on the communication channel, thereby guaranteeing that they cannot be spoofed.
|
||||
//! - The `Transport` trait defines how to reach a remote node or listen for incoming remote
|
||||
//! connections. See the `transport` module.
|
||||
//! - The `Swarm` struct contains all active and pending connections to remotes and manages the
|
||||
//! state of all the substreams that have been opened, and all the upgrades that were built upon
|
||||
//! these substreams.
|
||||
//! - Use the `NetworkBehaviour` trait to customize the behaviour of a `Swarm`. It is the
|
||||
//! `NetworkBehaviour` that controls what happens on the network. Multiple types that implement
|
||||
//! `NetworkBehaviour` can be composed into a single behaviour.
|
||||
//! - The `Topology` trait is implemented for types that hold the layout of a network. When other
|
||||
//! components need the network layout to operate, they are passed an instance of a `Topology`.
|
||||
//! - The `StreamMuxer` trait is implemented on structs that hold a connection to a remote and can
|
||||
//! subdivide this connection into multiple substreams. See the `muxing` module.
|
||||
//! - The `UpgradeInfo`, `InboundUpgrade` and `OutboundUpgrade` traits define how to upgrade each
|
||||
//! individual substream to use a protocol. See the `upgrade` module.
|
||||
//! - The `ProtocolsHandler` trait defines how each active connection to a remote should behave:
|
||||
//! how to handle incoming substreams, which protocols are supported, when to open a new
|
||||
//! outbound substream, etc. See the `protocols_handler` trait.
|
||||
//!
|
||||
|
||||
extern crate bs58;
|
||||
|
Reference in New Issue
Block a user