mirror of https://github.com/oxen-io/lokinet
implement new rc gossip logic
Relays will now re-sign and gossip their RCs every 6 hours (minus a couple random minutes) using the new gossip_rc message. Removes the old RCGossiper conceptpull/2224/head
parent
2425652696
commit
b044622a21
@ -1,151 +0,0 @@
|
||||
#include "rc_gossiper.hpp"
|
||||
|
||||
#include <llarp/router_contact.hpp>
|
||||
#include <llarp/util/time.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
// 30 minutes
|
||||
static constexpr auto RCGossipFilterDecayInterval = 30min;
|
||||
// (30 minutes * 2) - 5 minutes
|
||||
static constexpr auto GossipOurRCInterval = (RCGossipFilterDecayInterval * 2) - (5min);
|
||||
|
||||
RCGossiper::RCGossiper() : filter(std::chrono::duration_cast<Time_t>(RCGossipFilterDecayInterval))
|
||||
{}
|
||||
|
||||
void
|
||||
RCGossiper::Init(LinkManager* l, const RouterID& ourID, Router* r)
|
||||
{
|
||||
rid = ourID;
|
||||
link_manager = l;
|
||||
router = r;
|
||||
}
|
||||
|
||||
bool
|
||||
RCGossiper::ShouldGossipOurRC(Time_t now) const
|
||||
{
|
||||
return now >= (last_rc_gossip + GossipOurRCInterval);
|
||||
}
|
||||
|
||||
bool
|
||||
RCGossiper::IsOurRC(const LocalRC& rc) const
|
||||
{
|
||||
return rc.router_id() == rid;
|
||||
}
|
||||
|
||||
void
|
||||
RCGossiper::Decay(Time_t now)
|
||||
{
|
||||
filter.Decay(now);
|
||||
}
|
||||
|
||||
void
|
||||
RCGossiper::Forget(const RouterID& pk)
|
||||
{
|
||||
filter.Remove(pk);
|
||||
if (rid == pk)
|
||||
last_rc_gossip = 0s;
|
||||
}
|
||||
|
||||
TimePoint_t
|
||||
RCGossiper::NextGossipAt() const
|
||||
{
|
||||
if (auto maybe = LastGossipAt())
|
||||
return *maybe + GossipOurRCInterval;
|
||||
return DateClock_t::now();
|
||||
}
|
||||
|
||||
std::optional<TimePoint_t>
|
||||
RCGossiper::LastGossipAt() const
|
||||
{
|
||||
if (last_rc_gossip == 0s)
|
||||
return std::nullopt;
|
||||
return DateClock_t::time_point{last_rc_gossip};
|
||||
}
|
||||
|
||||
bool
|
||||
RCGossiper::GossipRC(const LocalRC& rc)
|
||||
{
|
||||
// only distribute public routers
|
||||
if (not rc.is_public_router())
|
||||
return false;
|
||||
if (link_manager == nullptr)
|
||||
return false;
|
||||
const RouterID pubkey(rc.router_id());
|
||||
// filter check
|
||||
if (filter.Contains(pubkey))
|
||||
return false;
|
||||
filter.Insert(pubkey);
|
||||
|
||||
const auto now = time_now_ms();
|
||||
// is this our rc?
|
||||
if (IsOurRC(rc))
|
||||
{
|
||||
// should we gossip our rc?
|
||||
if (not ShouldGossipOurRC(now))
|
||||
{
|
||||
// nah drop it
|
||||
return false;
|
||||
}
|
||||
// ya pop it
|
||||
last_rc_gossip = now;
|
||||
}
|
||||
|
||||
// send a GRCM as gossip method
|
||||
// DHTImmediateMessage gossip;
|
||||
// gossip.msgs.emplace_back(new dht::GotRouterMessage(dht::Key_t{}, 0, {rc}, false));
|
||||
|
||||
// std::vector<RouterID> gossipTo;
|
||||
|
||||
/*
|
||||
* TODO: gossip RC via libquic
|
||||
*
|
||||
// select peers to gossip to
|
||||
m_LinkManager->ForEachPeer(
|
||||
[&](const AbstractLinkSession* peerSession, bool) {
|
||||
// ensure connected session
|
||||
if (not(peerSession && peerSession->IsEstablished()))
|
||||
return;
|
||||
// check if public router
|
||||
const auto other_rc = peerSession->GetRemoteRC();
|
||||
if (not other_rc.IsPublicRouter())
|
||||
return;
|
||||
gossipTo.emplace_back(other_rc.pubkey);
|
||||
},
|
||||
true);
|
||||
|
||||
std::unordered_set<RouterID> keys;
|
||||
// grab the keys we want to use
|
||||
std::sample(
|
||||
gossipTo.begin(), gossipTo.end(), std::inserter(keys, keys.end()), MaxGossipPeers,
|
||||
llarp::csrng);
|
||||
|
||||
m_LinkManager->ForEachPeer([&](AbstractLinkSession* peerSession) {
|
||||
if (not(peerSession && peerSession->IsEstablished()))
|
||||
return;
|
||||
|
||||
// exclude from gossip as we have not selected to use it
|
||||
if (keys.count(peerSession->GetPubKey()) == 0)
|
||||
return;
|
||||
|
||||
// encode message
|
||||
AbstractLinkSession::Message_t msg{};
|
||||
msg.resize(MAX_LINK_MSG_SIZE / 2);
|
||||
llarp_buffer_t buf(msg);
|
||||
if (not gossip.BEncode(&buf))
|
||||
return;
|
||||
msg.resize(buf.cur - buf.base);
|
||||
|
||||
m_router->NotifyRouterEvent<tooling::RCGossipSentEvent>(m_router->pubkey(), rc);
|
||||
|
||||
// send message
|
||||
peerSession->SendMessageBuffer(std::move(msg), nullptr, gossip.Priority());
|
||||
});
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace llarp
|
@ -1,57 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <llarp/router_id.hpp>
|
||||
#include <llarp/util/decaying_hashset.hpp>
|
||||
|
||||
#include <optional>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
struct Router;
|
||||
|
||||
/// The maximum number of peers we will flood a gossiped RC to when propagating an RC
|
||||
constexpr size_t MaxGossipPeers = 20;
|
||||
struct LinkManager;
|
||||
struct LocalRC;
|
||||
|
||||
struct RCGossiper
|
||||
{
|
||||
using Time_t = Duration_t;
|
||||
|
||||
RCGossiper();
|
||||
|
||||
~RCGossiper() = default;
|
||||
|
||||
bool
|
||||
GossipRC(const LocalRC& rc);
|
||||
|
||||
void
|
||||
Decay(Time_t now);
|
||||
|
||||
bool
|
||||
ShouldGossipOurRC(Time_t now) const;
|
||||
|
||||
bool
|
||||
IsOurRC(const LocalRC& rc) const;
|
||||
|
||||
void
|
||||
Init(LinkManager*, const RouterID&, Router*);
|
||||
|
||||
void
|
||||
Forget(const RouterID& router);
|
||||
|
||||
TimePoint_t
|
||||
NextGossipAt() const;
|
||||
|
||||
std::optional<TimePoint_t>
|
||||
LastGossipAt() const;
|
||||
|
||||
private:
|
||||
RouterID rid;
|
||||
Time_t last_rc_gossip = 0s;
|
||||
LinkManager* link_manager = nullptr;
|
||||
util::DecayingHashSet<RouterID> filter;
|
||||
|
||||
Router* router;
|
||||
};
|
||||
} // namespace llarp
|
Loading…
Reference in New Issue