cs_mwc_libp2p_gossipsub/lib.rs
1// Copyright 2020 Sigma Prime Pty Ltd.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a
4// copy of this software and associated documentation files (the "Software"),
5// to deal in the Software without restriction, including without limitation
6// the rights to use, copy, modify, merge, publish, distribute, sublicense,
7// and/or sell copies of the Software, and to permit persons to whom the
8// Software is furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
14// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19// DEALINGS IN THE SOFTWARE.
20
21//! Gossipsub is a P2P pubsub (publish/subscription) routing layer designed to extend upon
22//! floodsub and meshsub routing protocols.
23//!
24//! # Overview
25//!
26//! *Note: The gossipsub protocol specifications
27//! (https://github.com/libp2p/specs/tree/master/pubsub/gossipsub) provide an outline for the
28//! routing protocol. They should be consulted for further detail.*
29//!
30//! Gossipsub is a blend of meshsub for data and randomsub for mesh metadata. It provides bounded
31//! degree and amplification factor with the meshsub construction and augments it using gossip
32//! propagation of metadata with the randomsub technique.
33//!
34//! The router maintains an overlay mesh network of peers on which to efficiently send messages and
35//! metadata. Peers use control messages to broadcast and request known messages and
36//! subscribe/unsubscribe from topics in the mesh network.
37//!
38//! # Important Discrepancies
39//!
40//! This section outlines the current implementation's potential discrepancies from that of other
41//! implementations, due to undefined elements in the current specification.
42//!
43//! - **Topics** - In gossipsub, topics configurable by the `hash_topics` configuration parameter.
44//! Topics are of type [`TopicHash`]. The current go implementation uses raw utf-8 strings, and this
45//! is default configuration in rust-libp2p. Topics can be hashed (SHA256 hashed then base64
46//! encoded) by setting the `hash_topics` configuration parameter to true.
47//!
48//! - **Sequence Numbers** - A message on the gossipsub network is identified by the source
49//! [`mwc_libp2p_core::PeerId`] and a nonce (sequence number) of the message. The sequence numbers in
50//! this implementation are sent as raw bytes across the wire. They are 64-bit big-endian unsigned
51//! integers. They are chosen at random in this implementation of gossipsub, but are sequential in
52//! the current go implementation.
53//!
54//! # Using Gossipsub
55//!
56//! ## GossipsubConfig
57//!
58//! The [`GossipsubConfig`] struct specifies various network performance/tuning configuration
59//! parameters. Specifically it specifies:
60//!
61//! [`GossipsubConfig`]: struct.Config.html
62//!
63//! This struct implements the [`Default`] trait and can be initialised via
64//! [`GossipsubConfig::default()`].
65//!
66//!
67//! ## Gossipsub
68//!
69//! The [`Gossipsub`] struct implements the [`mwc_libp2p_swarm::NetworkBehaviour`] trait allowing it to
70//! act as the routing behaviour in a [`mwc_libp2p_swarm::Swarm`]. This struct requires an instance of
71//! [`mwc_libp2p_core::PeerId`] and [`GossipsubConfig`].
72//!
73//! [`Gossipsub`]: struct.Gossipsub.html
74
75//! ## Example
76//!
77//! An example of initialising a gossipsub compatible swarm:
78//!
79//! ```
80//! use mwc_libp2p_gossipsub::GossipsubEvent;
81//! use mwc_libp2p_core::{identity::Keypair,transport::{Transport, MemoryTransport}, Multiaddr};
82//! use mwc_libp2p_gossipsub::MessageAuthenticity;
83//! let local_key = Keypair::generate_ed25519();
84//! let local_peer_id = mwc_libp2p_core::PeerId::from_public_key(local_key.public());
85//!
86//! // Set up an encrypted TCP Transport over the Mplex
87//! // This is test transport (memory).
88//! let noise_keys = mwc_libp2p_noise::Keypair::<mwc_libp2p_noise::X25519Spec>::new().into_authentic(&local_key).unwrap();
89//! let transport = MemoryTransport::default()
90//! .upgrade(mwc_libp2p_core::upgrade::Version::V1)
91//! .authenticate(mwc_libp2p_noise::NoiseConfig::xx(noise_keys).into_authenticated())
92//! .multiplex(mwc_libp2p_mplex::MplexConfig::new())
93//! .boxed();
94//!
95//! // Create a Gossipsub topic
96//! let topic = mwc_libp2p_gossipsub::IdentTopic::new("example");
97//!
98//! // Set the message authenticity - How we expect to publish messages
99//! // Here we expect the publisher to sign the message with their key.
100//! let message_authenticity = MessageAuthenticity::Signed(local_key);
101//!
102//! // Create a Swarm to manage peers and events
103//! let mut swarm = {
104//! // set default parameters for gossipsub
105//! let gossipsub_config = mwc_libp2p_gossipsub::GossipsubConfig::default();
106//! // build a gossipsub network behaviour
107//! let mut gossipsub: mwc_libp2p_gossipsub::Gossipsub =
108//! mwc_libp2p_gossipsub::Gossipsub::new(message_authenticity, gossipsub_config).unwrap();
109//! // subscribe to the topic
110//! gossipsub.subscribe(&topic);
111//! // create the swarm
112//! mwc_libp2p_swarm::Swarm::new(
113//! transport,
114//! gossipsub,
115//! local_peer_id,
116//! )
117//! };
118//!
119//! // Listen on a memory transport.
120//! let memory: Multiaddr = mwc_libp2p_core::multiaddr::Protocol::Memory(10).into();
121//! let addr = mwc_libp2p_swarm::Swarm::listen_on(&mut swarm, memory).unwrap();
122//! println!("Listening on {:?}", addr);
123//! ```
124
125pub mod error;
126pub mod protocol;
127
128mod backoff;
129mod behaviour;
130mod config;
131mod gossip_promises;
132mod handler;
133mod mcache;
134mod peer_score;
135pub mod subscription_filter;
136pub mod time_cache;
137mod topic;
138mod transform;
139mod types;
140
141#[cfg(test)]
142#[macro_use]
143extern crate derive_builder;
144
145mod rpc_proto;
146
147pub use self::behaviour::{Gossipsub, GossipsubEvent, MessageAuthenticity, PEER_TOPIC, PEER_EXCHANGE_NUMBER_LIMIT };
148pub use self::transform::{DataTransform, IdentityTransform};
149
150pub use self::config::{GossipsubConfig, GossipsubConfigBuilder, ValidationMode};
151pub use self::peer_score::{
152 score_parameter_decay, score_parameter_decay_with_base, PeerScoreParams, PeerScoreThresholds,
153 TopicScoreParams,
154};
155pub use self::topic::{Hasher, Topic, TopicHash};
156pub use self::types::{
157 FastMessageId, GossipsubMessage, GossipsubRpc, MessageAcceptance, MessageId,
158 RawGossipsubMessage,
159};
160pub type IdentTopic = Topic<self::topic::IdentityHash>;
161pub type Sha256Topic = Topic<self::topic::Sha256Hash>;