From b39c6b99091e43988e3c9034cf1e3a7be5a6fb45 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Sun, 8 Dec 2024 10:14:46 +0000 Subject: [PATCH 1/2] fix: avoid potential divide-by-zero in H/s stats calculation --- src/init.cpp | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 1abb710513..1b599eaefd 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -848,20 +848,23 @@ static void PeriodicStats(NodeContext& node) LogPrintf("%s: GetUTXOStats failed\n", __func__); } - // short version of GetNetworkHashPS(120, -1); CBlockIndex *tip = chainman.ActiveChain().Tip(); - CBlockIndex *pindex = tip; - int64_t minTime = pindex->GetBlockTime(); - int64_t maxTime = minTime; - for (int i = 0; i < 120 && pindex->pprev != nullptr; i++) { - pindex = pindex->pprev; - int64_t time = pindex->GetBlockTime(); - minTime = std::min(time, minTime); - maxTime = std::max(time, maxTime); - } - arith_uint256 workDiff = tip->nChainWork - pindex->nChainWork; - int64_t timeDiff = maxTime - minTime; - double nNetworkHashPS = workDiff.getdouble() / timeDiff; + double nNetworkHashPS = [&]() { + // Short version of GetNetworkHashPS(120, -1); + CBlockIndex *pindex = tip; + int64_t minTime = pindex->GetBlockTime(); + int64_t maxTime = minTime; + for (int i = 0; i < 120 && pindex->pprev != nullptr; i++) { + pindex = pindex->pprev; + int64_t time = pindex->GetBlockTime(); + minTime = std::min(time, minTime); + maxTime = std::max(time, maxTime); + } + if (minTime == maxTime) return 0.0; + arith_uint256 workDiff = tip->nChainWork - pindex->nChainWork; + int64_t timeDiff = maxTime - minTime; + return workDiff.getdouble() / timeDiff; + }(); ::g_stats_client->gaugeDouble("network.hashesPerSecond", nNetworkHashPS); ::g_stats_client->gaugeDouble("network.terahashesPerSecond", nNetworkHashPS / 1e12); From 40070c0337fb07af9e2a0ce62adf782067aa8472 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Sun, 8 Dec 2024 10:18:13 +0000 Subject: [PATCH 2/2] stats: don't report `network.*hashesPerSecond` if it's zero It's more likely that the stat is broken than the network running with such low difficulty, the hash rate is reported as zero. `*hashesPerSecond` are a gauge and we should let the last known good value linger instead of potentially overwriting it with an improbable value. --- src/init.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 1b599eaefd..092bc971e2 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -866,10 +866,12 @@ static void PeriodicStats(NodeContext& node) return workDiff.getdouble() / timeDiff; }(); - ::g_stats_client->gaugeDouble("network.hashesPerSecond", nNetworkHashPS); - ::g_stats_client->gaugeDouble("network.terahashesPerSecond", nNetworkHashPS / 1e12); - ::g_stats_client->gaugeDouble("network.petahashesPerSecond", nNetworkHashPS / 1e15); - ::g_stats_client->gaugeDouble("network.exahashesPerSecond", nNetworkHashPS / 1e18); + if (nNetworkHashPS > 0.0) { + ::g_stats_client->gaugeDouble("network.hashesPerSecond", nNetworkHashPS); + ::g_stats_client->gaugeDouble("network.terahashesPerSecond", nNetworkHashPS / 1e12); + ::g_stats_client->gaugeDouble("network.petahashesPerSecond", nNetworkHashPS / 1e15); + ::g_stats_client->gaugeDouble("network.exahashesPerSecond", nNetworkHashPS / 1e18); + } // No need for cs_main, we never use null tip here ::g_stats_client->gaugeDouble("network.difficulty", (double)GetDifficulty(tip));