From 9e64d69bf74c8a381fb59841519cc3736bce14d4 Mon Sep 17 00:00:00 2001 From: John Newbery Date: Tue, 14 Dec 2021 10:15:10 +0000 Subject: [PATCH] [move] Move PoissonNextSend to src/random and update comment PoissonNextSend is used by net and net_processing and is stateless, so place it in the utility random.cpp translation unit. --- src/net.cpp | 6 ------ src/net.h | 3 --- src/random.cpp | 7 +++++++ src/random.h | 14 +++++++++++++- 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 89a4aee5d98..1b1e7a4e8a0 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -3069,12 +3069,6 @@ std::chrono::microseconds CConnman::PoissonNextSendInbound(std::chrono::microsec return m_next_send_inv_to_incoming; } -std::chrono::microseconds PoissonNextSend(std::chrono::microseconds now, std::chrono::seconds average_interval) -{ - double unscaled = -log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */); - return now + std::chrono::duration_cast(unscaled * average_interval + 0.5us); -} - CSipHasher CConnman::GetDeterministicRandomizer(uint64_t id) const { return CSipHasher(nSeed0, nSeed1).Write(id); diff --git a/src/net.h b/src/net.h index 80fc93a5d03..b0162bb9492 100644 --- a/src/net.h +++ b/src/net.h @@ -1270,9 +1270,6 @@ private: friend struct ConnmanTestMsg; }; -/** Return a timestamp in the future (in microseconds) for exponentially distributed events. */ -std::chrono::microseconds PoissonNextSend(std::chrono::microseconds now, std::chrono::seconds average_interval); - /** Dump binary message to file, with timestamp */ void CaptureMessage(const CAddress& addr, const std::string& msg_type, const Span& data, bool is_incoming); diff --git a/src/random.cpp b/src/random.cpp index 6eb06c5d472..919061e61d9 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -19,6 +19,7 @@ #include // for Mutex #include // for GetTimeMicros() +#include #include #include @@ -714,3 +715,9 @@ void RandomInit() ReportHardwareRand(); } + +std::chrono::microseconds PoissonNextSend(std::chrono::microseconds now, std::chrono::seconds average_interval) +{ + double unscaled = -log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */); + return now + std::chrono::duration_cast(unscaled * average_interval + 0.5us); +} diff --git a/src/random.h b/src/random.h index 0c6dc249835..be73e44a877 100644 --- a/src/random.h +++ b/src/random.h @@ -10,7 +10,7 @@ #include #include -#include // For std::chrono::microseconds +#include #include #include @@ -82,6 +82,18 @@ D GetRandomDuration(typename std::common_type::type max) noexcept }; constexpr auto GetRandMicros = GetRandomDuration; constexpr auto GetRandMillis = GetRandomDuration; + +/** + * Return a timestamp in the future sampled from an exponential distribution + * (https://en.wikipedia.org/wiki/Exponential_distribution). This distribution + * is memoryless and should be used for repeated network events (e.g. sending a + * certain type of message) to minimize leaking information to observers. + * + * The probability of an event occuring before time x is 1 - e^-(x/a) where a + * is the average interval between events. + * */ +std::chrono::microseconds PoissonNextSend(std::chrono::microseconds now, std::chrono::seconds average_interval); + int GetRandInt(int nMax) noexcept; uint256 GetRandHash() noexcept;