5555 std::abort ();
5656}
5757
58- static inline int64_t GetPerformanceCounter ()
58+ static inline int64_t GetPerformanceCounter () noexcept
5959{
6060 // Read the hardware time stamp counter when available.
6161 // See https://en.wikipedia.org/wiki/Time_Stamp_Counter for more information.
@@ -105,7 +105,7 @@ static void InitHardwareRand() {}
105105static void ReportHardwareRand () {}
106106#endif
107107
108- static bool GetHardwareRand (unsigned char * ent32) {
108+ static bool GetHardwareRand (unsigned char * ent32) noexcept {
109109#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
110110 if (rdrand_supported) {
111111 uint8_t ok;
@@ -285,7 +285,7 @@ struct RNGState {
285285 bool m_strongly_seeded GUARDED_BY (m_mutex) = false;
286286 std::unique_ptr<Mutex[]> m_mutex_openssl;
287287
288- RNGState ()
288+ RNGState () noexcept
289289 {
290290 InitHardwareRand ();
291291
@@ -313,7 +313,7 @@ struct RNGState {
313313 *
314314 * If this function has never been called with strong_seed = true, false is returned.
315315 */
316- bool MixExtract (unsigned char * out, size_t num, CSHA512&& hasher, bool strong_seed)
316+ bool MixExtract (unsigned char * out, size_t num, CSHA512&& hasher, bool strong_seed) noexcept
317317 {
318318 assert (num <= 32 );
319319 unsigned char buf[64 ];
@@ -344,7 +344,7 @@ struct RNGState {
344344 }
345345};
346346
347- RNGState& GetRNGState ()
347+ RNGState& GetRNGState () noexcept
348348{
349349 // This C++11 idiom relies on the guarantee that static variable are initialized
350350 // on first call, even when multiple parallel calls are permitted.
@@ -364,13 +364,28 @@ void LockingCallbackOpenSSL(int mode, int i, const char* file, int line) NO_THRE
364364 }
365365}
366366
367- static void SeedTimestamp (CSHA512& hasher)
367+ /* A note on the use of noexcept in the seeding functions below:
368+ *
369+ * None of the RNG code should ever throw any exception, with the sole exception
370+ * of MilliSleep in SeedSleep, which can (and does) support interruptions which
371+ * cause a boost::thread_interrupted to be thrown.
372+ *
373+ * This means that SeedSleep, and all functions that invoke it are throwing.
374+ * However, we know that GetRandBytes() and GetStrongRandBytes() never trigger
375+ * this sleeping logic, so they are noexcept. The same is true for all the
376+ * GetRand*() functions that use GetRandBytes() indirectly.
377+ *
378+ * TODO: After moving away from interruptible boost-based thread management,
379+ * everything can become noexcept here.
380+ */
381+
382+ static void SeedTimestamp (CSHA512& hasher) noexcept
368383{
369384 int64_t perfcounter = GetPerformanceCounter ();
370385 hasher.Write ((const unsigned char *)&perfcounter, sizeof (perfcounter));
371386}
372387
373- static void SeedFast (CSHA512& hasher)
388+ static void SeedFast (CSHA512& hasher) noexcept
374389{
375390 unsigned char buffer[32 ];
376391
@@ -386,7 +401,7 @@ static void SeedFast(CSHA512& hasher)
386401 SeedTimestamp (hasher);
387402}
388403
389- static void SeedSlow (CSHA512& hasher)
404+ static void SeedSlow (CSHA512& hasher) noexcept
390405{
391406 unsigned char buffer[32 ];
392407
@@ -426,7 +441,7 @@ static void SeedSleep(CSHA512& hasher)
426441 RandAddSeedPerfmon (hasher);
427442}
428443
429- static void SeedStartup (CSHA512& hasher)
444+ static void SeedStartup (CSHA512& hasher) noexcept
430445{
431446#ifdef WIN32
432447 RAND_screen ();
@@ -482,11 +497,11 @@ static void ProcRand(unsigned char* out, int num, RNGLevel level)
482497 }
483498}
484499
485- void GetRandBytes (unsigned char * buf, int num) { ProcRand (buf, num, RNGLevel::FAST); }
486- void GetStrongRandBytes (unsigned char * buf, int num) { ProcRand (buf, num, RNGLevel::SLOW); }
500+ void GetRandBytes (unsigned char * buf, int num) noexcept { ProcRand (buf, num, RNGLevel::FAST); }
501+ void GetStrongRandBytes (unsigned char * buf, int num) noexcept { ProcRand (buf, num, RNGLevel::SLOW); }
487502void RandAddSeedSleep () { ProcRand (nullptr , 0 , RNGLevel::SLEEP); }
488503
489- uint64_t GetRand (uint64_t nMax)
504+ uint64_t GetRand (uint64_t nMax) noexcept
490505{
491506 if (nMax == 0 )
492507 return 0 ;
@@ -501,12 +516,12 @@ uint64_t GetRand(uint64_t nMax)
501516 return (nRand % nMax);
502517}
503518
504- int GetRandInt (int nMax)
519+ int GetRandInt (int nMax) noexcept
505520{
506521 return GetRand (nMax);
507522}
508523
509- uint256 GetRandHash ()
524+ uint256 GetRandHash () noexcept
510525{
511526 uint256 hash;
512527 GetRandBytes ((unsigned char *)&hash, sizeof (hash));
@@ -520,7 +535,7 @@ void FastRandomContext::RandomSeed()
520535 requires_seed = false ;
521536}
522537
523- uint256 FastRandomContext::rand256 ()
538+ uint256 FastRandomContext::rand256 () noexcept
524539{
525540 if (bytebuf_size < 32 ) {
526541 FillByteBuffer ();
@@ -541,7 +556,7 @@ std::vector<unsigned char> FastRandomContext::randbytes(size_t len)
541556 return ret;
542557}
543558
544- FastRandomContext::FastRandomContext (const uint256& seed) : requires_seed(false ), bytebuf_size(0 ), bitbuf_size(0 )
559+ FastRandomContext::FastRandomContext (const uint256& seed) noexcept : requires_seed(false ), bytebuf_size(0 ), bitbuf_size(0 )
545560{
546561 rng.SetKey (seed.begin (), 32 );
547562}
@@ -592,7 +607,7 @@ bool Random_SanityCheck()
592607 return true ;
593608}
594609
595- FastRandomContext::FastRandomContext (bool fDeterministic ) : requires_seed(!fDeterministic ), bytebuf_size(0 ), bitbuf_size(0 )
610+ FastRandomContext::FastRandomContext (bool fDeterministic ) noexcept : requires_seed(!fDeterministic ), bytebuf_size(0 ), bitbuf_size(0 )
596611{
597612 if (!fDeterministic ) {
598613 return ;
0 commit comments