tests: overhaul deterministic test randomness

The existing code provides two randomness mechanisms for test purposes:
- g_insecure_rand_ctx (with its wrappers InsecureRand*), which during tests is
  initialized using either zeros (SeedRand::ZEROS), or using environment-provided
  randomness (SeedRand::SEED).
- g_mock_deterministic_tests, which controls some (but not all) of the normal
  randomness output if set, but then makes it extremely predictable (identical
  output repeatedly).

Replace this with a single mechanism, which retains the SeedRand modes to control
all randomness. There is a new internal deterministic PRNG inside the random
module, which is used in GetRandBytes() when in test mode, and which is also used
to initialize g_insecure_rand_ctx. This means that during tests, all random numbers
are made deterministic. There is one exception, GetStrongRandBytes(), which even
in test mode still uses the normal PRNG state.

This probably opens the door to removing a lot of the ad-hoc "deterministic" mode
functions littered through the codebase (by simply running relevant tests in
SeedRand::ZEROS mode), but this isn't done yet.
This commit is contained in:
Pieter Wuille
2024-03-10 19:49:42 -04:00
parent 6cfdc5b104
commit 810cdf6b4e
13 changed files with 133 additions and 76 deletions

View File

@@ -63,6 +63,12 @@
* When mixing in new entropy, H = SHA512(entropy || old_rng_state) is computed, and
* (up to) the first 32 bytes of H are produced as output, while the last 32 bytes
* become the new RNG state.
*
* During tests, the RNG can be put into a special deterministic mode, in which the output
* of all RNG functions, with the exception of GetStrongRandBytes(), is replaced with the
* output of a deterministic RNG. This deterministic RNG does not gather entropy, and is
* unaffected by RandAddPeriodic() or RandAddEvent(). It produces pseudorandom data that
* only depends on the seed it was initialized with, possibly until it is reinitialized.
*/
/**
@@ -340,6 +346,7 @@ private:
void RandomSeed() noexcept;
public:
/** Construct a FastRandomContext with GetRandHash()-based entropy (or zero key if fDeterministic). */
explicit FastRandomContext(bool fDeterministic = false) noexcept;
/** Initialize with explicit seed (only for testing) */