Add PeerDb to Router

pull/1312/head
Stephen Shelton 4 years ago
parent cc6e9c882a
commit 2a30e7dac2
No known key found for this signature in database
GPG Key ID: EE4BADACCE8B631C

@ -36,6 +36,7 @@ namespace llarp
constexpr int DefaultWorkerThreads = 1;
constexpr int DefaultNetThreads = 1;
constexpr bool DefaultBlockBogons = true;
constexpr bool DefaultEnablePeerStats = false;
conf.defineOption<int>("router", "job-queue-size", false, DefaultJobQueueSize, [this](int arg) {
if (arg < 1024)
@ -128,6 +129,13 @@ namespace llarp
conf.defineOption<std::string>(
"router", "transport-privkey", false, "", AssignmentAcceptor(m_transportKeyFile));
conf.defineOption<bool>(
"router",
"enable-peer-stats",
false,
DefaultEnablePeerStats,
AssignmentAcceptor(m_enablePeerStats));
}
void
@ -987,6 +995,40 @@ namespace llarp
"File containing service node's seed.",
});
// extra [network] options
// TODO: probably better to create an [exit] section and only allow it for routers
def.addOptionComments(
"network",
"exit",
{
"Whether or not we should act as an exit node. Beware that this increases demand",
"on the server and may pose liability concerns. Enable at your own risk.",
});
// TODO: define the order of precedence (e.g. is whitelist applied before blacklist?)
// additionally, what's default? What if I don't whitelist anything?
def.addOptionComments(
"network",
"exit-whitelist",
{
"List of destination protocol:port pairs to whitelist, example: udp:*",
"or tcp:80. Multiple values supported.",
});
def.addOptionComments(
"network",
"exit-blacklist",
{
"Blacklist of destinations (same format as whitelist).",
});
def.addOptionComments(
"router",
"enable-peer-stats",
{
"Enable collection of SNode peer stats",
});
return def.generateINIConfig(true);
}

@ -64,6 +64,8 @@ namespace llarp
std::string m_identityKeyFile;
std::string m_transportKeyFile;
bool m_enablePeerStats = false;
void
defineConfigOptions(ConfigDefinition& conf, const ConfigGenParameters& params);
};

@ -5,6 +5,11 @@
namespace llarp
{
PeerDb::PeerDb()
{
m_lastFlush.store({});
}
void
PeerDb::loadDatabase(std::optional<std::filesystem::path> file)
{
@ -47,6 +52,12 @@ namespace llarp
void
PeerDb::flushDatabase()
{
LogDebug("flushing PeerDb...");
auto start = time_now_ms();
if (not shouldFlush(start))
LogWarn("Double PeerDb flush?");
if (not m_storage)
throw std::runtime_error("Cannot flush database before it has been loaded");
@ -65,6 +76,13 @@ namespace llarp
m_storage->replace(entry.second);
}
auto end = time_now_ms();
auto elapsed = end - start;
LogDebug("PeerDb flush took about ", elapsed, " millis");
m_lastFlush.store(end);
}
void
@ -93,4 +111,21 @@ namespace llarp
return itr->second;
}
void
PeerDb::configure(const RouterConfig& routerConfig)
{
if (not routerConfig.m_enablePeerStats)
throw std::runtime_error("[router]:enable-peer-stats is not enabled");
fs::path dbPath = routerConfig.m_dataDir / "peerstats.sqlite";
loadDatabase(dbPath);
}
bool
PeerDb::shouldFlush(llarp_time_t now)
{
return (now - m_lastFlush.load() >= m_targetFlushInterval);
}
}; // namespace llarp

@ -1,11 +1,11 @@
#pragma once
#include <chrono>
#include <filesystem>
#include <unordered_map>
#include <sqlite_orm/sqlite_orm.h>
#include <config/config.hpp>
#include <router_id.hpp>
#include <util/time.hpp>
#include <peerstats/types.hpp>
@ -19,6 +19,9 @@ namespace llarp
/// a flush.
struct PeerDb
{
/// Constructor
PeerDb();
/// Loads the database from disk using the provided filepath. If the file is equal to
/// `std::nullopt`, the database will be loaded into memory (useful for testing).
///
@ -62,11 +65,27 @@ namespace llarp
std::optional<PeerStats>
getCurrentPeerStats(const RouterID& routerId) const;
/// Configures the PeerDb based on RouterConfig
///
/// @param routerConfig
void
configure(const RouterConfig& routerConfig);
/// Returns whether or not we should flush, as determined by the last time we flushed and the
/// configured flush interval.
///
/// @param now is the current[-ish] time
bool
shouldFlush(llarp_time_t now);
private:
std::unordered_map<RouterID, PeerStats, RouterID::Hash> m_peerStats;
std::mutex m_statsLock;
std::unique_ptr<PeerDbStorage> m_storage;
llarp_time_t m_targetFlushInterval = 30s;
std::atomic<llarp_time_t> m_lastFlush;
};
} // namespace llarp

@ -578,6 +578,14 @@ namespace llarp
hiddenServiceContext().AddEndpoint(*conf);
}
// peer stats
if (conf->router.m_enablePeerStats)
{
LogInfo("Initializing peerdb...");
m_peerDb = std::make_unique<PeerDb>();
m_peerDb->configure(conf->router);
}
// Logging config
LogContext::Instance().Initialize(
conf->logging.m_logLevel,
@ -754,6 +762,10 @@ namespace llarp
{
nodedb()->AsyncFlushToDisk();
}
if (m_peerDb and m_peerDb->shouldFlush(now))
diskworker()->addJob([this]() { m_peerDb->flushDatabase(); });
// get connected peers
std::set<dht::Key_t> peersWeHave;
_linkManager.ForEachPeer([&peersWeHave](ILinkSession* s) {

@ -16,6 +16,7 @@
#include <messages/link_message_parser.hpp>
#include <nodedb.hpp>
#include <path/path_context.hpp>
#include <peerstats/peer_db.hpp>
#include <profiling.hpp>
#include <router_contact.hpp>
#include <router/outbound_message_handler.hpp>
@ -495,6 +496,7 @@ namespace llarp
llarp_time_t m_LastStatsReport = 0s;
std::shared_ptr<llarp::KeyManager> m_keyManager;
std::unique_ptr<PeerDb> m_peerDb;
uint32_t path_build_count = 0;

Loading…
Cancel
Save