feat(telemetry): add 7-day validation agreement window to ValidationTracker

Add window7d_ deque, agreementPct7d(), agreements7d(), missed7d() to
match the external xrpl-validator-dashboard's 7-day agreement tracking.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Pratik Mankawde
2026-03-31 16:38:21 +01:00
parent f51976f63e
commit eca887c66e
2 changed files with 54 additions and 1 deletions

View File

@@ -139,6 +139,12 @@ public:
double
agreementPct24h() const;
/** Agreement percentage over the last 7 days.
* @return Percentage [0.0, 100.0], or 0.0 if no data.
*/
double
agreementPct7d() const;
/** @} */
/** @name Rolling-window count getters */
@@ -160,6 +166,14 @@ public:
uint64_t
missed24h() const;
/** Number of agreements in the 7-day window. */
uint64_t
agreements7d() const;
/** Number of misses in the 7-day window. */
uint64_t
missed7d() const;
/** @} */
/** @name Lifetime totals (atomic, lock-free reads) */
@@ -223,7 +237,10 @@ private:
/// Duration of the long rolling window.
static constexpr auto kWindow24h = std::chrono::hours(24);
/// Protects pending_, window1h_, and window24h_.
/// Duration of the extended rolling window (7 days).
static constexpr auto kWindow7d = std::chrono::hours(168);
/// Protects pending_, window1h_, window24h_, and window7d_.
mutable std::mutex mutex_;
/// Pending ledger events indexed by ledger hash.
@@ -235,6 +252,9 @@ private:
/// Sliding window of reconciled events (last 24 hours).
std::deque<WindowEvent> window24h_;
/// Sliding window of reconciled events (last 7 days).
std::deque<WindowEvent> window7d_;
/// Lifetime count of agreements.
std::atomic<uint64_t> totalAgreements_{0};

View File

@@ -62,6 +62,7 @@ ValidationTracker::reconcile()
WindowEvent we{now, evt.ledgerHash, evt.agreed};
window1h_.push_back(we);
window24h_.push_back(we);
window7d_.push_back(we);
}
else if (
evt.reconciled && !evt.agreed && evt.weValidated && evt.networkValidated &&
@@ -75,6 +76,7 @@ ValidationTracker::reconcile()
// Flip the corresponding window entries from miss to agreement.
repairWindowEntry(window1h_, evt.ledgerHash);
repairWindowEntry(window24h_, evt.ledgerHash);
repairWindowEntry(window7d_, evt.ledgerHash);
}
}
@@ -92,6 +94,10 @@ ValidationTracker::evictStaleWindows(TimePoint now)
auto const cutoff24h = now - kWindow24h;
while (!window24h_.empty() && window24h_.front().time < cutoff24h)
window24h_.pop_front();
auto const cutoff7d = now - kWindow7d;
while (!window7d_.empty() && window7d_.front().time < cutoff7d)
window7d_.pop_front();
}
void
@@ -186,6 +192,33 @@ ValidationTracker::missed24h() const
window24h_.begin(), window24h_.end(), [](auto const& e) { return !e.agreed; }));
}
double
ValidationTracker::agreementPct7d() const
{
std::lock_guard lock(mutex_);
if (window7d_.empty())
return 0.0;
auto const agreed = static_cast<double>(
std::count_if(window7d_.begin(), window7d_.end(), [](auto const& e) { return e.agreed; }));
return (agreed / static_cast<double>(window7d_.size())) * 100.0;
}
uint64_t
ValidationTracker::agreements7d() const
{
std::lock_guard lock(mutex_);
return static_cast<uint64_t>(
std::count_if(window7d_.begin(), window7d_.end(), [](auto const& e) { return e.agreed; }));
}
uint64_t
ValidationTracker::missed7d() const
{
std::lock_guard lock(mutex_);
return static_cast<uint64_t>(
std::count_if(window7d_.begin(), window7d_.end(), [](auto const& e) { return !e.agreed; }));
}
uint64_t
ValidationTracker::totalAgreements() const
{