Skip to content

Commit 5671217

Browse files
committed
Merge bitcoin/bitcoin#24974: refactor: Make FEELER_SLEEP_WINDOW type safe (std::chrono)
fa74e72 refactor: Make FEELER_SLEEP_WINDOW type safe (std::chrono) (MacroFake) fa3b3cb Expose underlying clock in CThreadInterrupt (MacroFake) Pull request description: This gets rid of the `value*1000` manual conversion. ACKs for top commit: naumenkogs: utACK fa74e72 dergoegge: Code review ACK fa74e72 Tree-SHA512: 90409c05c25f0dd2f1c4dead78f707ebfd78b7d84ea4db9fcefd9c4958a1a3338ac657cd9e99eb8b47d52d4485fa3c947dce4ee1559fb56ae65878685e1ed9a3
2 parents c90f86e + fa74e72 commit 5671217

File tree

6 files changed

+31
-24
lines changed

6 files changed

+31
-24
lines changed

ci/test/06_script_b.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ if [ "${RUN_TIDY}" = "true" ]; then
5151
" src/rpc/fees.cpp"\
5252
" src/rpc/signmessage.cpp"\
5353
" src/test/fuzz/txorphan.cpp"\
54+
" src/threadinterrupt.cpp"\
5455
" src/util/bip32.cpp"\
5556
" src/util/bytevectorhash.cpp"\
5657
" src/util/error.cpp"\

src/net.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ static constexpr int DNSSEEDS_DELAY_PEER_THRESHOLD = 1000; // "many" vs "few" pe
8585
/** The default timeframe for -maxuploadtarget. 1 day. */
8686
static constexpr std::chrono::seconds MAX_UPLOAD_TIMEFRAME{60 * 60 * 24};
8787

88-
// We add a random period time (0 to 1 seconds) to feeler connections to prevent synchronization.
89-
#define FEELER_SLEEP_WINDOW 1
88+
// A random time period (0 to 1 seconds) is added to feeler connections to prevent synchronization.
89+
static constexpr auto FEELER_SLEEP_WINDOW{1s};
9090

9191
/** Used to pass flags to the Bind() function */
9292
enum BindFlags {
@@ -1568,6 +1568,7 @@ int CConnman::GetExtraBlockRelayCount() const
15681568
void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
15691569
{
15701570
SetSyscallSandboxPolicy(SyscallSandboxPolicy::NET_OPEN_CONNECTION);
1571+
FastRandomContext rng;
15711572
// Connect to specific addresses
15721573
if (!connect.empty())
15731574
{
@@ -1821,12 +1822,11 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
18211822
}
18221823

18231824
if (addrConnect.IsValid()) {
1824-
18251825
if (fFeeler) {
18261826
// Add small amount of random noise before connection to avoid synchronization.
1827-
int randsleep = GetRand<int>(FEELER_SLEEP_WINDOW * 1000);
1828-
if (!interruptNet.sleep_for(std::chrono::milliseconds(randsleep)))
1827+
if (!interruptNet.sleep_for(rng.rand_uniform_duration<CThreadInterrupt::Clock>(FEELER_SLEEP_WINDOW))) {
18291828
return;
1829+
}
18301830
LogPrint(BCLog::NET, "Making feeler connection to %s\n", addrConnect.ToString());
18311831
}
18321832

src/random.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <span.h>
1212
#include <uint256.h>
1313

14+
#include <cassert>
1415
#include <chrono>
1516
#include <cstdint>
1617
#include <limits>
@@ -236,13 +237,19 @@ class FastRandomContext
236237
template <typename Tp>
237238
Tp rand_uniform_delay(const Tp& time, typename Tp::duration range)
238239
{
239-
using Dur = typename Tp::duration;
240-
Dur dur{range.count() > 0 ? /* interval [0..range) */ Dur{randrange(range.count())} :
241-
range.count() < 0 ? /* interval (range..0] */ -Dur{randrange(-range.count())} :
242-
/* interval [0..0] */ Dur{0}};
243-
return time + dur;
240+
return time + rand_uniform_duration<Tp>(range);
244241
}
245242

243+
/** Generate a uniform random duration in the range from 0 (inclusive) to range (exclusive). */
244+
template <typename Chrono>
245+
typename Chrono::duration rand_uniform_duration(typename Chrono::duration range) noexcept
246+
{
247+
using Dur = typename Chrono::duration;
248+
return range.count() > 0 ? /* interval [0..range) */ Dur{randrange(range.count())} :
249+
range.count() < 0 ? /* interval (range..0] */ -Dur{randrange(-range.count())} :
250+
/* interval [0..0] */ Dur{0};
251+
};
252+
246253
// Compatibility with the C++11 UniformRandomBitGenerator concept
247254
typedef uint64_t result_type;
248255
static constexpr uint64_t min() { return 0; }

src/test/random_tests.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,16 @@ BOOST_AUTO_TEST_CASE(fastrandom_tests)
5353
BOOST_CHECK_EQUAL(ctx1.randbits(3), ctx2.randbits(3));
5454
BOOST_CHECK(ctx1.rand256() == ctx2.rand256());
5555
BOOST_CHECK(ctx1.randbytes(50) == ctx2.randbytes(50));
56+
{
57+
struct MicroClock {
58+
using duration = std::chrono::microseconds;
59+
};
60+
FastRandomContext ctx{true};
61+
// Check with clock type
62+
BOOST_CHECK_EQUAL(47222, ctx.rand_uniform_duration<MicroClock>(1s).count());
63+
// Check with time-point type
64+
BOOST_CHECK_EQUAL(2782, ctx.rand_uniform_duration<SteadySeconds>(9h).count());
65+
}
5666

5767
// Check that a nondeterministic ones are not
5868
g_mock_deterministic_tests = false;

src/threadinterrupt.cpp

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,8 @@ void CThreadInterrupt::operator()()
2828
cond.notify_all();
2929
}
3030

31-
bool CThreadInterrupt::sleep_for(std::chrono::milliseconds rel_time)
31+
bool CThreadInterrupt::sleep_for(Clock::duration rel_time)
3232
{
3333
WAIT_LOCK(mut, lock);
3434
return !cond.wait_for(lock, rel_time, [this]() { return flag.load(std::memory_order_acquire); });
3535
}
36-
37-
bool CThreadInterrupt::sleep_for(std::chrono::seconds rel_time)
38-
{
39-
return sleep_for(std::chrono::duration_cast<std::chrono::milliseconds>(rel_time));
40-
}
41-
42-
bool CThreadInterrupt::sleep_for(std::chrono::minutes rel_time)
43-
{
44-
return sleep_for(std::chrono::duration_cast<std::chrono::milliseconds>(rel_time));
45-
}

src/threadinterrupt.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,12 @@
1919
class CThreadInterrupt
2020
{
2121
public:
22+
using Clock = std::chrono::steady_clock;
2223
CThreadInterrupt();
2324
explicit operator bool() const;
2425
void operator()() EXCLUSIVE_LOCKS_REQUIRED(!mut);
2526
void reset();
26-
bool sleep_for(std::chrono::milliseconds rel_time) EXCLUSIVE_LOCKS_REQUIRED(!mut);
27-
bool sleep_for(std::chrono::seconds rel_time) EXCLUSIVE_LOCKS_REQUIRED(!mut);
28-
bool sleep_for(std::chrono::minutes rel_time) EXCLUSIVE_LOCKS_REQUIRED(!mut);
27+
bool sleep_for(Clock::duration rel_time) EXCLUSIVE_LOCKS_REQUIRED(!mut);
2928

3029
private:
3130
std::condition_variable cond;

0 commit comments

Comments
 (0)