2023-01-22 09:57:19 -08:00
|
|
|
// Copyright (c) 2023 The Bitcoin Core developers
|
|
|
|
|
// Distributed under the MIT software license, see the accompanying
|
|
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
|
|
|
|
|
|
#include <test/util/random.h>
|
|
|
|
|
|
|
|
|
|
#include <logging.h>
|
|
|
|
|
#include <random.h>
|
|
|
|
|
#include <uint256.h>
|
|
|
|
|
|
|
|
|
|
#include <cstdlib>
|
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
|
|
FastRandomContext g_insecure_rand_ctx;
|
|
|
|
|
|
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.
2024-03-10 19:49:42 -04:00
|
|
|
extern void MakeRandDeterministicDANGEROUS(const uint256& seed) noexcept;
|
2023-01-22 09:57:19 -08:00
|
|
|
|
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.
2024-03-10 19:49:42 -04:00
|
|
|
void SeedRandomForTest(SeedRand seedtype)
|
2023-01-22 09:57:19 -08:00
|
|
|
{
|
|
|
|
|
static const std::string RANDOM_CTX_SEED{"RANDOM_CTX_SEED"};
|
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.
2024-03-10 19:49:42 -04:00
|
|
|
|
|
|
|
|
// Do this once, on the first call, regardless of seedtype, because once
|
|
|
|
|
// MakeRandDeterministicDANGEROUS is called, the output of GetRandHash is
|
|
|
|
|
// no longer truly random. It should be enough to get the seed once for the
|
|
|
|
|
// process.
|
|
|
|
|
static const uint256 ctx_seed = []() {
|
|
|
|
|
// If RANDOM_CTX_SEED is set, use that as seed.
|
|
|
|
|
const char* num = std::getenv(RANDOM_CTX_SEED.c_str());
|
|
|
|
|
if (num) return uint256S(num);
|
|
|
|
|
// Otherwise use a (truly) random value.
|
|
|
|
|
return GetRandHash();
|
|
|
|
|
}();
|
|
|
|
|
|
|
|
|
|
const uint256& seed{seedtype == SeedRand::SEED ? ctx_seed : uint256::ZERO};
|
2023-01-22 09:57:19 -08:00
|
|
|
LogPrintf("%s: Setting random seed for current tests to %s=%s\n", __func__, RANDOM_CTX_SEED, seed.GetHex());
|
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.
2024-03-10 19:49:42 -04:00
|
|
|
MakeRandDeterministicDANGEROUS(seed);
|
|
|
|
|
g_insecure_rand_ctx = FastRandomContext(GetRandHash());
|
2023-01-22 09:57:19 -08:00
|
|
|
}
|