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
57use std::num::NonZeroUsize;
58
59pub use addresses::Addresses;
60pub use behaviour::{
61    AddProviderContext, AddProviderError, AddProviderOk, AddProviderPhase, AddProviderResult,
62    Behaviour, BootstrapError, BootstrapOk, BootstrapResult, BucketInserts, Caching, Config, Event,
63    GetClosestPeersError, GetClosestPeersOk, GetClosestPeersResult, GetProvidersError,
64    GetProvidersOk, GetProvidersResult, GetRecordError, GetRecordOk, GetRecordResult,
65    InboundRequest, Mode, NoKnownPeers, PeerInfo, PeerRecord, ProgressStep, PutRecordContext,
66    PutRecordError, PutRecordOk, PutRecordPhase, PutRecordResult, QueryInfo, QueryMut, QueryRef,
67    QueryResult, QueryStats, Quorum, RoutingUpdate, StoreInserts,
68};
69pub use kbucket::{
70    Distance as KBucketDistance, EntryView, KBucketRef, Key as KBucketKey, NodeStatus, U256,
71};
72use libp2p_swarm::StreamProtocol;
73pub use protocol::{ConnectionType, KadPeer};
74pub use query::QueryId;
75pub use record::{store, Key as RecordKey, ProviderRecord, Record};
76
77/// The `k` parameter of the Kademlia specification.
78///
79/// This parameter determines:
80///
81///   1) The (fixed) maximum number of nodes in a bucket.
82///   2) The (default) replication factor, which in turn determines: a) The number of closer peers
83///      returned in response to a request. b) The number of closest peers to a key to search for in
84///      an iterative query.
85///
86/// The choice of (1) is fixed to this constant. The replication factor is configurable
87/// but should generally be no greater than `K_VALUE`. All nodes in a Kademlia
88/// DHT should agree on the choices made for (1) and (2).
89///
90/// The current value is `20`.
91pub const K_VALUE: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(20) };
92
93/// The `α` parameter of the Kademlia specification.
94///
95/// This parameter determines the default parallelism for iterative queries,
96/// i.e. the allowed number of in-flight requests that an iterative query is
97/// waiting for at a particular time while it continues to make progress towards
98/// locating the closest peers to a key.
99///
100/// The current value is `3`.
101pub const ALPHA_VALUE: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(3) };
102
103pub const PROTOCOL_NAME: StreamProtocol = protocol::DEFAULT_PROTO_NAME;
104
105/// Constant shared across tests for the [`Multihash`](libp2p_core::multihash::Multihash) type.
106#[cfg(test)]
107const SHA_256_MH: u64 = 0x12;