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:
parent
29ec72f0da
commit
2425652696
3 changed files with 44 additions and 83 deletions
|
@ -26,7 +26,7 @@ namespace
|
||||||
namespace llarp
|
namespace llarp
|
||||||
{
|
{
|
||||||
struct LinkManager;
|
struct LinkManager;
|
||||||
struct NodeDB;
|
class NodeDB;
|
||||||
|
|
||||||
namespace link
|
namespace link
|
||||||
{
|
{
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue