Skip to content

Commit 55a46f3

Browse files
authored
kademlia fixes (#266)
Signed-off-by: turuslan <turuslan.devbox@gmail.com>
1 parent a3f1004 commit 55a46f3

File tree

15 files changed

+132
-172
lines changed

15 files changed

+132
-172
lines changed

include/libp2p/injector/network_injector.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,9 @@ namespace libp2p::injector {
147147
* );
148148
* @endcode
149149
*/
150-
inline auto useKeyPair(const crypto::KeyPair &key_pair) {
150+
inline auto useKeyPair(crypto::KeyPair key_pair) {
151151
return boost::di::bind<crypto::KeyPair>().template to(
152-
key_pair)[boost::di::override];
152+
std::move(key_pair))[boost::di::override];
153153
}
154154

155155
/**

include/libp2p/protocol/kademlia/config.hpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ namespace libp2p::protocol::kademlia {
1313

1414
using namespace std::chrono_literals;
1515

16+
// https://github.com/libp2p/rust-libp2p/blob/e63975d7742710d4498b941e151c5177e06392ce/protocols/kad/src/lib.rs#L93
17+
constexpr size_t K_VALUE = 20;
18+
1619
namespace {
1720
struct RandomWalk {
1821
/**
@@ -122,7 +125,7 @@ namespace libp2p::protocol::kademlia {
122125
* This is implementation specified property.
123126
* @note Default: 20
124127
*/
125-
size_t maxBucketSize = 20;
128+
size_t maxBucketSize = K_VALUE;
126129

127130
/**
128131
* Maximum time to waiting response
@@ -142,6 +145,9 @@ namespace libp2p::protocol::kademlia {
142145
* Random walk config
143146
*/
144147
RandomWalk randomWalk{};
148+
149+
// https://github.com/libp2p/rust-libp2p/blob/c6cf7fec6913aa590622aeea16709fce6e9c99a5/protocols/kad/src/query/peers/closest.rs#L110-L120
150+
size_t query_initial_peers = K_VALUE;
145151
};
146152

147153
} // namespace libp2p::protocol::kademlia

include/libp2p/protocol/kademlia/impl/find_peer_executor.hpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
#include <libp2p/protocol/kademlia/impl/peer_routing_table.hpp>
2323
#include <libp2p/protocol/kademlia/impl/session.hpp>
2424
#include <libp2p/protocol/kademlia/impl/session_host.hpp>
25-
#include <libp2p/protocol/kademlia/peer_routing.hpp>
2625

