adds methods to print slot details from command

This commit is contained in:
Vito
2025-05-28 16:30:59 +02:00
parent cf4f95a9c9
commit 0f2fec66dc
3 changed files with 145 additions and 18 deletions

View File

@@ -52,12 +52,42 @@ enum class PeerState : uint8_t {
Selected, // selected to relay, counting if Slot in Counting
Squelched, // squelched, doesn't relay
};
inline std::string
to_string(PeerState state)
{
switch (state)
{
case PeerState::Counting:
return "counting";
case PeerState::Selected:
return "selected";
case PeerState::Squelched:
return "squelched";
default:
return "unknown";
}
}
/** Slot's State */
enum class SlotState : uint8_t {
Counting, // counting messages
Selected, // peers selected, stop counting
};
inline std::string
to_string(SlotState state)
{
switch (state)
{
case SlotState::Counting:
return "counting";
case SlotState::Selected:
return "selected";
default:
return "unknown";
}
}
template <typename Unit, typename TP>
Unit
epoch(TP const& t)
@@ -237,13 +267,17 @@ private:
void
initCounting();
void
onWrite(beast::PropertyStream::Map& stream) const;
/** Data maintained for each peer */
struct PeerInfo
{
PeerState state; // peer's state
std::size_t count; // message count
time_point expire; // squelch expiration time
time_point lastMessage; // time last message received
PeerState state; // peer's state
std::size_t count; // message count
time_point expire; // squelch expiration time
time_point lastMessage; // time last message received
std::size_t timesSelected; // number of times the peer was selected
};
std::unordered_map<id_t, PeerInfo> peers_; // peer's data
@@ -308,8 +342,14 @@ Slot<clock_type>::update(
{
JLOG(journal_.trace())
<< "update: adding peer " << Slice(validator) << " " << id;
peers_.emplace(
std::make_pair(id, PeerInfo{PeerState::Counting, 0, now, now}));
peers_.emplace(std::make_pair(
id,
PeerInfo{
.state = PeerState::Counting,
.count = 0,
.expire = now,
.lastMessage = now,
.timesSelected = 0}));
initCounting();
return;
}
@@ -412,7 +452,11 @@ Slot<clock_type>::update(
v.count = 0;
if (selected.find(k) != selected.end())
{
v.state = PeerState::Selected;
++v.timesSelected;
}
else if (v.state != PeerState::Squelched)
{
if (journal_.trace())
@@ -491,6 +535,34 @@ Slot<clock_type>::deletePeer(PublicKey const& validator, id_t id, bool erase)
}
}
template <typename clock_type>
void
Slot<clock_type>::onWrite(beast::PropertyStream::Map& stream) const
{
auto const now = clock_type::now();
stream["state"] = to_string(state_);
stream["reachedThreshold"] = reachedThreshold_;
stream["considered"] = considered_.size();
stream["lastSelected"] =
duration_cast<std::chrono::seconds>(now - lastSelected_).count();
stream["isTrusted"] = isTrusted_;
beast::PropertyStream::Set peers("peers", stream);
for (auto const& [id, info] : peers_)
{
beast::PropertyStream::Map item(peers);
item["id"] = id;
item["count"] = info.count;
item["expire"] =
duration_cast<std::chrono::seconds>(info.expire - now).count();
item["lastMessage"] =
duration_cast<std::chrono::seconds>(now - info.lastMessage).count();
item["timesSelected"] = info.timesSelected;
item["state"] = to_string(info.state);
}
}
template <typename clock_type>
void
Slot<clock_type>::resetCounts()
@@ -786,6 +858,9 @@ public:
it->second.insert(id);
}
void
onWrite(beast::PropertyStream::Map& stream) const;
private:
/** Add message/peer if have not seen this message
* from the peer. A message is aged after IDLED seconds.
@@ -1137,6 +1212,52 @@ Slots<clock_type>::deleteIdlePeers()
handler_.squelchAll(validator, MAX_UNSQUELCH_EXPIRE_DEFAULT.count());
}
template <typename clock_type>
void
Slots<clock_type>::onWrite(beast::PropertyStream::Map& stream) const
{
auto const writeSlot =
[](beast::PropertyStream::Set& set,
hash_map<PublicKey, Slot<clock_type>> const& slots) {
for (auto const& [validator, slot] : slots)
{
beast::PropertyStream::Map item(set);
item["validator"] = toBase58(TokenType::NodePublic, validator);
slot.onWrite(item);
}
};
beast::PropertyStream::Map slots("slots", stream);
{
beast::PropertyStream::Set set("trusted", slots);
writeSlot(set, slots_);
}
{
beast::PropertyStream::Set set("untrusted", slots);
writeSlot(set, untrusted_slots_);
}
{
beast::PropertyStream::Set set("considered", slots);
auto const now = clock_type::now();
for (auto const& [validator, info] : considered_validators_)
{
beast::PropertyStream::Map item(set);
item["validator"] = toBase58(TokenType::NodePublic, validator);
item["lastMessage"] =
std::chrono::duration_cast<std::chrono::seconds>(
now - info.lastMessage)
.count();
item["messageCount"] = info.count;
item["peers"] = info.peers.size();
}
}
}
} // namespace reduce_relay
} // namespace ripple

View File

@@ -22,12 +22,11 @@
#include <xrpld/overlay/ReduceRelayCommon.h>
#include <xrpl/basics/Log.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/protocol/PublicKey.h>
#include <algorithm>
#include <chrono>
#include <functional>
namespace ripple {
@@ -108,7 +107,7 @@ template <typename clock_type>
bool
Squelch<clock_type>::expireSquelch(PublicKey const& validator)
{
auto now = clock_type::now();
auto const now = clock_type::now();
auto const& it = squelched_.find(validator);
if (it == squelched_.end())

View File

@@ -578,16 +578,23 @@ OverlayImpl::stop()
void
OverlayImpl::onWrite(beast::PropertyStream::Map& stream)
{
beast::PropertyStream::Set set("traffic", stream);
auto const stats = m_traffic.getCounts();
for (auto const& pair : stats)
{
beast::PropertyStream::Map item(set);
item["category"] = pair.second.name;
item["bytes_in"] = std::to_string(pair.second.bytesIn.load());
item["messages_in"] = std::to_string(pair.second.messagesIn.load());
item["bytes_out"] = std::to_string(pair.second.bytesOut.load());
item["messages_out"] = std::to_string(pair.second.messagesOut.load());
beast::PropertyStream::Set set("traffic", stream);
auto const stats = m_traffic.getCounts();
for (auto const& pair : stats)
{
beast::PropertyStream::Map item(set);
item["category"] = pair.second.name;
item["bytes_in"] = std::to_string(pair.second.bytesIn.load());
item["messages_in"] = std::to_string(pair.second.messagesIn.load());
item["bytes_out"] = std::to_string(pair.second.bytesOut.load());
item["messages_out"] =
std::to_string(pair.second.messagesOut.load());
}
}
{
slots_.onWrite(stream);
}
}