aboutsummaryrefslogtreecommitdiff
path: root/src/random.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/random.h')
-rw-r--r--src/random.h36
1 files changed, 32 insertions, 4 deletions
diff --git a/src/random.h b/src/random.h
index 97302d61ab..5fe20c5f76 100644
--- a/src/random.h
+++ b/src/random.h
@@ -8,8 +8,10 @@
#include <crypto/chacha20.h>
#include <crypto/common.h>
+#include <span.h>
#include <uint256.h>
+#include <cassert>
#include <chrono>
#include <cstdint>
#include <limits>
@@ -66,9 +68,19 @@
*
* Thread-safe.
*/
-void GetRandBytes(unsigned char* buf, int num) noexcept;
+void GetRandBytes(Span<unsigned char> bytes) noexcept;
/** Generate a uniform random integer in the range [0..range). Precondition: range > 0 */
-uint64_t GetRand(uint64_t nMax) noexcept;
+uint64_t GetRandInternal(uint64_t nMax) noexcept;
+/** Generate a uniform random integer of type T in the range [0..nMax)
+ * nMax defaults to std::numeric_limits<T>::max()
+ * Precondition: nMax > 0, T is an integral type, no larger than uint64_t
+ */
+template<typename T>
+T GetRand(T nMax=std::numeric_limits<T>::max()) noexcept {
+ static_assert(std::is_integral<T>(), "T must be integral");
+ static_assert(std::numeric_limits<T>::max() <= std::numeric_limits<uint64_t>::max(), "GetRand only supports up to uint64_t");
+ return T(GetRandInternal(nMax));
+}
/** Generate a uniform random duration in the range [0..max). Precondition: max.count() > 0 */
template <typename D>
D GetRandomDuration(typename std::common_type<D>::type max) noexcept
@@ -94,7 +106,6 @@ constexpr auto GetRandMillis = GetRandomDuration<std::chrono::milliseconds>;
* */
std::chrono::microseconds GetExponentialRand(std::chrono::microseconds now, std::chrono::seconds average_interval);
-int GetRandInt(int nMax) noexcept;
uint256 GetRandHash() noexcept;
/**
@@ -105,7 +116,7 @@ uint256 GetRandHash() noexcept;
*
* Thread-safe.
*/
-void GetStrongRandBytes(unsigned char* buf, int num) noexcept;
+void GetStrongRandBytes(Span<unsigned char> bytes) noexcept;
/**
* Gather entropy from various expensive sources, and feed them to the PRNG state.
@@ -222,6 +233,23 @@ public:
/** Generate a random boolean. */
bool randbool() noexcept { return randbits(1); }
+ /** Return the time point advanced by a uniform random duration. */
+ template <typename Tp>
+ Tp rand_uniform_delay(const Tp& time, typename Tp::duration range)
+ {
+ return time + rand_uniform_duration<Tp>(range);
+ }
+
+ /** Generate a uniform random duration in the range from 0 (inclusive) to range (exclusive). */
+ template <typename Chrono>
+ typename Chrono::duration rand_uniform_duration(typename Chrono::duration range) noexcept
+ {
+ using Dur = typename Chrono::duration;
+ return range.count() > 0 ? /* interval [0..range) */ Dur{randrange(range.count())} :
+ range.count() < 0 ? /* interval (range..0] */ -Dur{randrange(-range.count())} :
+ /* interval [0..0] */ Dur{0};
+ };
+
// Compatibility with the C++11 UniformRandomBitGenerator concept
typedef uint64_t result_type;
static constexpr uint64_t min() { return 0; }