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 record_priv;
39#[deprecated(
40    note = "The `record` module will be made private in the future and should not be depended on."
41)]
42pub mod record {
43    pub use super::record_priv::*;
44}
45
46mod addresses;
47mod behaviour;
48mod handler;
49mod jobs;
50mod kbucket;
51mod protocol;
52mod query;
53
54mod proto {
55    #![allow(unreachable_pub)]
56    include!("generated/mod.rs");
57    pub use self::dht::pb::{
58        mod_Message::{ConnectionType, MessageType, Peer},
59        Message, Record,
60    };
61}
62
63pub use addresses::Addresses;
64pub use behaviour::{
65    AddProviderContext, AddProviderError, AddProviderOk, AddProviderPhase, AddProviderResult,
66    BootstrapError, BootstrapOk, BootstrapResult, GetClosestPeersError, GetClosestPeersOk,
67    GetClosestPeersResult, GetProvidersError, GetProvidersOk, GetProvidersResult, GetRecordError,
68    GetRecordOk, GetRecordResult, InboundRequest, Mode, NoKnownPeers, PeerRecord, PutRecordContext,
69    PutRecordError, PutRecordOk, PutRecordPhase, PutRecordResult, QueryInfo, QueryMut, QueryRef,
70    QueryResult, QueryStats, RoutingUpdate,
71};
72pub use behaviour::{
73    Behaviour, BucketInserts, Caching, Config, Event, ProgressStep, Quorum, StoreInserts,
74};
75pub use kbucket::{
76    Distance as KBucketDistance, EntryView, KBucketRef, Key as KBucketKey, NodeStatus,
77};
78pub use protocol::ConnectionType;
79pub use query::QueryId;
80pub use record_priv::{store, Key as RecordKey, ProviderRecord, Record};
81
82use libp2p_swarm::StreamProtocol;
83use std::num::NonZeroUsize;
84
85/// The `k` parameter of the Kademlia specification.
86///
87/// This parameter determines:
88///
89///   1) The (fixed) maximum number of nodes in a bucket.
90///   2) The (default) replication factor, which in turn determines:
91///       a) The number of closer peers returned in response to a request.
92///       b) The number of closest peers to a key to search for in an iterative query.
93///
94/// The choice of (1) is fixed to this constant. The replication factor is configurable
95/// but should generally be no greater than `K_VALUE`. All nodes in a Kademlia
96/// DHT should agree on the choices made for (1) and (2).
97///
98/// The current value is `20`.
99pub const K_VALUE: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(20) };
100
101/// The `α` parameter of the Kademlia specification.
102///
103/// This parameter determines the default parallelism for iterative queries,
104/// i.e. the allowed number of in-flight requests that an iterative query is
105/// waiting for at a particular time while it continues to make progress towards
106/// locating the closest peers to a key.
107///
108/// The current value is `3`.
109pub const ALPHA_VALUE: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(3) };
110
111pub const PROTOCOL_NAME: StreamProtocol = protocol::DEFAULT_PROTO_NAME;
112
113/// Constant shared across tests for the [`Multihash`](libp2p_core::multihash::Multihash) type.
114#[cfg(test)]
115const SHA_256_MH: u64 = 0x12;
116
117#[deprecated(note = "Import the `kad` module instead and refer to this type as `kad::Behaviour`.")]
118pub type Kademlia<TStore> = Behaviour<TStore>;
119
120#[deprecated(
121    note = "Import the `kad` module instead and refer to this type as `kad::BucketInserts`."
122)]
123pub type KademliaBucketInserts = BucketInserts;
124
125#[deprecated(
126    note = "Import the `kad` module instead and refer to this type as `kad::StoreInserts`."
127)]
128pub type KademliaStoreInserts = StoreInserts;
129
130#[deprecated(note = "Import the `kad` module instead and refer to this type as `kad::Config`.")]
131pub type KademliaConfig = Config;
132
133#[deprecated(note = "Import the `kad` module instead and refer to this type as `kad::Caching`.")]
134pub type KademliaCaching = Caching;
135
136#[deprecated(note = "Import the `kad` module instead and refer to this type as `kad::Event`.")]
137pub type KademliaEvent = Event;
138
139#[deprecated(
140    note = "Import the `kad` module instead and refer to this type as `kad::ConnectionType`."
141)]
142pub type KadConnectionType = ConnectionType;