mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-13 10:01:25 +00:00
Gossipsub Protocol (#898)
* Create gossipsub crate - Basic template, borrowed from floodsub * Add a GossipsubConfig struct and set up basic structures in the Gossipsub struct * Begin implementation of join. Adds get_random_peers helper function and adds tests * Implements gossipsub leave() * Update publishMany to incorporate gossipsub mesh and fanout logic * Use the gossipsub mesh for determining peer subscription * Remove subscribed_topics field from the Gossipsub struct * Rename gossipsubconfig to ProtocolConfig * Implement the gossipsub control messages into the Codec's Encode/Decode and modifies GossipsubRpc * Modify GossipsubActions to enums for succinctness. * Modify the memcache to store Gossipsub messages * Implement control message handling. * Update control message handling to handle multiple messages. * Handle received gossipsub messages using pre-built handlers. * Remove excess connected peer hashmap * Add extra peer mapping and consistent topic naming. * Implement heartbeat, emit_gossip and send_graft_prune. * Group logic in forwarding messages. Add messages to memcache. * Add heartbeat timer and move location of helper function. * Add gossipsub the libp2p workspace, makes layer structs public * Add logging to gossipsub - Adds the log crate and implements logging macros - Specifies versions for external crates * Add example chat for debugging purposes * Implement #868 for gossipsub. * Add rust documentation to gossipsub crate. - Adds basic documentation, overview and examples to the gossipsub crate. * Re-introduce the initial heartbeat time config. This commit also adds the inject_connected test. * Add subscribe tests. - Modifies `handle_received_subscriptions` to take a reference of subscriptions - Adds `test_subscribe` - Adds `test_handle_received_subscriptions` - Adds tests for the filter in `get_random_peers` * Add Bug fixes and further testing for gossipsub. - Corrects the tuple use of topic_hashes - Corrects JOIN logic around fanout and adding peers to the mesh - Adds test_unsubscribe - Adds test_join * Rename GossipsubMessage::msg_id -> id * Add bug fix for handling disconnected peers. * Implements (partially) #889 for Gossipsub. * handle_iwant event count tests * handle_ihave event count tests * Move layer.rs tests into separate file. * Implement clippy suggestions for gossipsub. * Modify control message tests for specific types. * Implement builder pattern for GossipsubConfig. As suggested by @twittner - The builder pattern for building GossipsubConfig struct is implemented. * Package version updates as suggested by @twittner. * Correct line lengths in gossipsub. * Correct braces in found by @twittner. * Implement @twittner's suggestions. - Uses `HashSet` where applicable - Update `FnvHashMap` to standard `HashMap` - Uses `min` function in code simplification. * Add NodeList struct to clarify topic_peers. * Cleaner handling of messagelist Co-Authored-By: AgeManning <Age@AgeManning.com> * Cleaner handling of added peers. Co-Authored-By: AgeManning <Age@AgeManning.com> * handle_prune peer removed test * basic grafting tests * multiple topic grafting test * Convert &vec to slice. Co-Authored-By: AgeManning <Age@AgeManning.com> * Convert to lazy insert. Co-Authored-By: AgeManning <Age@AgeManning.com> * Cleaner topic handling. Co-Authored-By: AgeManning <Age@AgeManning.com> * control pool piggybacking using HashMap.drain() in control_pool_flush going to squash this * Add Debug derives to gossipsub and correct tests. * changes from PR squash this all tests passing, but still some that need to be reconsidered test reform * Implements Arc for GossipsubRpc events * Remove support for floodsub nodes * Reconnected to disconnected peers, to mitigate timeout * Use ReadOne WriteOne with configurable max gossip sizes * Remove length delimination from RPC encoding * Prevent peer duplication in mesh * Allow oneshot handler's inactivity_timeout to be configurable * Correct peer duplication in mesh bug * Remove auto-reconnect to allow for user-level disconnects * Single long-lived inbound/outbound streams to match go implementation * Allow gossipsub topics to be optionally hashable * Improves gossipsub stream handling - Corrects the handler's keep alive. - Correct the chat example. - Instantly add peers to the mesh on subscription if the mesh is low. * Allows message validation in gossipsub * Replaces Cuckoofilter with LRUCache The false positive rate was unacceptable for rejecting messages. * Renames configuration parameter and corrects logic * Removes peer from fanout on disconnection * Add publish and fanout tests * Apply @mxinden suggestions * Resend message if outbound stream negotiated - Downgrades log warnings * Implement further reviewer suggestions - Created associated functions to avoid unnecessary cloning - Messages are rejected if their sequence numbers are not u64 - `GossipsbuConfigBuilder` has the same defaults as `GossipsubConfig` - Miscellaneous typos * Add MessageId type and remove unnecessary comments * Add a return value to propagate_message function * Adds user-customised gossipsub message ids * Adds the message id to GossipsubEvent * Implement Debug for GossipsubConfig * protocols/gossipsub: Add basic smoke test Implement a basic smoke test that: 1. Builds a fully connected graph of size N. 2. Subscribes each node to the same topic. 3. Publishes a single message. 4. Waits for all nodes to receive the above message. N and the structure of the graph are reproducibly randomized via Quickcheck. * Corrections pointed out by @mxinden * Add option to remove source id publishing * protocols/gossipsub/tests/smoke: Remove unused variable * Merge latest master * protocols/gossipsub: Move to stable futures * examples/gossipsub-chat.rs: Move to stable futures * protocols/gossipsub/src/behaviour/tests: Update to stable futures * protocols/gossipsub/tests: Update to stable futures * protocols/gossipsub: Log substream errors * protocols/gossipsub: Log outbound substream errors * Remove rust-fmt formatting * Shift to prost for protobuf compiling * Use wasm_timer for wasm compatibility Co-authored-by: Grant Wuerker <gwuerker@gmail.com> Co-authored-by: Toralf Wittner <tw@dtex.org> Co-authored-by: Pawan Dhananjay <pawandhananjay@gmail.com> Co-authored-by: Max Inden <mail@max-inden.de> Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>
This commit is contained in:
committed by
Pierre Krieger
parent
0cb3cd4262
commit
37c7d73b11
153
protocols/gossipsub/src/lib.rs
Normal file
153
protocols/gossipsub/src/lib.rs
Normal file
@ -0,0 +1,153 @@
|
||||
// Copyright 2020 Sigma Prime Pty Ltd.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
//! Gossipsub is a P2P pubsub (publish/subscription) routing layer designed to extend upon
|
||||
//! flooodsub and meshsub routing protocols.
|
||||
//!
|
||||
//! # Overview
|
||||
//!
|
||||
//! *Note: The gossipsub protocol specifications
|
||||
//! (https://github.com/libp2p/specs/tree/master/pubsub/gossipsub) provide an outline for the
|
||||
//! routing protocol. They should be consulted for further detail.*
|
||||
//!
|
||||
//! Gossipsub is a blend of meshsub for data and randomsub for mesh metadata. It provides bounded
|
||||
//! degree and amplification factor with the meshsub construction and augments it using gossip
|
||||
//! propagation of metadata with the randomsub technique.
|
||||
//!
|
||||
//! The router maintains an overlay mesh network of peers on which to efficiently send messages and
|
||||
//! metadata. Peers use control messages to broadcast and request known messages and
|
||||
//! subscribe/unsubscribe from topics in the mesh network.
|
||||
//!
|
||||
//! # Important Discrepancies
|
||||
//!
|
||||
//! This section outlines the current implementation's potential discrepancies from that of other
|
||||
//! implementations, due to undefined elements in the current specification.
|
||||
//!
|
||||
//! - **Topics** - In gossipsub, topics configurable by the `hash_topics` configuration parameter.
|
||||
//! Topics are of type `TopicHash`. The current go implementation uses raw utf-8 strings, and this
|
||||
//! is default configuration in rust-libp2p. Topics can be hashed (SHA256 hashed then base64
|
||||
//! encoded) by setting the `hash_topics` configuration parameter to true.
|
||||
//!
|
||||
//! - **Sequence Numbers** - A message on the gossipsub network is identified by the source
|
||||
//! `PeerId` and a nonce (sequence number) of the message. The sequence numbers in this
|
||||
//! implementation are sent as raw bytes across the wire. They are 64-bit big-endian unsigned
|
||||
//! integers. They are chosen at random in this implementation of gossipsub, but are sequential in
|
||||
//! the current go implementation.
|
||||
//!
|
||||
//! # Using Gossipsub
|
||||
//!
|
||||
//! ## GossipsubConfig
|
||||
//!
|
||||
//! The [`GossipsubConfig`] struct specifies various network performance/tuning configuration
|
||||
//! parameters. Specifically it specifies:
|
||||
//!
|
||||
//! [`GossipsubConfig`]: struct.GossipsubConfig.html
|
||||
//!
|
||||
//! - `protocol_id` - The protocol id that this implementation will accept connections on.
|
||||
//! - `history_length` - The number of heartbeats which past messages are kept in cache (default: 5).
|
||||
//! - `history_gossip` - The number of past heartbeats that the node will send gossip metadata
|
||||
//! about (default: 3).
|
||||
//! - `mesh_n` - The target number of peers store in the local mesh network.
|
||||
//! (default: 6).
|
||||
//! - `mesh_n_low` - The minimum number of peers in the local mesh network before.
|
||||
//! trying to add more peers to the mesh from the connected peer pool (default: 4).
|
||||
//! - `mesh_n_high` - The maximum number of peers in the local mesh network before removing peers to
|
||||
//! reach `mesh_n` peers (default: 12).
|
||||
//! - `gossip_lazy` - The number of peers that the local node will gossip to during a heartbeat (default: `mesh_n` = 6).
|
||||
//! - `heartbeat_initial_delay - The initial time delay before starting the first heartbeat (default: 5 seconds).
|
||||
//! - `heartbeat_interval` - The time between each heartbeat (default: 1 second).
|
||||
//! - `fanout_ttl` - The fanout time to live time period. The timeout required before removing peers from the fanout
|
||||
//! for a given topic (default: 1 minute).
|
||||
//! - `max_transmit_size` - This sets the maximum transmission size for total gossipsub messages on the network.
|
||||
//! - `hash_topics` - Whether to hash the topics using base64(SHA256(topic)) or to leave as plain utf-8 strings.
|
||||
//! - `manual_propagation` - Whether gossipsub should immediately forward received messages on the
|
||||
//! network. For applications requiring message validation, this should be set to false, then the
|
||||
//! application should call `propagate_message(message_id, propagation_source)` once validated, to
|
||||
//! propagate the message to peers.
|
||||
//!
|
||||
//! This struct implements the `Default` trait and can be initialised via
|
||||
//! `GossipsubConfig::default()`.
|
||||
//!
|
||||
//!
|
||||
//! ## Gossipsub
|
||||
//!
|
||||
//! The [`Gossipsub`] struct implements the `NetworkBehaviour` trait allowing it to act as the
|
||||
//! routing behaviour in a `Swarm`. This struct requires an instance of `PeerId` and
|
||||
//! [`GossipsubConfig`].
|
||||
//!
|
||||
//! [`Gossipsub`]: struct.Gossipsub.html
|
||||
|
||||
//! ## Example
|
||||
//!
|
||||
//! An example of initialising a gossipsub compatible swarm:
|
||||
//!
|
||||
//! ```ignore
|
||||
//! #extern crate libp2p;
|
||||
//! #extern crate futures;
|
||||
//! #extern crate tokio;
|
||||
//! #use libp2p::gossipsub::GossipsubEvent;
|
||||
//! #use libp2p::{gossipsub, secio,
|
||||
//! # tokio_codec::{FramedRead, LinesCodec},
|
||||
//! #};
|
||||
//! let local_key = secio::SecioKeyPair::ed25519_generated().unwrap();
|
||||
//! let local_pub_key = local_key.to_public_key();
|
||||
//!
|
||||
//! // Set up an encrypted TCP Transport over the Mplex and Yamux protocols
|
||||
//! let transport = libp2p::build_development_transport(local_key);
|
||||
//!
|
||||
//! // Create a Floodsub/Gossipsub topic
|
||||
//! let topic = libp2p::floodsub::TopicBuilder::new("example").build();
|
||||
//!
|
||||
//! // Create a Swarm to manage peers and events
|
||||
//! let mut swarm = {
|
||||
//! // set default parameters for gossipsub
|
||||
//! let gossipsub_config = gossipsub::GossipsubConfig::default();
|
||||
//! // build a gossipsub network behaviour
|
||||
//! let mut gossipsub =
|
||||
//! gossipsub::Gossipsub::new(local_pub_key.clone().into_peer_id(), gossipsub_config);
|
||||
//! gossipsub.subscribe(topic.clone());
|
||||
//! libp2p::Swarm::new(
|
||||
//! transport,
|
||||
//! gossipsub,
|
||||
//! libp2p::core::topology::MemoryTopology::empty(local_pub_key),
|
||||
//! )
|
||||
//! };
|
||||
//!
|
||||
//! // Listen on all interfaces and whatever port the OS assigns
|
||||
//! let addr = libp2p::Swarm::listen_on(&mut swarm, "/ip4/0.0.0.0/tcp/0".parse().unwrap()).unwrap();
|
||||
//! println!("Listening on {:?}", addr);
|
||||
//! ```
|
||||
|
||||
pub mod protocol;
|
||||
|
||||
mod behaviour;
|
||||
mod config;
|
||||
mod handler;
|
||||
mod mcache;
|
||||
mod topic;
|
||||
|
||||
mod rpc_proto {
|
||||
include!(concat!(env!("OUT_DIR"), "/gossipsub.pb.rs"));
|
||||
}
|
||||
|
||||
pub use self::behaviour::{Gossipsub, GossipsubEvent, GossipsubRpc};
|
||||
pub use self::config::{GossipsubConfig, GossipsubConfigBuilder};
|
||||
pub use self::protocol::{GossipsubMessage, MessageId};
|
||||
pub use self::topic::{Topic, TopicHash};
|
Reference in New Issue
Block a user