Merge bitcoin/bitcoin#34436: refactor: add overflow-safe CeilDiv helper and use it in unsigned callsites

02d047fd5b refactor: add overflow-safe `CeilDiv` helper (Lőrinc)

Pull request description:

  ### Problem
  The codebase has many open-coded ceiling-division expressions (for example `(x+y-1)/y`) scattered across files.
  These are less readable, duplicate logic, and can be overflow-prone in edge cases.

  ### Fix
  Introduce a small overflow-safe integer helper, `CeilDiv()`, and use it in existing **unsigned** callsites where the conversion is straightforward and noise-free.

  ### What this PR does
  * Adds `CeilDiv()` to `src/util/overflow.h` for unsigned integral inputs.
  * Keeps the precondition check `assert(divisor > 0)`.
  * Replaces selected unsigned ceiling-division expressions with `CeilDiv(...)`.
  * Adds focused unit tests in `src/test/util_tests.cpp` for the migrated patterns.

  ---

  This is a pure refactor with no intended behavioral change.
  Signed arithmetic callsites are intentionally left unchanged in this PR.
  This PR changed a few more things originally but based on feedback reverted to the simplest cases only.

ACKs for top commit:
  rustaceanrob:
    ACK 02d047fd5b
  hodlinator:
    ACK 02d047fd5b
  sedited:
    ACK 02d047fd5b

Tree-SHA512: b09336031f487e6ce289822e0ffeb8cfc8cfe8a2f4f3f49470748dfbd0a6cbab97498674cb8686dd2bd4ab6dd0b79cfdf2da00041fee12d109892e1bc5dde0ff
This commit is contained in:
merge-script
2026-03-11 11:30:42 +01:00
15 changed files with 85 additions and 19 deletions

View File

@@ -12,6 +12,7 @@
#include <span.h>
#include <streams.h>
#include <util/fastrange.h>
#include <util/overflow.h>
#include <algorithm>
#include <cmath>
@@ -166,7 +167,7 @@ CRollingBloomFilter::CRollingBloomFilter(const unsigned int nElements, const dou
* restrict it to the range 1-50. */
nHashFuncs = std::max(1, std::min((int)round(logFpRate / log(0.5)), 50));
/* In this rolling bloom filter, we'll store between 2 and 3 generations of nElements / 2 entries. */
nEntriesPerGeneration = (nElements + 1) / 2;
nEntriesPerGeneration = CeilDiv(nElements, 2u);
uint32_t nMaxElements = nEntriesPerGeneration * 3;
/* The maximum fpRate = pow(1.0 - exp(-nHashFuncs * nMaxElements / nFilterBits), nHashFuncs)
* => pow(fpRate, 1.0 / nHashFuncs) = 1.0 - exp(-nHashFuncs * nMaxElements / nFilterBits)
@@ -182,7 +183,7 @@ CRollingBloomFilter::CRollingBloomFilter(const unsigned int nElements, const dou
* treated as set in generation 1, 2, or 3 respectively.
* These bits are stored in separate integers: position P corresponds to bit
* (P & 63) of the integers data[(P >> 6) * 2] and data[(P >> 6) * 2 + 1]. */
data.resize(((nFilterBits + 63) / 64) << 1);
data.resize(CeilDiv(nFilterBits, 64u) << 1);
reset();
}