Skip to content

Commit

Permalink
kademlia random walk (exponential time, peer count) (#2084)
Browse files Browse the repository at this point in the history
  • Loading branch information
turuslan authored May 8, 2024
1 parent 4a323eb commit 55d51c1
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 4 deletions.
2 changes: 1 addition & 1 deletion cmake/Hunter/config.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ hunter_config(

hunter_config(
libp2p
VERSION 0.1.20
VERSION 0.1.21
KEEP_PACKAGE_SOURCES
)

Expand Down
4 changes: 2 additions & 2 deletions cmake/Hunter/hunter-gate-url.cmake
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
HunterGate(
URL https://github.com/qdrvm/hunter/archive/refs/tags/v0.25.3-qdrvm9.zip
SHA1 7f3f8ee341aaac8c400e776c8a9f28e8fc458296
URL https://github.com/qdrvm/hunter/archive/refs/tags/v0.25.3-qdrvm10.zip
SHA1 9571399d8d091420131eb81f884521326c9d3615
LOCAL
)
1 change: 1 addition & 0 deletions core/application/impl/kagome_application_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ namespace kagome::application {

kagome::telemetry::setTelemetryService(injector_.injectTelemetryService());

injector_.kademliaRandomWalk();
injector_.injectAddressPublisher();
injector_.injectTimeline();

Expand Down
6 changes: 5 additions & 1 deletion core/injector/application_injector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@
#include "network/impl/sync_protocol_observer_impl.hpp"
#include "network/impl/synchronizer_impl.hpp"
#include "network/impl/transactions_transmitter_impl.hpp"
#include "network/kademlia_random_walk.hpp"
#include "network/warp/cache.hpp"
#include "network/warp/protocol.hpp"
#include "network/warp/sync.hpp"
Expand Down Expand Up @@ -320,7 +321,7 @@ namespace {
kademlia_config.protocols =
network::make_protocols("/{}/kad", genesis, chain_spec);
kademlia_config.maxBucketSize = 1000;
kademlia_config.randomWalk = {.interval = random_wak_interval};
kademlia_config.randomWalk.enabled = false;

return std::make_shared<libp2p::protocol::kademlia::Config>(
std::move(kademlia_config));
Expand Down Expand Up @@ -1106,4 +1107,7 @@ namespace kagome::injector {
return pimpl_->injector_.template create<sptr<common::MainThreadPool>>();
}

void KagomeNodeInjector::kademliaRandomWalk() {
pimpl_->injector_.create<sptr<KademliaRandomWalk>>();
}
} // namespace kagome::injector
1 change: 1 addition & 0 deletions core/injector/application_injector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ namespace kagome::injector {
std::shared_ptr<storage::SpacedStorage> injectStorage();
std::shared_ptr<authority_discovery::AddressPublisher>
injectAddressPublisher();
void kademliaRandomWalk();

std::shared_ptr<application::mode::PrintChainInfoMode>
injectPrintChainInfoMode();
Expand Down
77 changes: 77 additions & 0 deletions core/network/kademlia_random_walk.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/**
* Copyright Quadrivium LLC
* All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

#include <libp2p/basic/scheduler.hpp>
#include <libp2p/protocol/kademlia/peer_routing.hpp>

#include "application/app_configuration.hpp"
#include "application/app_state_manager.hpp"
#include "common/main_thread_pool.hpp"
#include "log/logger.hpp"
#include "network/peer_manager.hpp"
#include "utils/pool_handler_ready_make.hpp"

namespace kagome {
/**
* Kademlia random walk:
* - Exponential delay.
* - Don't walk if enough peers are available.
* https://github.com/paritytech/polkadot-sdk/blob/29c8130bab0ed8216f48e47a78c602e7f0c5c1f2/substrate/client/network/src/discovery.rs#L702-L724
*/
class KademliaRandomWalk
: public std::enable_shared_from_this<KademliaRandomWalk> {
static constexpr std::chrono::seconds kWalkInitialDelay{1};
static constexpr size_t kExtraPeers{15};

public:
KademliaRandomWalk(
std::shared_ptr<application::AppStateManager> app_state_manager,
const application::AppConfiguration &app_config,
common::MainThreadPool &main_thread_pool,
std::shared_ptr<libp2p::basic::Scheduler> scheduler,
std::shared_ptr<network::PeerManager> peer_manager,
std::shared_ptr<libp2p::protocol::kademlia::Kademlia> kademlia)
: discovery_only_if_under_num_{app_config.outPeers() + kExtraPeers},
main_pool_handler_{poolHandlerReadyMake(
this, app_state_manager, main_thread_pool, log_)},
scheduler_{std::move(scheduler)},
peer_manager_{std::move(peer_manager)},
kademlia_{std::move(kademlia)} {}

bool tryStart() {
walk();
return true;
}

private:
void walk() {
if (peer_manager_->activePeersNumber() < discovery_only_if_under_num_) {
std::ignore = kademlia_->findRandomPeer();
}
auto delay = delay_;
delay_ = std::min(delay_ * 2, std::chrono::seconds{60});
auto cb = [weak_self{weak_from_this()}] {
auto self = weak_self.lock();
if (not self) {
return;
}
self->walk();
};
scheduler_->schedule(std::move(cb), delay);
}

log::Logger log_ = log::createLogger("KademliaRandomWalk");
size_t discovery_only_if_under_num_;
std::shared_ptr<PoolHandlerReady> main_pool_handler_;
std::shared_ptr<libp2p::basic::Scheduler> scheduler_;
std::shared_ptr<network::PeerManager> peer_manager_;
std::shared_ptr<libp2p::protocol::kademlia::PeerRouting> kademlia_;

std::chrono::seconds delay_{kWalkInitialDelay};
};
} // namespace kagome
2 changes: 2 additions & 0 deletions test/mock/libp2p/protocol/kademlia/kademlia_mock.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ namespace libp2p::protocol::kademlia {
(const PeerId &, FoundPeerInfoHandler),
(override));

MOCK_METHOD(outcome::result<void>, findRandomPeer, (), (override));

MOCK_METHOD(outcome::result<void>, bootstrap, (), (override));

MOCK_METHOD(void, start, (), (override));
Expand Down

0 comments on commit 55d51c1

Please sign in to comment.