libp2p_kad/
lib.rs

1// Copyright 2018 Parity Technologies (UK) 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//! Implementation of the libp2p-specific [Kademlia](https://github.com/libp2p/specs/blob/master/kad-dht/README.md) protocol.
22//!
23//! # Important Discrepancies
24//!
25//! - **Peer Discovery with Identify** In other libp2p implementations, the
26//!   [Identify](https://github.com/libp2p/specs/tree/master/identify) protocol might be seen as a core protocol. Rust-libp2p
27//!   tries to stay as generic as possible, and does not make this assumption.
28//!   This means that the Identify protocol must be manually hooked up to Kademlia through calls
29//!   to [`Behaviour::add_address`].
30//!   If you choose not to use the Identify protocol, and do not provide an alternative peer
31//!   discovery mechanism, a Kademlia node will not discover nodes beyond the network's
32//!   [boot nodes](https://docs.libp2p.io/concepts/glossary/#boot-node). Without the Identify protocol,
33//!   existing nodes in the kademlia network cannot obtain the listen addresses
34//!   of nodes querying them, and thus will not be able to add them to their routing table.
35
36#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
37
38mod addresses;
39mod behaviour;
40mod bootstrap;
41mod handler;
42mod jobs;
43mod kbucket;
44mod protocol;
45mod query;
46mod record;
47
48mod proto {
49    #![allow(unreachable_pub)]
50    include!("generated/mod.rs");
51    pub use self::dht::pb::{
52        mod_Message::{ConnectionType, MessageType, Peer},
53        Message, Record,
54    };
55}
56
57pub use addresses::Addresses;
58pub use behaviour::{
59    AddProviderContext, AddProviderError, AddProviderOk, AddProviderPhase, AddProviderResult,
60    BootstrapError, BootstrapOk, BootstrapResult, GetClosestPeersError, GetClosestPeersOk,
61    GetClosestPeersResult, GetProvidersError, GetProvidersOk, GetProvidersResult, GetRecordError,
62    GetRecordOk, GetRecordResult, InboundRequest, Mode, NoKnownPeers, PeerInfo, PeerRecord,
63    PutRecordContext, PutRecordError, PutRecordOk, PutRecordPhase, PutRecordResult, QueryInfo,
64    QueryMut, QueryRef, QueryResult, QueryStats, RoutingUpdate,
65};
66pub use behaviour::{
67    Behaviour, BucketInserts, Caching, Config, Event, ProgressStep, Quorum, StoreInserts,
68};
69pub use kbucket::{
70    Distance as KBucketDistance, EntryView, KBucketRef, Key as KBucketKey, NodeStatus,
71};
72pub use protocol::ConnectionType;
73pub use query::QueryId;
74pub use record::{store, Key as RecordKey, ProviderRecord, Record};
75
76use libp2p_swarm::StreamProtocol;
77use std::num::NonZeroUsize;
78
79/// The `k` parameter of the Kademlia specification.
80///
81/// This parameter determines:
82///
83///   1) The (fixed) maximum number of nodes in a bucket.
84///   2) The (default) replication factor, which in turn determines:
85///       a) The number of closer peers returned in response to a request.
86///       b) The number of closest peers to a key to search for in an iterative query.
87///
88/// The choice of (1) is fixed to this constant. The replication factor is configurable
89/// but should generally be no greater than `K_VALUE`. All nodes in a Kademlia
90/// DHT should agree on the choices made for (1) and (2).
91///
92/// The current value is `20`.
93pub const K_VALUE: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(20) };
94
95/// The `α` parameter of the Kademlia specification.
96///
97/// This parameter determines the default parallelism for iterative queries,
98/// i.e. the allowed number of in-flight requests that an iterative query is
99/// waiting for at a particular time while it continues to make progress towards
100/// locating the closest peers to a key.
101///
102/// The current value is `3`.
103pub const ALPHA_VALUE: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(3) };
104
105pub const PROTOCOL_NAME: StreamProtocol = protocol::DEFAULT_PROTO_NAME;
106
107/// Constant shared across tests for the [`Multihash`](libp2p_core::multihash::Multihash) type.
108#[cfg(test)]
109const SHA_256_MH: u64 = 0x12;