aboutsummaryrefslogtreecommitdiff
path: root/src/random.cpp
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2019-10-29 11:55:59 -0700
committerPieter Wuille <pieter.wuille@gmail.com>2019-11-12 15:35:26 -0800
commitd61f2bb076d8f17840a8e79f1583d7f6e3e6d09a (patch)
treee36bc22346ff81282bc46dffea7ba9313fc49e0f /src/random.cpp
parent483b94292e89587e5ab40a30b8a90e2f56e847f3 (diff)
Run background seeding periodically instead of unpredictably
* Instead of calling RandAddSeedSleep anytime the scheduler goes idle, call its replacement (RandAddSeedPeriodic) just once per minute. This has better guarantees of actually being run, and helps limit how frequently the dynamic env data is gathered. * Since this code runs once per minute regardless now, we no longer need to keep track of the last time strengthening was run; just do it always. * Make strengthening time context dependent (100 ms at startup, 10 ms once per minute afterwards).
Diffstat (limited to 'src/random.cpp')
-rw-r--r--src/random.cpp46
1 files changed, 17 insertions, 29 deletions
diff --git a/src/random.cpp b/src/random.cpp
index 6f162a7cf0..2847aacf6f 100644
--- a/src/random.cpp
+++ b/src/random.cpp
@@ -507,22 +507,16 @@ static void SeedSlow(CSHA512& hasher) noexcept
}
/** Extract entropy from rng, strengthen it, and feed it into hasher. */
-static void SeedStrengthen(CSHA512& hasher, RNGState& rng) noexcept
+static void SeedStrengthen(CSHA512& hasher, RNGState& rng, int microseconds) noexcept
{
- static std::atomic<int64_t> last_strengthen{0};
- int64_t last_time = last_strengthen.load();
- int64_t current_time = GetTimeMicros();
- if (current_time > last_time + 60000000) { // Only run once a minute
- // Generate 32 bytes of entropy from the RNG, and a copy of the entropy already in hasher.
- unsigned char strengthen_seed[32];
- rng.MixExtract(strengthen_seed, sizeof(strengthen_seed), CSHA512(hasher), false);
- // Strengthen it for 10ms (100ms on first run), and feed it into hasher.
- Strengthen(strengthen_seed, last_time == 0 ? 100000 : 10000, hasher);
- last_strengthen = current_time;
- }
+ // Generate 32 bytes of entropy from the RNG, and a copy of the entropy already in hasher.
+ unsigned char strengthen_seed[32];
+ rng.MixExtract(strengthen_seed, sizeof(strengthen_seed), CSHA512(hasher), false);
+ // Strengthen the seed, and feed it into hasher.
+ Strengthen(strengthen_seed, microseconds, hasher);
}
-static void SeedSleep(CSHA512& hasher, RNGState& rng)
+static void SeedPeriodic(CSHA512& hasher, RNGState& rng)
{
// Everything that the 'fast' seeder includes
SeedFast(hasher);
@@ -530,17 +524,11 @@ static void SeedSleep(CSHA512& hasher, RNGState& rng)
// High-precision timestamp
SeedTimestamp(hasher);
- // Sleep for 1ms
- MilliSleep(1);
-
- // High-precision timestamp after sleeping (as we commit to both the time before and after, this measures the delay)
- SeedTimestamp(hasher);
-
- // Dynamic environment data (performance monitoring, ...; once every 10 minutes)
+ // Dynamic environment data (performance monitoring, ...)
RandAddDynamicEnv(hasher);
- // Strengthen every minute
- SeedStrengthen(hasher, rng);
+ // Strengthen for 10 ms
+ SeedStrengthen(hasher, rng, 10000);
}
static void SeedStartup(CSHA512& hasher, RNGState& rng) noexcept
@@ -551,20 +539,20 @@ static void SeedStartup(CSHA512& hasher, RNGState& rng) noexcept
// Everything that the 'slow' seeder includes.
SeedSlow(hasher);
- // Dynamic environment data
+ // Dynamic environment data (performance monitoring, ...)
RandAddDynamicEnv(hasher);
// Static environment data
RandAddStaticEnv(hasher);
- // Strengthen
- SeedStrengthen(hasher, rng);
+ // Strengthen for 100 ms
+ SeedStrengthen(hasher, rng, 100000);
}
enum class RNGLevel {
FAST, //!< Automatically called by GetRandBytes
SLOW, //!< Automatically called by GetStrongRandBytes
- SLEEP, //!< Called by RandAddSeedSleep()
+ PERIODIC, //!< Called by RandAddPeriodic()
};
static void ProcRand(unsigned char* out, int num, RNGLevel level)
@@ -582,8 +570,8 @@ static void ProcRand(unsigned char* out, int num, RNGLevel level)
case RNGLevel::SLOW:
SeedSlow(hasher);
break;
- case RNGLevel::SLEEP:
- SeedSleep(hasher, rng);
+ case RNGLevel::PERIODIC:
+ SeedPeriodic(hasher, rng);
break;
}
@@ -606,7 +594,7 @@ static void ProcRand(unsigned char* out, int num, RNGLevel level)
void GetRandBytes(unsigned char* buf, int num) noexcept { ProcRand(buf, num, RNGLevel::FAST); }
void GetStrongRandBytes(unsigned char* buf, int num) noexcept { ProcRand(buf, num, RNGLevel::SLOW); }
-void RandAddSeedSleep() { ProcRand(nullptr, 0, RNGLevel::SLEEP); }
+void RandAddPeriodic() { ProcRand(nullptr, 0, RNGLevel::PERIODIC); }
bool g_mock_deterministic_tests{false};