mirror of https://github.com/oxen-io/lokinet
Add PeerDb::handleGossipedRC
This commit is contained in:
parent
7109ddc951
commit
595288e046
|
@ -127,6 +127,10 @@ namespace llarp
|
|||
auto* router = dht.GetRouter();
|
||||
router->NotifyRouterEvent<tooling::RCGossipReceivedEvent>(router->pubkey(), rc);
|
||||
router->GossipRCIfNeeded(rc);
|
||||
|
||||
auto peerDb = router->peerDb();
|
||||
if (peerDb)
|
||||
peerDb->handleGossipedRC(rc);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -121,6 +121,31 @@ namespace llarp
|
|||
return itr->second;
|
||||
}
|
||||
|
||||
void
|
||||
PeerDb::handleGossipedRC(const RouterContact& rc, llarp_time_t now)
|
||||
{
|
||||
std::lock_guard gaurd(m_statsLock);
|
||||
|
||||
RouterID id(rc.pubkey);
|
||||
auto& stats = m_peerStats[id];
|
||||
|
||||
if (stats.lastRCUpdated < rc.last_updated.count())
|
||||
{
|
||||
// we track max expiry as the delta between (time received - last expiration time),
|
||||
// and this value will often be negative for a healthy router
|
||||
// TODO: handle case where new RC is also expired? just ignore?
|
||||
int64_t expiry = (now.count() - (stats.lastRCUpdated + RouterContact::Lifetime.count()));
|
||||
|
||||
if (stats.numDistinctRCsReceived == 0)
|
||||
stats.mostExpiredRCMs = expiry;
|
||||
else
|
||||
stats.mostExpiredRCMs = std::max(stats.mostExpiredRCMs, expiry);
|
||||
|
||||
stats.numDistinctRCsReceived++;
|
||||
stats.lastRCUpdated = rc.last_updated.count();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PeerDb::configure(const RouterConfig& routerConfig)
|
||||
{
|
||||
|
|
|
@ -81,6 +81,16 @@ namespace llarp
|
|||
std::optional<PeerStats>
|
||||
getCurrentPeerStats(const RouterID& routerId) const;
|
||||
|
||||
/// Handles a new gossiped RC, updating stats as needed. The database tracks the last
|
||||
/// advertised update time, so it knows whether this is a new RC or not.
|
||||
///
|
||||
/// The given RC is assumed to be valid.
|
||||
///
|
||||
/// @param rc is the RouterContact to handle
|
||||
/// @param now is an optional time representing the current time
|
||||
void
|
||||
handleGossipedRC(const RouterContact& rc, llarp_time_t now = time_now_ms());
|
||||
|
||||
/// Configures the PeerDb based on RouterConfig
|
||||
///
|
||||
/// @param routerConfig
|
||||
|
|
|
@ -32,6 +32,7 @@ namespace llarp
|
|||
double peakBandwidthBytesPerSec = 0;
|
||||
int64_t longestRCReceiveIntervalMs = 0;
|
||||
int64_t mostExpiredRCMs = 0;
|
||||
int64_t lastRCUpdated = 0;
|
||||
|
||||
PeerStats();
|
||||
PeerStats(const RouterID& routerId);
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <functional>
|
||||
#include <router_contact.hpp>
|
||||
#include <tooling/router_event.hpp>
|
||||
#include <peerstats/peer_db.hpp>
|
||||
|
||||
#ifdef LOKINET_HIVE
|
||||
#include "tooling/router_hive.hpp"
|
||||
|
@ -151,6 +152,9 @@ namespace llarp
|
|||
virtual I_RCLookupHandler&
|
||||
rcLookupHandler() = 0;
|
||||
|
||||
virtual std::shared_ptr<PeerDb>
|
||||
peerDb() = 0;
|
||||
|
||||
virtual bool
|
||||
Sign(Signature& sig, const llarp_buffer_t& buf) const = 0;
|
||||
|
||||
|
|
|
@ -582,7 +582,7 @@ namespace llarp
|
|||
if (conf->router.m_enablePeerStats)
|
||||
{
|
||||
LogInfo("Initializing peerdb...");
|
||||
m_peerDb = std::make_unique<PeerDb>();
|
||||
m_peerDb = std::make_shared<PeerDb>();
|
||||
m_peerDb->configure(conf->router);
|
||||
}
|
||||
|
||||
|
|
|
@ -307,6 +307,12 @@ namespace llarp
|
|||
return _rcLookupHandler;
|
||||
}
|
||||
|
||||
std::shared_ptr<PeerDb>
|
||||
peerDb() override
|
||||
{
|
||||
return m_peerDb;
|
||||
}
|
||||
|
||||
void
|
||||
GossipRCIfNeeded(const RouterContact rc) override;
|
||||
|
||||
|
@ -496,7 +502,7 @@ namespace llarp
|
|||
llarp_time_t m_LastStatsReport = 0s;
|
||||
|
||||
std::shared_ptr<llarp::KeyManager> m_keyManager;
|
||||
std::unique_ptr<PeerDb> m_peerDb;
|
||||
std::shared_ptr<PeerDb> m_peerDb;
|
||||
|
||||
uint32_t path_build_count = 0;
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include <numeric>
|
||||
#include <catch2/catch.hpp>
|
||||
#include "router_contact.hpp"
|
||||
#include "util/time.hpp"
|
||||
|
||||
TEST_CASE("Test PeerDb PeerStats memory storage", "[PeerDb]")
|
||||
{
|
||||
|
@ -111,3 +113,42 @@ TEST_CASE("Test PeerDb modifyPeerStats", "[PeerDb]")
|
|||
CHECK(stats.has_value());
|
||||
CHECK(stats.value().numPathBuilds == 42);
|
||||
}
|
||||
|
||||
TEST_CASE("Test PeerDb handleGossipedRC", "[PeerDb]")
|
||||
{
|
||||
const llarp::RouterID id = llarp::test::makeBuf<llarp::RouterID>(0xCA);
|
||||
|
||||
auto rcLifetime = llarp::RouterContact::Lifetime;
|
||||
llarp_time_t now = 0s;
|
||||
|
||||
llarp::RouterContact rc;
|
||||
rc.pubkey = llarp::PubKey(id);
|
||||
rc.last_updated = 10s;
|
||||
|
||||
llarp::PeerDb db;
|
||||
db.handleGossipedRC(rc, now);
|
||||
|
||||
auto stats = db.getCurrentPeerStats(id);
|
||||
CHECK(stats.has_value());
|
||||
CHECK(stats.value().mostExpiredRCMs == (0s - rcLifetime).count());
|
||||
CHECK(stats.value().numDistinctRCsReceived == 1);
|
||||
CHECK(stats.value().lastRCUpdated == 10000);
|
||||
|
||||
now = 9s;
|
||||
db.handleGossipedRC(rc, now);
|
||||
stats = db.getCurrentPeerStats(id);
|
||||
CHECK(stats.has_value());
|
||||
// these values should remain unchanged, this is not a new RC
|
||||
CHECK(stats.value().mostExpiredRCMs == (0s - rcLifetime).count());
|
||||
CHECK(stats.value().numDistinctRCsReceived == 1);
|
||||
CHECK(stats.value().lastRCUpdated == 10000);
|
||||
|
||||
rc.last_updated = 11s;
|
||||
|
||||
db.handleGossipedRC(rc, now);
|
||||
stats = db.getCurrentPeerStats(id);
|
||||
// new RC received at 9sec, making it (expiration time - 9 sec) expired (a negative number)
|
||||
CHECK(stats.value().mostExpiredRCMs == (9s - (now + rcLifetime)).count());
|
||||
CHECK(stats.value().numDistinctRCsReceived == 2);
|
||||
CHECK(stats.value().lastRCUpdated == 11000);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue