diff --git a/.github/scripts/levelization/results/ordering.txt b/.github/scripts/levelization/results/ordering.txt index b77b1315a8..5a2307b1be 100644 --- a/.github/scripts/levelization/results/ordering.txt +++ b/.github/scripts/levelization/results/ordering.txt @@ -191,18 +191,12 @@ test.toplevel > xrpl.json test.unit_test > xrpl.basics test.unit_test > xrpl.protocol tests.libxrpl > xrpl.basics -tests.libxrpl > xrpl.core tests.libxrpl > xrpld.telemetry tests.libxrpl > xrpl.json -tests.libxrpl > xrpl.ledger tests.libxrpl > xrpl.net -tests.libxrpl > xrpl.nodestore tests.libxrpl > xrpl.protocol tests.libxrpl > xrpl.protocol_autogen -tests.libxrpl > xrpl.server -tests.libxrpl > xrpl.shamap tests.libxrpl > xrpl.telemetry -tests.libxrpl > xrpl.tx xrpl.conditions > xrpl.basics xrpl.conditions > xrpl.protocol xrpl.core > xrpl.basics diff --git a/include/xrpl/beast/insight/OTelCollector.h b/include/xrpl/beast/insight/OTelCollector.h index 8e59155998..ee4d294c0a 100644 --- a/include/xrpl/beast/insight/OTelCollector.h +++ b/include/xrpl/beast/insight/OTelCollector.h @@ -40,8 +40,7 @@ #include #include -namespace beast { -namespace insight { +namespace beast::insight { /** * @brief A Collector that exports metrics via OpenTelemetry OTLP/HTTP. @@ -88,5 +87,4 @@ public: Journal journal); }; -} // namespace insight -} // namespace beast +} // namespace beast::insight diff --git a/src/libxrpl/beast/insight/OTelCollector.cpp b/src/libxrpl/beast/insight/OTelCollector.cpp index 03451cb6e1..0638ce7fb9 100644 --- a/src/libxrpl/beast/insight/OTelCollector.cpp +++ b/src/libxrpl/beast/insight/OTelCollector.cpp @@ -64,8 +64,7 @@ #include #include -namespace beast { -namespace insight { +namespace beast::insight { namespace detail { @@ -851,19 +850,19 @@ OTelCollector::New( return std::make_shared(endpoint, prefix, instanceId, journal); } -} // namespace insight -} // namespace beast +} // namespace beast::insight #else // !XRPL_ENABLE_TELEMETRY // When telemetry is disabled at compile time, OTelCollector::New() // returns a NullCollector so callers do not need conditional logic. +#include #include #include +#include -namespace beast { -namespace insight { +namespace beast::insight { std::shared_ptr OTelCollector::New( @@ -875,7 +874,6 @@ OTelCollector::New( return NullCollector::New(); } -} // namespace insight -} // namespace beast +} // namespace beast::insight #endif // XRPL_ENABLE_TELEMETRY diff --git a/src/tests/libxrpl/CMakeLists.txt b/src/tests/libxrpl/CMakeLists.txt index b74ef02771..eca46c436d 100644 --- a/src/tests/libxrpl/CMakeLists.txt +++ b/src/tests/libxrpl/CMakeLists.txt @@ -46,6 +46,12 @@ endif() xrpl_add_test(telemetry) target_link_libraries(xrpl.test.telemetry PRIVATE xrpl.imports.test) target_include_directories(xrpl.test.telemetry PRIVATE ${CMAKE_SOURCE_DIR}/src) +# ValidationTracker lives in src/xrpld/ (not libxrpl), so we compile its +# implementation directly into the test binary. +target_sources( + xrpl.test.telemetry + PRIVATE ${CMAKE_SOURCE_DIR}/src/xrpld/telemetry/detail/ValidationTracker.cpp +) if(telemetry) target_link_libraries( xrpl.test.telemetry diff --git a/src/tests/libxrpl/telemetry/ValidationTracker.cpp b/src/tests/libxrpl/telemetry/ValidationTracker.cpp index 91569eaf69..7a5179c871 100644 --- a/src/tests/libxrpl/telemetry/ValidationTracker.cpp +++ b/src/tests/libxrpl/telemetry/ValidationTracker.cpp @@ -4,9 +4,14 @@ #include +#include +#include + #include #include +#include +#include #include using namespace xrpl; diff --git a/src/xrpld/app/main/CollectorManager.cpp b/src/xrpld/app/main/CollectorManager.cpp index 8634f42a14..e72ba4b762 100644 --- a/src/xrpld/app/main/CollectorManager.cpp +++ b/src/xrpld/app/main/CollectorManager.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include diff --git a/src/xrpld/telemetry/ValidationTracker.h b/src/xrpld/telemetry/ValidationTracker.h index e1c3bf71e0..ff9fde5d11 100644 --- a/src/xrpld/telemetry/ValidationTracker.h +++ b/src/xrpld/telemetry/ValidationTracker.h @@ -14,8 +14,7 @@ #include #include -namespace xrpl { -namespace telemetry { +namespace xrpl::telemetry { /** * Tracks whether this validator's validations agree with network consensus, @@ -204,7 +203,7 @@ private: struct LedgerEvent { uint256 ledgerHash; ///< Ledger hash being tracked. - LedgerIndex seq; ///< Ledger sequence number. + LedgerIndex seq{0}; ///< Ledger sequence number. TimePoint recordTime; ///< Time the event was first recorded. bool weValidated = false; ///< True if we sent a validation. bool networkValidated = false; ///< True if network reached consensus. @@ -292,5 +291,4 @@ private: repairWindowEntry(std::deque& window, uint256 const& hash); }; -} // namespace telemetry -} // namespace xrpl +} // namespace xrpl::telemetry diff --git a/src/xrpld/telemetry/detail/ValidationTracker.cpp b/src/xrpld/telemetry/detail/ValidationTracker.cpp index 8167b2c51b..c0a7fc0b1e 100644 --- a/src/xrpld/telemetry/detail/ValidationTracker.cpp +++ b/src/xrpld/telemetry/detail/ValidationTracker.cpp @@ -4,15 +4,21 @@ #include -#include +#include +#include -namespace xrpl { -namespace telemetry { +#include +#include +#include +#include +#include + +namespace xrpl::telemetry { void ValidationTracker::recordOurValidation(uint256 const& ledgerHash, LedgerIndex seq) { - std::lock_guard lock(mutex_); + std::lock_guard const lock(mutex_); auto& evt = pending_[ledgerHash]; if (evt.recordTime == TimePoint{}) { @@ -28,7 +34,7 @@ ValidationTracker::recordOurValidation(uint256 const& ledgerHash, LedgerIndex se void ValidationTracker::recordNetworkValidation(uint256 const& ledgerHash, LedgerIndex seq) { - std::lock_guard lock(mutex_); + std::lock_guard const lock(mutex_); auto& evt = pending_[ledgerHash]; if (evt.recordTime == TimePoint{}) { @@ -43,7 +49,7 @@ ValidationTracker::recordNetworkValidation(uint256 const& ledgerHash, LedgerInde void ValidationTracker::reconcile() { - std::lock_guard lock(mutex_); + std::lock_guard const lock(mutex_); auto const now = Clock::now(); for (auto& [hash, evt] : pending_) @@ -55,11 +61,15 @@ ValidationTracker::reconcile() evt.agreed = evt.weValidated && evt.networkValidated; if (evt.agreed) + { totalAgreements_.fetch_add(1, std::memory_order_relaxed); + } else + { totalMissed_.fetch_add(1, std::memory_order_relaxed); + } - WindowEvent we{now, evt.ledgerHash, evt.agreed}; + WindowEvent const we{.time = now, .ledgerHash = evt.ledgerHash, .agreed = evt.agreed}; window1h_.push_back(we); window24h_.push_back(we); window7d_.push_back(we); @@ -107,9 +117,13 @@ ValidationTracker::evictOldPending(TimePoint now) for (auto it = pending_.begin(); it != pending_.end();) { if (it->second.reconciled && it->second.recordTime < cutoff) + { it = pending_.erase(it); + } else + { ++it; + } } // Hard trim if still over limit -- remove reconciled entries that are @@ -122,18 +136,26 @@ ValidationTracker::evictOldPending(TimePoint now) it != pending_.end() && pending_.size() > kMaxPendingEvents;) { if (it->second.reconciled && it->second.recordTime < cutoff) + { it = pending_.erase(it); + } else + { ++it; + } } // Pass 2: any reconciled entry if still over limit. for (auto it = pending_.begin(); it != pending_.end() && pending_.size() > kMaxPendingEvents;) { if (it->second.reconciled) + { it = pending_.erase(it); + } else + { ++it; + } } } } @@ -141,7 +163,7 @@ ValidationTracker::evictOldPending(TimePoint now) double ValidationTracker::agreementPct1h() const { - std::lock_guard lock(mutex_); + std::lock_guard const lock(mutex_); if (window1h_.empty()) return 0.0; auto const agreed = static_cast( @@ -152,7 +174,7 @@ ValidationTracker::agreementPct1h() const double ValidationTracker::agreementPct24h() const { - std::lock_guard lock(mutex_); + std::lock_guard const lock(mutex_); if (window24h_.empty()) return 0.0; auto const agreed = static_cast(std::count_if( @@ -163,7 +185,7 @@ ValidationTracker::agreementPct24h() const uint64_t ValidationTracker::agreements1h() const { - std::lock_guard lock(mutex_); + std::lock_guard const lock(mutex_); return static_cast( std::count_if(window1h_.begin(), window1h_.end(), [](auto const& e) { return e.agreed; })); } @@ -171,7 +193,7 @@ ValidationTracker::agreements1h() const uint64_t ValidationTracker::missed1h() const { - std::lock_guard lock(mutex_); + std::lock_guard const lock(mutex_); return static_cast( std::count_if(window1h_.begin(), window1h_.end(), [](auto const& e) { return !e.agreed; })); } @@ -179,7 +201,7 @@ ValidationTracker::missed1h() const uint64_t ValidationTracker::agreements24h() const { - std::lock_guard lock(mutex_); + std::lock_guard const lock(mutex_); return static_cast(std::count_if( window24h_.begin(), window24h_.end(), [](auto const& e) { return e.agreed; })); } @@ -187,7 +209,7 @@ ValidationTracker::agreements24h() const uint64_t ValidationTracker::missed24h() const { - std::lock_guard lock(mutex_); + std::lock_guard const lock(mutex_); return static_cast(std::count_if( window24h_.begin(), window24h_.end(), [](auto const& e) { return !e.agreed; })); } @@ -195,7 +217,7 @@ ValidationTracker::missed24h() const double ValidationTracker::agreementPct7d() const { - std::lock_guard lock(mutex_); + std::lock_guard const lock(mutex_); if (window7d_.empty()) return 0.0; auto const agreed = static_cast( @@ -206,7 +228,7 @@ ValidationTracker::agreementPct7d() const uint64_t ValidationTracker::agreements7d() const { - std::lock_guard lock(mutex_); + std::lock_guard const lock(mutex_); return static_cast( std::count_if(window7d_.begin(), window7d_.end(), [](auto const& e) { return e.agreed; })); } @@ -214,7 +236,7 @@ ValidationTracker::agreements7d() const uint64_t ValidationTracker::missed7d() const { - std::lock_guard lock(mutex_); + std::lock_guard const lock(mutex_); return static_cast( std::count_if(window7d_.begin(), window7d_.end(), [](auto const& e) { return !e.agreed; })); } @@ -257,5 +279,4 @@ ValidationTracker::repairWindowEntry(std::deque& window, uint256 co } } -} // namespace telemetry -} // namespace xrpl +} // namespace xrpl::telemetry