2726
namespace libp2p::protocol::kademlia {
2827

@@ -35,7 +34,6 @@ namespace libp2p::protocol::kademlia {
3534
std::shared_ptr<Host> host,
3635
std::shared_ptr<basic::Scheduler> scheduler,
3736
std::shared_ptr<SessionHost> session_host,
38-
std::shared_ptr<PeerRouting> peer_routing,
3937
const std::shared_ptr<PeerRoutingTable> &peer_routing_table,
4038
PeerId peer_id,
4139
FoundPeerInfoHandler handler);
@@ -70,7 +68,6 @@ namespace libp2p::protocol::kademlia {
7068
std::shared_ptr<Host> host_;
7169
std::shared_ptr<basic::Scheduler> scheduler_;
7270
std::shared_ptr<SessionHost> session_host_;
73-
std::shared_ptr<PeerRouting> peer_routing_;
7471

7572
// Secondary
7673
const PeerId sought_peer_id_;

include/libp2p/protocol/kademlia/impl/get_value_executor.hpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
#include <libp2p/protocol/kademlia/impl/peer_routing_table.hpp>
2727
#include <libp2p/protocol/kademlia/impl/session.hpp>
2828
#include <libp2p/protocol/kademlia/impl/session_host.hpp>
29-
#include <libp2p/protocol/kademlia/peer_routing.hpp>
3029
#include <libp2p/protocol/kademlia/validator.hpp>
3130

3231
namespace libp2p::protocol::kademlia {
@@ -40,7 +39,6 @@ namespace libp2p::protocol::kademlia {
4039
std::shared_ptr<Host> host,
4140
std::shared_ptr<basic::Scheduler> scheduler,
4241
std::shared_ptr<SessionHost> session_host,
43-
std::shared_ptr<PeerRouting> peer_routing,
4442
std::shared_ptr<ContentRoutingTable> content_routing_table,
4543
const std::shared_ptr<PeerRoutingTable> &peer_routing_table,
4644
std::shared_ptr<ExecutorsFactory> executor_factory,
@@ -76,7 +74,6 @@ namespace libp2p::protocol::kademlia {
7674
std::shared_ptr<Host> host_;
7775
std::shared_ptr<basic::Scheduler> scheduler_;
7876
std::shared_ptr<SessionHost> session_host_;
79-
std::shared_ptr<PeerRouting> peer_routing_;
8077
std::shared_ptr<ContentRoutingTable> content_routing_table_;
8178
std::shared_ptr<ExecutorsFactory> executor_factory_;
8279
std::shared_ptr<Validator> validator_;

include/libp2p/protocol/kademlia/impl/kademlia_impl.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ namespace libp2p::protocol::kademlia {
140140

141141
// Subscribtion to new connections
142142
event::Handle new_connection_subscription_;
143+
event::Handle on_disconnected_;
143144

144145
struct StreamPtrComparator {
145146
bool operator()(const std::shared_ptr<connection::Stream> &lhs,

include/libp2p/protocol/kademlia/impl/peer_id_with_distance.hpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@
1010
#include <libp2p/protocol/kademlia/node_id.hpp>
1111

1212
namespace libp2p::protocol::kademlia {
13-
13+
/**
14+
* Used with `priority_queue<PeerIdWithDistance>`.
15+
* `top()` must be minimal distance, so `operator<` is reversed.
16+
*/
1417
struct PeerIdWithDistance {
1518
template <typename T>
1619
PeerIdWithDistance(const PeerId &peer_id, T &&target)
@@ -21,7 +24,7 @@ namespace libp2p::protocol::kademlia {
2124
bool operator<(const PeerIdWithDistance &other) const {
2225
return std::memcmp(
2326
distance_.data(), other.distance_.data(), distance_.size())
24-
< 0;
27+
> 0;
2528
}
2629

2730
const PeerId &operator*() const {

include/libp2p/protocol/kademlia/impl/peer_routing_table_impl.hpp

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,27 +19,24 @@
1919
#include <libp2p/protocol/kademlia/node_id.hpp>
2020

2121
namespace libp2p::protocol::kademlia {
22+
constexpr size_t kBucketCount = 256;
2223

2324
struct BucketPeerInfo {
2425
peer::PeerId peer_id;
2526
bool is_replaceable;
27+
bool is_connected;
2628
NodeId node_id;
27-
BucketPeerInfo(const peer::PeerId &peer_id, bool is_replaceable)
28-
: peer_id(peer_id), is_replaceable(is_replaceable), node_id(peer_id) {}
29+
BucketPeerInfo(const PeerId &peer_id,
30+
bool is_replaceable,
31+
bool is_connected)
32+
: peer_id{peer_id},
33+
is_replaceable{is_replaceable},
34+
is_connected{is_connected},
35+
node_id{peer_id} {}
2936
};
3037

3138
struct XorDistanceComparator {
32-
explicit XorDistanceComparator(const peer::PeerId &from) {
33-
hfrom = crypto::sha256(from.toVector()).value();
34-
}
35-
36-
explicit XorDistanceComparator(const NodeId &from)
37-
: hfrom(from.getData()) {}
38-
39-
explicit XorDistanceComparator(const Hash256 &hash) : hfrom(hash) {}
40-
4139
bool operator()(const BucketPeerInfo &a, const BucketPeerInfo &b) {
42-
NodeId from(hfrom);
4340
auto d1 = a.node_id.distance(from);
4441
auto d2 = b.node_id.distance(from);
4542
constexpr auto size = Hash256().size();
@@ -48,7 +45,7 @@ namespace libp2p::protocol::kademlia {
4845
return std::memcmp(d1.data(), d2.data(), size) < 0;
4946
}
5047

51-
Hash256 hfrom{};
48+
NodeId from;
5249
};
5350

5451
/**
@@ -67,7 +64,9 @@ namespace libp2p::protocol::kademlia {
6764

6865
bool moveToFront(const PeerId &pid);
6966

70-
void emplaceToFront(const PeerId &pid, bool is_replaceable);
67+
void emplaceToFront(const PeerId &pid,
68+
bool is_replaceable,
69+
bool is_connected);
7170

7271
boost::optional<PeerId> removeReplaceableItem();
7372

@@ -79,8 +78,6 @@ namespace libp2p::protocol::kademlia {
7978

8079
bool remove(const peer::PeerId &p);
8180

82-
Bucket split(size_t commonLenPrefix, const NodeId &target);
83-
8481
private:
8582
std::list<BucketPeerInfo> peers_;
8683
};
@@ -116,17 +113,15 @@ namespace libp2p::protocol::kademlia {
116113
size_t size() const override;
117114

118115
private:
119-
void nextBucket();
116+
std::optional<size_t> getBucketIndex(const NodeId &key) const;
120117

121118
const Config &config_;
122119
std::shared_ptr<peer::IdentityManager> identity_manager_;
123120
std::shared_ptr<event::Bus> bus_;
124121

125122
const NodeId local_;
126123

127-
std::vector<Bucket> buckets_;
128-
129-
log::SubLogger log_;
124+
std::array<Bucket, kBucketCount> buckets_;
130125
};
131126

132127
} // namespace libp2p::protocol::kademlia

include/libp2p/protocol/kademlia/node_id.hpp

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,22 +53,17 @@ namespace libp2p::protocol::kademlia {
5353
*/
5454
class NodeId {
5555
public:
56-
explicit NodeId(const Hash256 &h) : data_(h) {}
57-
58-
explicit NodeId(const void *bytes) {
59-
memcpy(data_.data(), bytes, data_.size());
60-
}
61-
6256
explicit NodeId(const peer::PeerId &pid) {
6357
auto digest_res = crypto::sha256(pid.toVector());
6458
BOOST_ASSERT(digest_res.has_value());
6559
data_ = std::move(digest_res.value());
6660
}
6761

68-
explicit NodeId(const ContentId &content_id) {
69-
auto digest_res = crypto::sha256(content_id);
70-
BOOST_ASSERT(digest_res.has_value());
71-
data_ = std::move(digest_res.value());
62+
static NodeId prehashed(Hash256 hash) {
63+
return NodeId{hash};
64+
}
65+
static NodeId hash(BytesIn key) {
66+
return prehashed(crypto::sha256(key).value());
7267
}
7368

7469
inline bool operator==(const NodeId &other) const {
@@ -106,6 +101,8 @@ namespace libp2p::protocol::kademlia {
106101
}
107102

108103
private:
104+
explicit NodeId(Hash256 hash) : data_{hash} {}
105+
109106
Hash256 data_;
110107
};
111108

src/protocol/kademlia/impl/add_provider_executor.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ namespace libp2p::protocol::kademlia {
2828
scheduler_(std::move(scheduler)),
2929
session_host_(std::move(session_host)),
3030
key_(std::move(key)),
31-
target_(key_),
31+
target_{NodeId::hash(key_)},
3232
log_("KademliaExecutor", "kademlia", "AddProvider", ++instance_number) {
33-
auto nearest_peer_ids =
34-
peer_routing_table->getNearestPeers(target_, config_.maxBucketSize);
33+
auto nearest_peer_ids = peer_routing_table->getNearestPeers(
34+
target_, config_.query_initial_peers);
3535

3636
nearest_peer_ids_.insert(std::move_iterator(nearest_peer_ids.begin()),
3737
std::move_iterator(nearest_peer_ids.end()));

src/protocol/kademlia/impl/find_peer_executor.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,19 @@ namespace libp2p::protocol::kademlia {
2424
std::shared_ptr<Host> host,
2525
std::shared_ptr<basic::Scheduler> scheduler,
2626
std::shared_ptr<SessionHost> session_host,
27-
std::shared_ptr<PeerRouting> peer_routing,
2827
const std::shared_ptr<PeerRoutingTable> &peer_routing_table,
2928
PeerId sought_peer_id,
3029
FoundPeerInfoHandler handler)
3130
: config_(config),
3231
host_(std::move(host)),
3332
scheduler_(std::move(scheduler)),
3433
session_host_(std::move(session_host)),
35-
peer_routing_(std::move(peer_routing)),
3634
sought_peer_id_(std::move(sought_peer_id)),
3735
target_(sought_peer_id_),
3836
handler_(std::move(handler)),
3937
log_("KademliaExecutor", "kademlia", "FindPeer", ++instance_number) {
4038
auto nearest_peer_ids = peer_routing_table->getNearestPeers(
41-
target_, config_.closerPeerCount * 2);
39+
target_, config_.query_initial_peers);
4240

4341
nearest_peer_ids_.insert(std::move_iterator(nearest_peer_ids.begin()),
4442
std::move_iterator(nearest_peer_ids.end()));

0 commit comments

Comments
 (0)