Add implementation of get_peer_stats API

pull/1318/head
Stephen Shelton 4 years ago
parent bbc1cd5a31
commit eedf7ca599
No known key found for this signature in database
GPG Key ID: EE4BADACCE8B631C

@ -140,6 +140,22 @@ namespace llarp
return itr->second;
}
std::vector<PeerStats>
PeerDb::listAllPeerStats() const
{
std::lock_guard guard(m_statsLock);
std::vector<PeerStats> statsList;
statsList.reserve(m_peerStats.size());
for (const auto& [routerId, stats] : m_peerStats)
{
statsList.push_back(stats);
}
return statsList;
}
/// Assume we receive an RC at some point `R` in time which was signed at some point `S` in time
/// and expires at some point `E` in time, as depicted below:
///

@ -82,6 +82,14 @@ namespace llarp
std::optional<PeerStats>
getCurrentPeerStats(const RouterID& routerId) const;
/// Lists all peer stats. This essentially dumps the database into a list of PeerStats objects.
///
/// Note that this avoids disk I/O by copying from our cached map of peers.
///
/// @return a list of all PeerStats we have maintained
std::vector<PeerStats>
listAllPeerStats() const;
/// Handles a new gossiped RC, updating stats as needed. The database tracks the last
/// advertised update time, so it knows whether this is a new RC or not.
///

@ -101,7 +101,7 @@ namespace llarp
}
void
PeerStats::BEncode(llarp_buffer_t* buf)
PeerStats::BEncode(llarp_buffer_t* buf) const
{
if (not buf)
throw std::runtime_error("PeerStats: Can't use null buf");
@ -138,4 +138,22 @@ namespace llarp
}
void
PeerStats::BEncodeList(const std::vector<PeerStats>& statsList, llarp_buffer_t* buf)
{
if (not buf)
throw std::runtime_error("PeerStats: Can't use null buf");
if (not bencode_start_list(buf))
throw std::runtime_error("PeerStats: Could not create bencode dict");
for (const auto& stats : statsList)
{
stats.BEncode(buf);
}
if (not bencode_end(buf))
throw std::runtime_error("PeerStats: Could not end bencode dict");
}
}; // namespace llarp

@ -50,7 +50,10 @@ namespace llarp
toJson() const;
void
BEncode(llarp_buffer_t* buf);
BEncode(llarp_buffer_t* buf) const;
static void
BEncodeList(const std::vector<PeerStats>& statsList, llarp_buffer_t* buf);
};
} // namespace llarp

@ -220,12 +220,40 @@ namespace llarp
void
LokidRpcClient::HandleGetPeerStats(lokimq::Message& msg)
{
// TODO: construct response
LogInfo("Got request for peer stats (size: ", msg.data.size(), ")");
for (auto str : msg.data)
{
LogInfo(" :", str);
}
assert(m_Router != nullptr);
if (not m_Router->peerDb())
{
LogWarn("HandleGetPeerStats called when router has no peerDb set up.");
throw std::runtime_error("Cannot handle get_peer_stats request when no peer db available");
}
try
{
// TODO: parse input, expect list of peers to query for
auto statsList = m_Router->peerDb()->listAllPeerStats();
int32_t bufSize =
256 + (statsList.size() * 1024); // TODO: tune this or allow to grow dynamically
auto buf = std::unique_ptr<uint8_t[]>(new uint8_t[bufSize]);
llarp_buffer_t llarpBuf(buf.get(), bufSize);
PeerStats::BEncodeList(statsList, &llarpBuf);
msg.send_reply(std::string_view((const char*)llarpBuf.base, llarpBuf.cur - llarpBuf.base));
}
catch (const std::exception& e)
{
LogError("Failed to handle get_peer_stats request: ", e.what());
// TODO: reply with explicit rejection to make lokid's life easier
}
}
} // namespace rpc

Loading…
Cancel
Save