@@ -360,6 +360,9 @@ class RNGState {
360360 uint64_t m_counter GUARDED_BY (m_mutex) = 0;
361361 bool m_strongly_seeded GUARDED_BY (m_mutex) = false;
362362
363+ Mutex m_events_mutex;
364+ CSHA256 m_events_hasher GUARDED_BY (m_events_mutex);
365+
363366public:
364367 RNGState () noexcept
365368 {
@@ -370,6 +373,35 @@ class RNGState {
370373 {
371374 }
372375
376+ void AddEvent (uint32_t event_info) noexcept
377+ {
378+ LOCK (m_events_mutex);
379+
380+ m_events_hasher.Write ((const unsigned char *)&event_info, sizeof (event_info));
381+ // Get the low four bytes of the performance counter. This translates to roughly the
382+ // subsecond part.
383+ uint32_t perfcounter = (GetPerformanceCounter () & 0xffffffff );
384+ m_events_hasher.Write ((const unsigned char *)&perfcounter, sizeof (perfcounter));
385+ }
386+
387+ /* *
388+ * Feed (the hash of) all events added through AddEvent() to hasher.
389+ */
390+ void SeedEvents (CSHA512& hasher) noexcept
391+ {
392+ // We use only SHA256 for the events hashing to get the ASM speedups we have for SHA256,
393+ // since we want it to be fast as network peers may be able to trigger it repeatedly.
394+ LOCK (m_events_mutex);
395+
396+ unsigned char events_hash[32 ];
397+ m_events_hasher.Finalize (events_hash);
398+ hasher.Write (events_hash, 32 );
399+
400+ // Re-initialize the hasher with the finalized state to use later.
401+ m_events_hasher.Reset ();
402+ m_events_hasher.Write (events_hash, 32 );
403+ }
404+
373405 /* * Extract up to 32 bytes of entropy from the RNG state, mixing in new entropy from hasher.
374406 *
375407 * If this function has never been called with strong_seed = true, false is returned.
@@ -440,24 +472,7 @@ static void SeedFast(CSHA512& hasher) noexcept
440472 SeedTimestamp (hasher);
441473}
442474
443- // We use only SHA256 for the events hashing to get the ASM speedups we have for SHA256,
444- // since we want it to be fast as network peers may be able to trigger it repeatedly.
445- static Mutex events_mutex;
446- static CSHA256 events_hasher;
447- static void SeedEvents (CSHA512& hasher)
448- {
449- LOCK (events_mutex);
450-
451- unsigned char events_hash[32 ];
452- events_hasher.Finalize (events_hash);
453- hasher.Write (events_hash, 32 );
454-
455- // Re-initialize the hasher with the finalized state to use later.
456- events_hasher.Reset ();
457- events_hasher.Write (events_hash, 32 );
458- }
459-
460- static void SeedSlow (CSHA512& hasher) noexcept
475+ static void SeedSlow (CSHA512& hasher, RNGState& rng) noexcept
461476{
462477 unsigned char buffer[32 ];
463478
@@ -469,7 +484,7 @@ static void SeedSlow(CSHA512& hasher) noexcept
469484 hasher.Write (buffer, sizeof (buffer));
470485
471486 // Add the events hasher into the mix
472- SeedEvents (hasher);
487+ rng. SeedEvents (hasher);
473488
474489 // High-precision timestamp.
475490 //
@@ -497,7 +512,7 @@ static void SeedPeriodic(CSHA512& hasher, RNGState& rng) noexcept
497512 SeedTimestamp (hasher);
498513
499514 // Add the events hasher into the mix
500- SeedEvents (hasher);
515+ rng. SeedEvents (hasher);
501516
502517 // Dynamic environment data (performance monitoring, ...)
503518 auto old_size = hasher.Size ();
@@ -514,7 +529,7 @@ static void SeedStartup(CSHA512& hasher, RNGState& rng) noexcept
514529 SeedHardwareSlow (hasher);
515530
516531 // Everything that the 'slow' seeder includes.
517- SeedSlow (hasher);
532+ SeedSlow (hasher, rng );
518533
519534 // Dynamic environment data (performance monitoring, ...)
520535 auto old_size = hasher.Size ();
@@ -534,7 +549,7 @@ enum class RNGLevel {
534549 PERIODIC, // !< Called by RandAddPeriodic()
535550};
536551
537- static void ProcRand (unsigned char * out, int num, RNGLevel level)
552+ static void ProcRand (unsigned char * out, int num, RNGLevel level) noexcept
538553{
539554 // Make sure the RNG is initialized first (as all Seed* function possibly need hwrand to be available).
540555 RNGState& rng = GetRNGState ();
@@ -547,7 +562,7 @@ static void ProcRand(unsigned char* out, int num, RNGLevel level)
547562 SeedFast (hasher);
548563 break ;
549564 case RNGLevel::SLOW:
550- SeedSlow (hasher);
565+ SeedSlow (hasher, rng );
551566 break ;
552567 case RNGLevel::PERIODIC:
553568 SeedPeriodic (hasher, rng);
@@ -566,15 +581,7 @@ static void ProcRand(unsigned char* out, int num, RNGLevel level)
566581void GetRandBytes (unsigned char * buf, int num) noexcept { ProcRand (buf, num, RNGLevel::FAST); }
567582void GetStrongRandBytes (unsigned char * buf, int num) noexcept { ProcRand (buf, num, RNGLevel::SLOW); }
568583void RandAddPeriodic () noexcept { ProcRand (nullptr , 0 , RNGLevel::PERIODIC); }
569-
570- void RandAddEvent (const uint32_t event_info) {
571- LOCK (events_mutex);
572- events_hasher.Write ((const unsigned char *)&event_info, sizeof (event_info));
573- // Get the low four bytes of the performance counter. This translates to roughly the
574- // subsecond part.
575- uint32_t perfcounter = (GetPerformanceCounter () & 0xffffffff );
576- events_hasher.Write ((const unsigned char *)&perfcounter, sizeof (perfcounter));
577- }
584+ void RandAddEvent (const uint32_t event_info) noexcept { GetRNGState ().AddEvent (event_info); }
578585
579586bool g_mock_deterministic_tests{false };
580587
0 commit comments