Skip to content

Commit

Permalink
Merge #6465: fix: avoid potential divide-by-zero in network hashrate …
Browse files Browse the repository at this point in the history
…stats calculation

40070c0 stats: don't report `network.*hashesPerSecond` if it's zero (Kittywhiskers Van Gogh)
b39c6b9 fix: avoid potential divide-by-zero in H/s stats calculation (Kittywhiskers Van Gogh)

Pull request description:

  ## Additional Information

  It was reported that on occasion, `network.*hashesPerSecond` would report NaN gauge values, which would be dismissed as malformed reporting by Grafana (see below). Those gauges use a simplified version ([source](https://github.com/dashpay/dash/blob/1ecfb891bcdcfd62db7827c55370be9bc3587f2e/src/init.cpp#L851-L864)) of `GetNetworkHashPS` ([source](https://github.com/dashpay/dash/blob/1ecfb891bcdcfd62db7827c55370be9bc3587f2e/src/rpc/mining.cpp#L61)), crucially, without a check meant to avoid divide-by-zeros ([source](https://github.com/dashpay/dash/blob/1ecfb891bcdcfd62db7827c55370be9bc3587f2e/src/rpc/mining.cpp#L89-L91)).

  <details>

  <summary>Error log (courtesy of PastaPastaPasta):</summary>

  ```
  [...]
  graphite-1             | 7 Dec 21:18:05 - DEBUG: Bad line: -nan,g in msg "network.terahashesPerSecond:-nan|g"
  graphite-1             | 7 Dec 21:18:05 - DEBUG: Bad line: -nan,g in msg "network.petahashesPerSecond:-nan|g"
  graphite-1             | 7 Dec 21:18:05 - DEBUG: Bad line: -nan,g in msg "network.exahashesPerSecond:-nan|g"
  graphite-1             | 7 Dec 21:18:10 - DEBUG: Bad line: -nan,g in msg "network.hashesPerSecond:-nan|g"
  graphite-1             | 7 Dec 21:18:10 - DEBUG: Bad line: -nan,g in msg "network.terahashesPerSecond:-nan|g"
  graphite-1             | 7 Dec 21:18:10 - DEBUG: Bad line: -nan,g in msg "network.petahashesPerSecond:-nan|g"
  graphite-1             | 7 Dec 21:18:10 - DEBUG: Bad line: -nan,g in msg "network.exahashesPerSecond:-nan|g"
  graphite-1             | 7 Dec 21:18:15 - DEBUG: Bad line: -nan,g in msg "network.hashesPerSecond:-nan|g"
  [...]
  ```

  </details>

  This has been resolved by adding that check, alongside encapsulating the logic in a lambda and not reporting the gauge values if the estimated hashes per second reported is zero, due to the unlikelihood of it being correct.

  ## Breaking Changes

  None expected.

  ## Checklist

  - [x] I have performed a self-review of my own code
  - [x] I have commented my code, particularly in hard-to-understand areas **(note: N/A)**
  - [x] I have added or updated relevant unit/integration/functional/e2e tests **(note: N/A)**
  - [x] I have made corresponding changes to the documentation **(note: N/A)**
  - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_

ACKs for top commit:
  UdjinM6:
    utACK 40070c0
  knst:
    utACK 40070c0

Tree-SHA512: 64bcca0f51a8bebb090613d3495ddba481ea6464f9f4a6791d830593fd1401c890eba65869f8719c6c6033a3346af11f16855a95fec5f42722b26a12b9f8b3c9
  • Loading branch information
PastaPastaPasta committed Dec 9, 2024
2 parents 7c00c86 + 40070c0 commit c588944
Showing 1 changed file with 23 additions and 18 deletions.
41 changes: 23 additions & 18 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -848,25 +848,30 @@ 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;

::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);
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;
}();

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));

Expand Down

0 comments on commit c588944

Please sign in to comment.