diff --git a/llarp/link/link_manager.cpp b/llarp/link/link_manager.cpp index e9070533a..c679b8a2e 100644 --- a/llarp/link/link_manager.cpp +++ b/llarp/link/link_manager.cpp @@ -395,6 +395,129 @@ namespace llarp }); } + bool + LinkManager::have_connection_to(const RouterID& remote, bool client_only) const + { + return ep.have_conn(remote, client_only); + } + + bool + LinkManager::have_client_connection_to(const RouterID& remote) const + { + return ep.have_conn(remote, true); + } + + void + LinkManager::deregister_peer(RouterID remote) + { + if (auto rv = ep.deregister_peer(remote); rv) + { + persisting_conns.erase(remote); + log::info(logcat, "Peer {} successfully de-registered", remote); + } + else + log::warning(logcat, "Peer {} not found for de-registration!", remote); + } + + void + LinkManager::stop() + { + if (is_stopping) + { + return; + } + + LogInfo("stopping links"); + is_stopping = true; + + quic.reset(); + } + + void + LinkManager::set_conn_persist(const RouterID& remote, llarp_time_t until) + { + if (is_stopping) + return; + + persisting_conns[remote] = std::max(until, persisting_conns[remote]); + if (have_client_connection_to(remote)) + { + // mark this as a client so we don't try to back connect + clients.Upsert(remote); + } + } + + size_t + LinkManager::get_num_connected(bool clients_only) const + { + return ep.num_connected(clients_only); + } + + size_t + LinkManager::get_num_connected_clients() const + { + return get_num_connected(true); + } + + bool + LinkManager::get_random_connected(RemoteRC& router) const + { + return ep.get_random_connection(router); + } + + // TODO: this? perhaps no longer necessary in the same way? + void + LinkManager::check_persisting_conns(llarp_time_t) + { + if (is_stopping) + return; + } + + // TODO: this + util::StatusObject + LinkManager::extract_status() const + { + return {}; + } + + void + LinkManager::init() + { + is_stopping = false; + node_db = _router.node_db(); + } + + void + LinkManager::connect_to_random(int num_conns) + { + std::set exclude; + auto remainder = num_conns; + + do + { + auto filter = [exclude](const auto& rc) -> bool { + return exclude.count(rc.router_id()) == 0; + }; + + if (auto maybe_other = node_db->GetRandom(filter)) + { + exclude.insert(maybe_other->router_id()); + + if (not node_db->is_connection_allowed(maybe_other->router_id())) + continue; + + connect_to(*maybe_other); + --remainder; + } + } while (remainder > 0); + } + + void + LinkManager::recv_data_message(oxen::quic::dgram_interface&, bstring) + { + // TODO: this + } + void LinkManager::gossip_rc(const RouterID& rc_rid, std::string serialized_rc) { @@ -575,129 +698,6 @@ namespace llarp } } - bool - LinkManager::have_connection_to(const RouterID& remote, bool client_only) const - { - return ep.have_conn(remote, client_only); - } - - bool - LinkManager::have_client_connection_to(const RouterID& remote) const - { - return ep.have_conn(remote, true); - } - - void - LinkManager::deregister_peer(RouterID remote) - { - if (auto rv = ep.deregister_peer(remote); rv) - { - persisting_conns.erase(remote); - log::info(logcat, "Peer {} successfully de-registered", remote); - } - else - log::warning(logcat, "Peer {} not found for de-registration!", remote); - } - - void - LinkManager::stop() - { - if (is_stopping) - { - return; - } - - LogInfo("stopping links"); - is_stopping = true; - - quic.reset(); - } - - void - LinkManager::set_conn_persist(const RouterID& remote, llarp_time_t until) - { - if (is_stopping) - return; - - persisting_conns[remote] = std::max(until, persisting_conns[remote]); - if (have_client_connection_to(remote)) - { - // mark this as a client so we don't try to back connect - clients.Upsert(remote); - } - } - - size_t - LinkManager::get_num_connected(bool clients_only) const - { - return ep.num_connected(clients_only); - } - - size_t - LinkManager::get_num_connected_clients() const - { - return get_num_connected(true); - } - - bool - LinkManager::get_random_connected(RemoteRC& router) const - { - return ep.get_random_connection(router); - } - - // TODO: this? perhaps no longer necessary in the same way? - void - LinkManager::check_persisting_conns(llarp_time_t) - { - if (is_stopping) - return; - } - - // TODO: this - util::StatusObject - LinkManager::extract_status() const - { - return {}; - } - - void - LinkManager::init() - { - is_stopping = false; - node_db = _router.node_db(); - } - - void - LinkManager::connect_to_random(int num_conns) - { - std::set exclude; - auto remainder = num_conns; - - do - { - auto filter = [exclude](const auto& rc) -> bool { - return exclude.count(rc.router_id()) == 0; - }; - - if (auto maybe_other = node_db->GetRandom(filter)) - { - exclude.insert(maybe_other->router_id()); - - if (not node_db->is_connection_allowed(maybe_other->router_id())) - continue; - - connect_to(*maybe_other); - --remainder; - } - } while (remainder > 0); - } - - void - LinkManager::recv_data_message(oxen::quic::dgram_interface&, bstring) - { - // TODO: this - } - void LinkManager::handle_find_name(std::string_view body, std::function respond) { diff --git a/llarp/nodedb.cpp b/llarp/nodedb.cpp index a72211727..b7bd34e68 100644 --- a/llarp/nodedb.cpp +++ b/llarp/nodedb.cpp @@ -47,13 +47,11 @@ namespace llarp } } - constexpr auto FlushInterval = 5min; - NodeDB::NodeDB(fs::path root, std::function)> diskCaller, Router* r) : _router{*r} , _root{std::move(root)} , _disk(std::move(diskCaller)) - , _next_flush_time{time_now_ms() + FlushInterval} + , _next_flush_time{time_now_ms() + FLUSH_INTERVAL} { EnsureSkiplist(_root); } @@ -67,7 +65,7 @@ namespace llarp if (now > _next_flush_time) { _router.loop()->call([this]() { - _next_flush_time += FlushInterval; + _next_flush_time += FLUSH_INTERVAL; // make copy of all rcs std::vector copy; @@ -189,7 +187,6 @@ namespace llarp fetch_source = new_source.router_id(); } - // TODO: trust model bool NodeDB::process_fetched_rcs(RouterID source, std::vector rcs, rc_time timestamp) { @@ -213,7 +210,6 @@ namespace llarp fetch_rid_responses[source] = std::move(ids); } - // TODO: trust model bool NodeDB::process_fetched_rids() { diff --git a/llarp/nodedb.hpp b/llarp/nodedb.hpp index fec6d5d51..95933fd27 100644 --- a/llarp/nodedb.hpp +++ b/llarp/nodedb.hpp @@ -28,16 +28,63 @@ namespace llarp inline constexpr size_t MAX_RID_ERRORS{ROUTER_ID_SOURCE_COUNT - MIN_RID_FETCHES}; inline constexpr int MAX_FETCH_ATTEMPTS{10}; + inline constexpr auto FLUSH_INTERVAL{5min}; + class NodeDB { - std::unordered_map known_rcs; - Router& _router; const fs::path _root; const std::function)> _disk; llarp_time_t _next_flush_time; + /******** RouterID/RouterContacts ********/ + + /** RouterID mappings + Both the following are populated in NodeDB startup with RouterID's stored on disk. + - active_client_routers: meant to persist between lokinet sessions, and is only + populated during startup and RouterID fetching. This is meant to represent the + client instance's perspective of the network and which RouterID's are "active" + - known_rcs: populated during startup and when RC's are updated both during gossip + and periodic RC fetching + */ + std::unordered_set active_client_routers; + std::unordered_map known_rcs; + + /** RouterID lists + - white: active routers + - gray: fully funded, but decommissioned routers + - green: registered, but not fully-staked routers + */ + std::unordered_set router_whitelist; + std::unordered_set router_greylist; + std::unordered_set router_greenlist; + + // All registered relays (service nodes) + std::unordered_set registered_routers; + // timing + std::unordered_map last_rc_update_times; + rc_time last_rc_update_relay_timestamp; + // only ever use to specific edges as path first-hops + std::unordered_set pinned_edges; + // source of "truth" for RC updating. This relay will also mediate requests to the + // 12 selected active RID's for RID fetching + RouterID fetch_source; + // set of 12 randomly selected RID's from the set of active client routers + std::unordered_set rid_sources; + // logs the RID's that resulted in an error during RID fetching + std::unordered_set fail_sources; + // stores all RID fetch responses for greedy comprehensive processing + std::unordered_map> fetch_rid_responses; + // tracks fetch failures from the RC node performing the initial RC fetch and mediating + // the 12 RID requests to the 12 sources, NOT failures from the 12 sources themselves + std::atomic fetch_failures{0}; + + std::atomic is_fetching_rids{false}, is_fetching_rcs{false}; + + bool + want_rc(const RouterID& rid) const; + /// asynchronously remove the files for a set of rcs on disk given their public ident key void remove_many_from_disk_async(std::unordered_set idents) const; @@ -48,41 +95,6 @@ namespace llarp std::unordered_map bootstraps; - // Router lists for snodes - // whitelist = active routers - std::unordered_set router_whitelist; - // greylist = fully funded, but decommissioned routers - std::unordered_set router_greylist; - // greenlist = registered but not fully-staked routers - std::unordered_set router_greenlist; - // all registered relays (snodes) - std::unordered_set registered_routers; - std::unordered_map last_rc_update_times; - - // Client list of active RouterID's - std::unordered_set active_client_routers; - - // only ever use to specific edges as path first-hops - std::unordered_set pinned_edges; - - // rc update info: we only set this upon a SUCCESSFUL fetching - RouterID fetch_source; - - rc_time last_rc_update_relay_timestamp; - - std::unordered_set rid_sources; - - std::unordered_set fail_sources; - - // process responses once all are received (or failed/timed out) - std::unordered_map> fetch_rid_responses; - - std::atomic is_fetching_rids{false}, is_fetching_rcs{false}; - std::atomic fetch_failures{0}; - - bool - want_rc(const RouterID& rid) const; - public: void set_bootstrap_routers(const std::set& rcs);