55
55
std::abort ();
56
56
}
57
57
58
- static inline int64_t GetPerformanceCounter ()
58
+ static inline int64_t GetPerformanceCounter () noexcept
59
59
{
60
60
// Read the hardware time stamp counter when available.
61
61
// See https://en.wikipedia.org/wiki/Time_Stamp_Counter for more information.
@@ -105,7 +105,7 @@ static void InitHardwareRand() {}
105
105
static void ReportHardwareRand () {}
106
106
#endif
107
107
108
- static bool GetHardwareRand (unsigned char * ent32) {
108
+ static bool GetHardwareRand (unsigned char * ent32) noexcept {
109
109
#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
110
110
if (rdrand_supported) {
111
111
uint8_t ok;
@@ -285,7 +285,7 @@ struct RNGState {
285
285
bool m_strongly_seeded GUARDED_BY (m_mutex) = false;
286
286
std::unique_ptr<Mutex[]> m_mutex_openssl;
287
287
288
- RNGState ()
288
+ RNGState () noexcept
289
289
{
290
290
InitHardwareRand ();
291
291
@@ -313,7 +313,7 @@ struct RNGState {
313
313
*
314
314
* If this function has never been called with strong_seed = true, false is returned.
315
315
*/
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
317
317
{
318
318
assert (num <= 32 );
319
319
unsigned char buf[64 ];
@@ -344,7 +344,7 @@ struct RNGState {
344
344
}
345
345
};
346
346
347
- RNGState& GetRNGState ()
347
+ RNGState& GetRNGState () noexcept
348
348
{
349
349
// This C++11 idiom relies on the guarantee that static variable are initialized
350
350
// 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
364
364
}
365
365
}
366
366
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
368
383
{
369
384
int64_t perfcounter = GetPerformanceCounter ();
370
385
hasher.Write ((const unsigned char *)&perfcounter, sizeof (perfcounter));
371
386
}
372
387
373
- static void SeedFast (CSHA512& hasher)
388
+ static void SeedFast (CSHA512& hasher) noexcept
374
389
{
375
390
unsigned char buffer[32 ];
376
391
@@ -386,7 +401,7 @@ static void SeedFast(CSHA512& hasher)
386
401
SeedTimestamp (hasher);
387
402
}
388
403
389
- static void SeedSlow (CSHA512& hasher)
404
+ static void SeedSlow (CSHA512& hasher) noexcept
390
405
{
391
406
unsigned char buffer[32 ];
392
407
@@ -426,7 +441,7 @@ static void SeedSleep(CSHA512& hasher)
426
441
RandAddSeedPerfmon (hasher);
427
442
}
428
443
429
- static void SeedStartup (CSHA512& hasher)
444
+ static void SeedStartup (CSHA512& hasher) noexcept
430
445
{
431
446
#ifdef WIN32
432
447
RAND_screen ();
@@ -482,11 +497,11 @@ static void ProcRand(unsigned char* out, int num, RNGLevel level)
482
497
}
483
498
}
484
499
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); }
487
502
void RandAddSeedSleep () { ProcRand (nullptr , 0 , RNGLevel::SLEEP); }
488
503
489
- uint64_t GetRand (uint64_t nMax)
504
+ uint64_t GetRand (uint64_t nMax) noexcept
490
505
{
491
506
if (nMax == 0 )
492
507
return 0 ;
@@ -501,12 +516,12 @@ uint64_t GetRand(uint64_t nMax)
501
516
return (nRand % nMax);
502
517
}
503
518
504
- int GetRandInt (int nMax)
519
+ int GetRandInt (int nMax) noexcept
505
520
{
506
521
return GetRand (nMax);
507
522
}
508
523
509
- uint256 GetRandHash ()
524
+ uint256 GetRandHash () noexcept
510
525
{
511
526
uint256 hash;
512
527
GetRandBytes ((unsigned char *)&hash, sizeof (hash));
@@ -520,7 +535,7 @@ void FastRandomContext::RandomSeed()
520
535
requires_seed = false ;
521
536
}
522
537
523
- uint256 FastRandomContext::rand256 ()
538
+ uint256 FastRandomContext::rand256 () noexcept
524
539
{
525
540
if (bytebuf_size < 32 ) {
526
541
FillByteBuffer ();
@@ -541,7 +556,7 @@ std::vector<unsigned char> FastRandomContext::randbytes(size_t len)
541
556
return ret;
542
557
}
543
558
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 )
545
560
{
546
561
rng.SetKey (seed.begin (), 32 );
547
562
}
@@ -592,7 +607,7 @@ bool Random_SanityCheck()
592
607
return true ;
593
608
}
594
609
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 )
596
611
{
597
612
if (!fDeterministic ) {
598
613
return ;
0 commit comments