1
1
Fork 0
mirror of https://github.com/oxen-io/lokinet synced 2023-12-14 06:53:00 +01:00

NodeDB RCs don't need insertion time

We will want some notion of "when did we receive it" for RCs (or
RouterIDs, details tbd), but that will be per-source as a means to form
some metric of consensus/trust on which relays are *actually* on the
network.  Clients don't have a blockchain daemon to pull this from, so
they have to ask many relays for the full list of relays and form a
trust model on that (bootstrapping problem notwithstanding).
This commit is contained in:
Thomas Winget 2023-11-15 14:27:54 -05:00
parent 29ec72f0da
commit 2425652696
3 changed files with 44 additions and 83 deletions

View file

@ -26,7 +26,7 @@ namespace
namespace llarp namespace llarp
{ {
struct LinkManager; struct LinkManager;
struct NodeDB; class NodeDB;
namespace link namespace link
{ {

View file

@ -14,9 +14,6 @@ static const std::string RC_FILE_EXT = ".signed";
namespace llarp namespace llarp
{ {
NodeDB::Entry::Entry(RemoteRC value) : rc(std::move(value)), insertedAt(llarp::time_now_ms())
{}
static void static void
EnsureSkiplist(fs::path nodedbDir) EnsureSkiplist(fs::path nodedbDir)
{ {
@ -72,8 +69,8 @@ namespace llarp
// make copy of all rcs // make copy of all rcs
std::vector<RemoteRC> copy; std::vector<RemoteRC> copy;
for (const auto& item : entries) for (const auto& item : known_rcs)
copy.push_back(item.second.rc); copy.push_back(item.second);
// flush them to disk in one big job // flush them to disk in one big job
// TODO: split this up? idk maybe some day... // TODO: split this up? idk maybe some day...
@ -212,10 +209,10 @@ namespace llarp
return true; return true;
} }
// validate signature and purge entries with invalid signatures // validate signature and purge known_rcs with invalid signatures
// load ones with valid signatures // load ones with valid signatures
if (rc.verify()) if (rc.verify())
entries.emplace(rc.router_id(), rc); known_rcs.emplace(rc.router_id(), rc);
else else
purge.emplace(f); purge.emplace(f);
@ -240,33 +237,33 @@ namespace llarp
return; return;
router.loop()->call([this]() { router.loop()->call([this]() {
for (const auto& item : entries) for (const auto& item : known_rcs)
item.second.rc.write(get_path_by_pubkey(item.first)); item.second.write(get_path_by_pubkey(item.first));
}); });
} }
bool bool
NodeDB::has_router(RouterID pk) const NodeDB::has_router(RouterID pk) const
{ {
return entries.count(pk); return known_rcs.count(pk);
} }
std::optional<RemoteRC> std::optional<RemoteRC>
NodeDB::get_rc(RouterID pk) const NodeDB::get_rc(RouterID pk) const
{ {
const auto itr = entries.find(pk); const auto itr = known_rcs.find(pk);
if (itr == entries.end()) if (itr == known_rcs.end())
return std::nullopt; return std::nullopt;
return itr->second.rc; return itr->second;
} }
void void
NodeDB::remove_router(RouterID pk) NodeDB::remove_router(RouterID pk)
{ {
router.loop()->call([this, pk]() { router.loop()->call([this, pk]() {
entries.erase(pk); known_rcs.erase(pk);
remove_many_from_disk_async({pk}); remove_many_from_disk_async({pk});
}); });
} }
@ -274,22 +271,9 @@ namespace llarp
void void
NodeDB::remove_stale_rcs(std::unordered_set<RouterID> keep, llarp_time_t cutoff) NodeDB::remove_stale_rcs(std::unordered_set<RouterID> keep, llarp_time_t cutoff)
{ {
router.loop()->call([this, keep, cutoff]() { (void)keep;
std::unordered_set<RouterID> removed; (void)cutoff;
auto itr = entries.begin(); // TODO: handling of "stale" is pending change, removing here for now.
while (itr != entries.end())
{
if (itr->second.insertedAt < cutoff and keep.count(itr->second.rc.router_id()) == 0)
{
removed.insert(itr->second.rc.router_id());
itr = entries.erase(itr);
}
else
++itr;
}
if (not removed.empty())
remove_many_from_disk_async(std::move(removed));
});
} }
bool bool
@ -298,22 +282,22 @@ namespace llarp
const auto& rid = rc.router_id(); const auto& rid = rc.router_id();
if (not want_rc(rid)) if (not want_rc(rid))
return false; return false;
entries.erase(rid); known_rcs.erase(rid);
entries.emplace(rid, rc); known_rcs.emplace(rid, std::move(rc));
return true; return true;
} }
size_t size_t
NodeDB::num_loaded() const NodeDB::num_loaded() const
{ {
return router.loop()->call_get([this]() { return entries.size(); }); return router.loop()->call_get([this]() { return known_rcs.size(); });
} }
bool bool
NodeDB::put_rc_if_newer(RemoteRC rc) NodeDB::put_rc_if_newer(RemoteRC rc)
{ {
auto itr = entries.find(rc.router_id()); auto itr = known_rcs.find(rc.router_id());
if (itr == entries.end() or itr->second.rc.other_is_newer(rc)) if (itr == known_rcs.end() or itr->second.other_is_newer(rc))
{ {
return put_rc(std::move(rc)); return put_rc(std::move(rc));
} }
@ -364,10 +348,10 @@ namespace llarp
return router.loop()->call_get([this, location, numRouters]() -> std::vector<RemoteRC> { return router.loop()->call_get([this, location, numRouters]() -> std::vector<RemoteRC> {
std::vector<const RemoteRC*> all; std::vector<const RemoteRC*> all;
all.reserve(entries.size()); all.reserve(known_rcs.size());
for (auto& entry : entries) for (auto& entry : known_rcs)
{ {
all.push_back(&entry.second.rc); all.push_back(&entry.second);
} }
auto it_mid = numRouters < all.size() ? all.begin() + numRouters : all.end(); auto it_mid = numRouters < all.size() ? all.begin() + numRouters : all.end();

View file

@ -24,16 +24,7 @@ namespace llarp
class NodeDB class NodeDB
{ {
struct Entry std::unordered_map<RouterID, RemoteRC> known_rcs;
{
const RemoteRC rc;
llarp_time_t insertedAt;
explicit Entry(RemoteRC rc);
};
using NodeMap = std::unordered_map<RouterID, Entry>;
NodeMap entries;
const Router& router; const Router& router;
const fs::path m_Root; const fs::path m_Root;
@ -137,7 +128,7 @@ namespace llarp
/// in memory nodedb /// in memory nodedb
NodeDB(); NodeDB();
/// load all entries from disk syncrhonously /// load all known_rcs from disk syncrhonously
void void
load_from_disk(); load_from_disk();
@ -174,44 +165,30 @@ namespace llarp
GetRandom(Filter visit) const GetRandom(Filter visit) const
{ {
return router.loop()->call_get([visit]() -> std::optional<RemoteRC> { return router.loop()->call_get([visit]() -> std::optional<RemoteRC> {
std::vector<const decltype(entries)::value_type*> entries; std::vector<const decltype(known_rcs)::value_type*> known_rcs;
for (const auto& entry : entries) for (const auto& entry : known_rcs)
entries.push_back(entry); known_rcs.push_back(entry);
std::shuffle(entries.begin(), entries.end(), llarp::csrng); std::shuffle(known_rcs.begin(), known_rcs.end(), llarp::csrng);
for (const auto entry : entries) for (const auto entry : known_rcs)
{ {
if (visit(entry->second.rc)) if (visit(entry->second))
return entry->second.rc; return entry->second;
} }
return std::nullopt; return std::nullopt;
}); });
} }
/// visit all entries /// visit all known_rcs
template <typename Visit> template <typename Visit>
void void
VisitAll(Visit visit) const VisitAll(Visit visit) const
{ {
router.loop()->call([this, visit]() { router.loop()->call([this, visit]() {
for (const auto& item : entries) for (const auto& item : known_rcs)
visit(item.second.rc); visit(item.second);
});
}
/// visit all entries inserted before a timestamp
template <typename Visit>
void
VisitInsertedBefore(Visit visit, llarp_time_t insertedBefore)
{
router.loop()->call([this, visit, insertedBefore]() {
for (const auto& item : entries)
{
if (item.second.insertedAt < insertedBefore)
visit(item.second.rc);
}
}); });
} }
@ -226,13 +203,13 @@ namespace llarp
{ {
router.loop()->call([this, visit]() { router.loop()->call([this, visit]() {
std::unordered_set<RouterID> removed; std::unordered_set<RouterID> removed;
auto itr = entries.begin(); auto itr = known_rcs.begin();
while (itr != entries.end()) while (itr != known_rcs.end())
{ {
if (visit(itr->second.rc)) if (visit(itr->second))
{ {
removed.insert(itr->second.rc.router_id()); removed.insert(itr->second.router_id());
itr = entries.erase(itr); itr = known_rcs.erase(itr);
} }
else else
++itr; ++itr;
@ -246,14 +223,14 @@ namespace llarp
void void
remove_stale_rcs(std::unordered_set<RouterID> keep, llarp_time_t cutoff); remove_stale_rcs(std::unordered_set<RouterID> keep, llarp_time_t cutoff);
/// put (or replace) the RC if we consider it valid (want_rc). returns true if put.
bool
put_rc(RemoteRC rc);
/// if we consider it valid (want_rc), /// if we consider it valid (want_rc),
/// put this rc into the cache if it is not there or is newer than the one there already /// put this rc into the cache if it is not there or is newer than the one there already
/// returns true if the rc was inserted /// returns true if the rc was inserted
bool bool
put_rc_if_newer(RemoteRC rc); put_rc_if_newer(RemoteRC rc);
/// put (or replace) the RC if we consider it valid (want_rc). returns true if put.
bool
put_rc(RemoteRC rc);
}; };
} // namespace llarp } // namespace llarp