aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/net.cpp3
-rw-r--r--src/net_processing.cpp6
-rw-r--r--src/random.h33
-rw-r--r--src/test/random_tests.cpp24
4 files changed, 36 insertions, 30 deletions
diff --git a/src/net.cpp b/src/net.cpp
index ac66540022..9e969718b7 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -3475,7 +3475,8 @@ std::vector<CAddress> CConnman::GetAddresses(CNode& requestor, size_t max_addres
// nodes to be "terrible" (see IsTerrible()) if the timestamps are older than 30 days,
// max. 24 hours of "penalty" due to cache shouldn't make any meaningful difference
// in terms of the freshness of the response.
- cache_entry.m_cache_entry_expiration = current_time + std::chrono::hours(21) + GetRandMicros(std::chrono::hours(6));
+ cache_entry.m_cache_entry_expiration = current_time +
+ 21h + FastRandomContext().randrange<std::chrono::microseconds>(6h);
}
return cache_entry.m_addrs_response_cache;
}
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index d674811ba7..ce3ff71df1 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -1698,7 +1698,7 @@ void PeerManagerImpl::ReattemptInitialBroadcast(CScheduler& scheduler)
// Schedule next run for 10-15 minutes in the future.
// We add randomness on every cycle to avoid the possibility of P2P fingerprinting.
- const std::chrono::milliseconds delta = 10min + GetRandMillis(5min);
+ const auto delta = 10min + FastRandomContext().randrange<std::chrono::milliseconds>(5min);
scheduler.scheduleFromNow([&] { ReattemptInitialBroadcast(scheduler); }, delta);
}
@@ -2050,7 +2050,7 @@ void PeerManagerImpl::StartScheduledTasks(CScheduler& scheduler)
scheduler.scheduleEvery([this] { this->CheckForStaleTipAndEvictPeers(); }, std::chrono::seconds{EXTRA_PEER_CHECK_INTERVAL});
// schedule next run for 10-15 minutes in the future
- const std::chrono::milliseconds delta = 10min + GetRandMillis(5min);
+ const auto delta = 10min + FastRandomContext().randrange<std::chrono::milliseconds>(5min);
scheduler.scheduleFromNow([&] { ReattemptInitialBroadcast(scheduler); }, delta);
}
@@ -5753,7 +5753,7 @@ void PeerManagerImpl::MaybeSendFeefilter(CNode& pto, Peer& peer, std::chrono::mi
// until scheduled broadcast, then move the broadcast to within MAX_FEEFILTER_CHANGE_DELAY.
else if (current_time + MAX_FEEFILTER_CHANGE_DELAY < peer.m_next_send_feefilter &&
(currentFilter < 3 * peer.m_fee_filter_sent / 4 || currentFilter > 4 * peer.m_fee_filter_sent / 3)) {
- peer.m_next_send_feefilter = current_time + GetRandomDuration<std::chrono::microseconds>(MAX_FEEFILTER_CHANGE_DELAY);
+ peer.m_next_send_feefilter = current_time + FastRandomContext().randrange<std::chrono::microseconds>(MAX_FEEFILTER_CHANGE_DELAY);
}
}
diff --git a/src/random.h b/src/random.h
index 1573e49ef7..b9cba1d602 100644
--- a/src/random.h
+++ b/src/random.h
@@ -132,6 +132,13 @@ concept RandomNumberGenerator = requires(T& rng, Span<std::byte> s) {
requires std::derived_from<std::remove_reference_t<T>, RandomMixin<std::remove_reference_t<T>>>;
};
+/** A concept for C++ std::chrono durations. */
+template<typename T>
+concept StdChronoDuration = requires {
+ []<class Rep, class Period>(std::type_identity<std::chrono::duration<Rep, Period>>){}(
+ std::type_identity<T>());
+};
+
/** Mixin class that provides helper randomness functions.
*
* Intended to be used through CRTP: https://en.cppreference.com/w/cpp/language/crtp.
@@ -300,7 +307,7 @@ public:
}
/** Generate a uniform random duration in the range from 0 (inclusive) to range (exclusive). */
- template <typename Chrono>
+ template <typename Chrono> requires StdChronoDuration<typename Chrono::duration>
typename Chrono::duration rand_uniform_duration(typename Chrono::duration range) noexcept
{
using Dur = typename Chrono::duration;
@@ -309,6 +316,17 @@ public:
/* interval [0..0] */ Dur{0};
};
+ /** Generate a uniform random duration in the range [0..max). Precondition: max.count() > 0 */
+ template <StdChronoDuration Dur>
+ Dur randrange(typename std::common_type_t<Dur> range) noexcept
+ // Having the compiler infer the template argument from the function argument
+ // is dangerous, because the desired return value generally has a different
+ // type than the function argument. So std::common_type is used to force the
+ // call site to specify the type of the return value.
+ {
+ return Dur{Impl().randrange(range.count())};
+ }
+
// Compatibility with the UniformRandomBitGenerator concept
typedef uint64_t result_type;
static constexpr uint64_t min() noexcept { return 0; }
@@ -426,19 +444,6 @@ void Shuffle(I first, I last, R&& rng)
}
}
-/** 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
-// Having the compiler infer the template argument from the function argument
-// is dangerous, because the desired return value generally has a different
-// type than the function argument. So std::common_type is used to force the
-// call site to specify the type of the return value.
-{
- return D{FastRandomContext().randrange(max.count())};
-};
-constexpr auto GetRandMicros = GetRandomDuration<std::chrono::microseconds>;
-constexpr auto GetRandMillis = GetRandomDuration<std::chrono::milliseconds>;
-
/* Number of random bytes returned by GetOSRand.
* When changing this constant make sure to change all call sites, and make
* sure that the underlying OS APIs for all platforms support the number.
diff --git a/src/test/random_tests.cpp b/src/test/random_tests.cpp
index 6932e186d5..b7479d310c 100644
--- a/src/test/random_tests.cpp
+++ b/src/test/random_tests.cpp
@@ -30,18 +30,18 @@ BOOST_AUTO_TEST_CASE(fastrandom_tests_deterministic)
{
BOOST_CHECK_EQUAL(FastRandomContext().rand<uint64_t>(), uint64_t{9330418229102544152u});
BOOST_CHECK_EQUAL(FastRandomContext().rand<int>(), int{618925161});
- BOOST_CHECK_EQUAL(GetRandMicros(std::chrono::hours{1}).count(), 1271170921);
- BOOST_CHECK_EQUAL(GetRandMillis(std::chrono::hours{1}).count(), 2803534);
+ BOOST_CHECK_EQUAL(FastRandomContext().randrange<std::chrono::microseconds>(1h).count(), 1271170921);
+ BOOST_CHECK_EQUAL(FastRandomContext().randrange<std::chrono::milliseconds>(1h).count(), 2803534);
BOOST_CHECK_EQUAL(FastRandomContext().rand<uint64_t>(), uint64_t{10170981140880778086u});
BOOST_CHECK_EQUAL(FastRandomContext().rand<int>(), int{1689082725});
- BOOST_CHECK_EQUAL(GetRandMicros(std::chrono::hours{1}).count(), 2464643716);
- BOOST_CHECK_EQUAL(GetRandMillis(std::chrono::hours{1}).count(), 2312205);
+ BOOST_CHECK_EQUAL(FastRandomContext().randrange<std::chrono::microseconds>(1h).count(), 2464643716);
+ BOOST_CHECK_EQUAL(FastRandomContext().randrange<std::chrono::milliseconds>(1h).count(), 2312205);
BOOST_CHECK_EQUAL(FastRandomContext().rand<uint64_t>(), uint64_t{5689404004456455543u});
BOOST_CHECK_EQUAL(FastRandomContext().rand<int>(), int{785839937});
- BOOST_CHECK_EQUAL(GetRandMicros(std::chrono::hours{1}).count(), 93558804);
- BOOST_CHECK_EQUAL(GetRandMillis(std::chrono::hours{1}).count(), 507022);
+ BOOST_CHECK_EQUAL(FastRandomContext().randrange<std::chrono::microseconds>(1h).count(), 93558804);
+ BOOST_CHECK_EQUAL(FastRandomContext().randrange<std::chrono::milliseconds>(1h).count(), 507022);
}
{
@@ -84,18 +84,18 @@ BOOST_AUTO_TEST_CASE(fastrandom_tests_nondeterministic)
{
BOOST_CHECK(FastRandomContext().rand<uint64_t>() != uint64_t{9330418229102544152u});
BOOST_CHECK(FastRandomContext().rand<int>() != int{618925161});
- BOOST_CHECK(GetRandMicros(std::chrono::hours{1}).count() != 1271170921);
- BOOST_CHECK(GetRandMillis(std::chrono::hours{1}).count() != 2803534);
+ BOOST_CHECK(FastRandomContext().randrange<std::chrono::microseconds>(1h).count() != 1271170921);
+ BOOST_CHECK(FastRandomContext().randrange<std::chrono::milliseconds>(1h).count() != 2803534);
BOOST_CHECK(FastRandomContext().rand<uint64_t>() != uint64_t{10170981140880778086u});
BOOST_CHECK(FastRandomContext().rand<int>() != int{1689082725});
- BOOST_CHECK(GetRandMicros(std::chrono::hours{1}).count() != 2464643716);
- BOOST_CHECK(GetRandMillis(std::chrono::hours{1}).count() != 2312205);
+ BOOST_CHECK(FastRandomContext().randrange<std::chrono::microseconds>(1h).count() != 2464643716);
+ BOOST_CHECK(FastRandomContext().randrange<std::chrono::milliseconds>(1h).count() != 2312205);
BOOST_CHECK(FastRandomContext().rand<uint64_t>() != uint64_t{5689404004456455543u});
BOOST_CHECK(FastRandomContext().rand<int>() != int{785839937});
- BOOST_CHECK(GetRandMicros(std::chrono::hours{1}).count() != 93558804);
- BOOST_CHECK(GetRandMillis(std::chrono::hours{1}).count() != 507022);
+ BOOST_CHECK(FastRandomContext().randrange<std::chrono::microseconds>(1h).count() != 93558804);
+ BOOST_CHECK(FastRandomContext().randrange<std::chrono::milliseconds>(1h).count() != 507022);
}
{