lokinet/llarp/nodedb.hpp

245 lines
5.6 KiB
C++
Raw Normal View History

2018-08-30 18:48:43 +00:00
#ifndef LLARP_NODEDB_HPP
#define LLARP_NODEDB_HPP
2018-12-12 01:55:30 +00:00
#include <router_contact.hpp>
#include <router_id.hpp>
#include <util/common.hpp>
#include <util/fs.hpp>
2019-09-01 13:26:16 +00:00
#include <util/thread/threading.hpp>
#include <dht/key.hpp>
#include <absl/base/thread_annotations.h>
#include <set>
2019-07-30 23:42:13 +00:00
#include <utility>
/**
2018-08-30 18:48:43 +00:00
* nodedb.hpp
*
* persistent storage API for router contacts
*/
struct llarp_threadpool;
2018-12-10 14:14:55 +00:00
namespace llarp
{
class Logic;
namespace thread
{
class ThreadPool;
}
} // namespace llarp
2018-12-10 14:14:55 +00:00
2018-06-18 22:05:02 +00:00
struct llarp_nodedb_iter
{
void *user;
2018-08-30 18:48:43 +00:00
llarp::RouterContact *rc;
size_t index;
2018-06-18 22:05:02 +00:00
bool (*visit)(struct llarp_nodedb_iter *);
};
struct llarp_nodedb
{
explicit llarp_nodedb(std::shared_ptr< llarp::thread::ThreadPool > diskworker,
const std::string rootdir)
: disk(std::move(diskworker)), nodePath(rootdir)
{
}
2018-06-18 22:05:02 +00:00
~llarp_nodedb()
{
Clear();
}
2019-07-09 13:47:24 +00:00
std::shared_ptr< llarp::thread::ThreadPool > disk;
mutable llarp::util::Mutex access; // protects entries
2020-01-14 17:01:41 +00:00
/// time for next save to disk event, 0 if never happened
llarp_time_t m_NextSaveToDisk = 0;
/// how often to save to disk
const llarp_time_t m_SaveInterval = 60 * 5 * 1000;
struct NetDBEntry
{
const llarp::RouterContact rc;
llarp_time_t inserted;
2019-07-30 23:42:13 +00:00
NetDBEntry(llarp::RouterContact data);
};
using NetDBMap_t =
std::unordered_map< llarp::RouterID, NetDBEntry, llarp::RouterID::Hash >;
NetDBMap_t entries GUARDED_BY(access);
fs::path nodePath;
2018-06-19 17:11:24 +00:00
llarp::RouterContact
FindClosestTo(const llarp::dht::Key_t &location);
2020-01-14 17:01:41 +00:00
/// return true if we should save our nodedb to disk
bool
ShouldSaveToDisk(llarp_time_t now = 0) const;
bool
Remove(const llarp::RouterID &pk) LOCKS_EXCLUDED(access);
2018-06-18 22:05:02 +00:00
void
RemoveIf(std::function< bool(const llarp::RouterContact &) > filter)
LOCKS_EXCLUDED(access);
void
Clear() LOCKS_EXCLUDED(access);
2018-06-18 22:05:02 +00:00
bool
Get(const llarp::RouterID &pk, llarp::RouterContact &result)
LOCKS_EXCLUDED(access);
bool
Has(const llarp::RouterID &pk) LOCKS_EXCLUDED(access);
std::string
getRCFilePath(const llarp::RouterID &pubkey) const;
/// insert without writing to disk
bool
Insert(const llarp::RouterContact &rc) LOCKS_EXCLUDED(access);
/// invokes Insert() asynchronously with an optional completion
/// callback
void
2019-05-22 16:20:50 +00:00
InsertAsync(llarp::RouterContact rc,
std::shared_ptr< llarp::Logic > l = nullptr,
std::function< void(void) > completionHandler = nullptr);
/// update rc if newer
/// return true if we started to put this rc in the database
/// retur false if not newer
bool
UpdateAsyncIfNewer(llarp::RouterContact rc,
std::shared_ptr< llarp::Logic > l = nullptr,
std::function< void(void) > completionHandler = nullptr)
LOCKS_EXCLUDED(access);
ssize_t
Load(const fs::path &path);
ssize_t
loadSubdir(const fs::path &dir);
/// save all entries to disk async
void
AsyncFlushToDisk();
bool
loadfile(const fs::path &fpath) LOCKS_EXCLUDED(access);
void
visit(std::function< bool(const llarp::RouterContact &) > visit)
LOCKS_EXCLUDED(access);
void
set_dir(const char *dir);
ssize_t
LoadAll();
ssize_t
store_dir(const char *dir);
2019-06-20 14:00:04 +00:00
/// visit all entries inserted into nodedb cache before a timestamp
void
2019-06-20 14:00:04 +00:00
VisitInsertedBefore(std::function< void(const llarp::RouterContact &) > visit,
llarp_time_t insertedAfter) LOCKS_EXCLUDED(access);
void
RemoveStaleRCs(const std::set< llarp::RouterID > &keep, llarp_time_t cutoff);
size_t
num_loaded() const LOCKS_EXCLUDED(access);
bool
select_random_exit(llarp::RouterContact &rc) LOCKS_EXCLUDED(access);
bool
select_random_hop(const llarp::RouterContact &prev,
llarp::RouterContact &result, size_t N)
LOCKS_EXCLUDED(access);
bool
select_random_hop_excluding(llarp::RouterContact &result,
const std::set< llarp::RouterID > &exclude)
LOCKS_EXCLUDED(access);
static bool
ensure_dir(const char *dir);
void
SaveAll() LOCKS_EXCLUDED(access);
};
2018-06-18 22:05:02 +00:00
/// struct for async rc verification
struct llarp_async_verify_rc;
using llarp_async_verify_rc_hook_func =
std::function< void(struct llarp_async_verify_rc *) >;
2018-06-18 22:05:02 +00:00
/// verify rc request
struct llarp_async_verify_rc
{
/// async_verify_context
void *user;
/// nodedb storage
llarp_nodedb *nodedb;
2018-12-10 14:14:55 +00:00
// llarp::Logic for queue_job
2019-07-12 14:07:12 +00:00
std::shared_ptr< llarp::Logic > logic;
2019-07-09 13:47:24 +00:00
std::shared_ptr< llarp::thread::ThreadPool > cryptoworker;
std::shared_ptr< llarp::thread::ThreadPool > diskworker;
2018-06-18 22:05:02 +00:00
2018-07-03 13:13:56 +00:00
/// router contact
2018-08-30 18:48:43 +00:00
llarp::RouterContact rc;
2018-06-18 22:05:02 +00:00
/// result
bool valid;
/// hook
llarp_async_verify_rc_hook_func hook;
};
/**
struct for async rc verification
data is loaded in disk io threadpool
crypto is done on the crypto worker threadpool
result is called on the logic thread
*/
void
llarp_nodedb_async_verify(struct llarp_async_verify_rc *job);
struct llarp_async_load_rc;
using llarp_async_load_rc_hook_func =
std::function< void(struct llarp_async_load_rc *) >;
2018-06-18 22:05:02 +00:00
struct llarp_async_load_rc
{
/// async_verify_context
void *user;
/// nodedb storage
llarp_nodedb *nodedb;
2018-12-10 14:14:55 +00:00
/// llarp::Logic for calling hook
llarp::Logic *logic;
2018-06-18 22:05:02 +00:00
/// disk worker threadpool
llarp::thread::ThreadPool *diskworker;
2018-06-18 22:05:02 +00:00
/// target pubkey
2018-08-30 18:48:43 +00:00
llarp::PubKey pubkey;
2018-06-18 22:05:02 +00:00
/// router contact result
2018-08-30 18:48:43 +00:00
llarp::RouterContact result;
2018-06-18 22:05:02 +00:00
/// set to true if we loaded the rc
bool loaded;
/// hook function called in logic thread
llarp_async_load_rc_hook_func hook;
};
/// asynchronously load an rc from disk
void
llarp_nodedb_async_load_rc(struct llarp_async_load_rc *job);
2018-06-13 12:58:51 +00:00
2018-04-08 12:18:16 +00:00
#endif