Skip to content

Commit 2de0559

Browse files
committed
Merge bitcoin/bitcoin#27189: util: Use steady clock in SeedStrengthen, FindBestImplementation, FlushStateToDisk
fa1b4e5 Use steady clock in FlushStateToDisk (MarcoFalke) 1111e2f Use steady clock in SeedStrengthen and FindBestImplementation (MarcoFalke) Pull request description: There may be a theoretical deadlock for the duration of the offset when the system clock is adjusted into a past time while executing `SeedStrengthen`. Fix this by using steady clock. Do the same in `FindBestImplementation`, which shouldn't be affected, because it discards outlier measurements. However, doing the same there for consistency seems fine. Do the same in `FlushStateToDisk`, which should make the flushes more steady, if the system clock is adjusted by a large offset. ACKs for top commit: john-moffett: ACK fa1b4e5 willcl-ark: ACK fa1b4e5 Tree-SHA512: cc625e796b186accd53222bd64eb57d0512bc7e588312d254349b542bbc5e5daac348ff2b3b3f7dc5ae0bbbae2ec11fdbf3022cf2164211633765a4b0108e83e
2 parents d5e4f9a + fa1b4e5 commit 2de0559

File tree

6 files changed

+20
-18
lines changed

6 files changed

+20
-18
lines changed

ci/test/06_script_b.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,14 @@ if [ "${RUN_TIDY}" = "true" ]; then
5151
" src/node/chainstate.cpp"\
5252
" src/node/chainstatemanager_args.cpp"\
5353
" src/node/mempool_args.cpp"\
54+
" src/node/minisketchwrapper.cpp"\
5455
" src/node/utxo_snapshot.cpp"\
5556
" src/node/validation_cache_args.cpp"\
5657
" src/policy/feerate.cpp"\
5758
" src/policy/packages.cpp"\
5859
" src/policy/settings.cpp"\
5960
" src/primitives/transaction.cpp"\
61+
" src/random.cpp"\
6062
" src/rpc/fees.cpp"\
6163
" src/rpc/signmessage.cpp"\
6264
" src/test/fuzz/txorphan.cpp"\

src/node/minisketchwrapper.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,25 +23,25 @@ static constexpr uint32_t BITS = 32;
2323

2424
uint32_t FindBestImplementation()
2525
{
26-
std::optional<std::pair<int64_t, uint32_t>> best;
26+
std::optional<std::pair<SteadyClock::duration, uint32_t>> best;
2727

2828
uint32_t max_impl = Minisketch::MaxImplementation();
2929
for (uint32_t impl = 0; impl <= max_impl; ++impl) {
30-
std::vector<int64_t> benches;
30+
std::vector<SteadyClock::duration> benches;
3131
uint64_t offset = 0;
3232
/* Run a little benchmark with capacity 32, adding 184 entries, and decoding 11 of them once. */
3333
for (int b = 0; b < 11; ++b) {
3434
if (!Minisketch::ImplementationSupported(BITS, impl)) break;
3535
Minisketch sketch(BITS, impl, 32);
36-
auto start = GetTimeMicros();
36+
auto start = SteadyClock::now();
3737
for (uint64_t e = 0; e < 100; ++e) {
3838
sketch.Add(e*1337 + b*13337 + offset);
3939
}
4040
for (uint64_t e = 0; e < 84; ++e) {
4141
sketch.Add(e*1337 + b*13337 + offset);
4242
}
4343
offset += (*sketch.Decode(32))[0];
44-
auto stop = GetTimeMicros();
44+
auto stop = SteadyClock::now();
4545
benches.push_back(stop - start);
4646
}
4747
/* Remember which implementation has the best median benchmark time. */

src/random.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -221,14 +221,14 @@ static void SeedHardwareSlow(CSHA512& hasher) noexcept {
221221
}
222222

223223
/** Use repeated SHA512 to strengthen the randomness in seed32, and feed into hasher. */
224-
static void Strengthen(const unsigned char (&seed)[32], int microseconds, CSHA512& hasher) noexcept
224+
static void Strengthen(const unsigned char (&seed)[32], SteadyClock::duration dur, CSHA512& hasher) noexcept
225225
{
226226
CSHA512 inner_hasher;
227227
inner_hasher.Write(seed, sizeof(seed));
228228

229229
// Hash loop
230230
unsigned char buffer[64];
231-
int64_t stop = GetTimeMicros() + microseconds;
231+
const auto stop{SteadyClock::now() + dur};
232232
do {
233233
for (int i = 0; i < 1000; ++i) {
234234
inner_hasher.Finalize(buffer);
@@ -238,7 +238,7 @@ static void Strengthen(const unsigned char (&seed)[32], int microseconds, CSHA51
238238
// Benchmark operation and feed it into outer hasher.
239239
int64_t perf = GetPerformanceCounter();
240240
hasher.Write((const unsigned char*)&perf, sizeof(perf));
241-
} while (GetTimeMicros() < stop);
241+
} while (SteadyClock::now() < stop);
242242

243243
// Produce output from inner state and feed it to outer hasher.
244244
inner_hasher.Finalize(buffer);
@@ -492,13 +492,13 @@ static void SeedSlow(CSHA512& hasher, RNGState& rng) noexcept
492492
}
493493

494494
/** Extract entropy from rng, strengthen it, and feed it into hasher. */
495-
static void SeedStrengthen(CSHA512& hasher, RNGState& rng, int microseconds) noexcept
495+
static void SeedStrengthen(CSHA512& hasher, RNGState& rng, SteadyClock::duration dur) noexcept
496496
{
497497
// Generate 32 bytes of entropy from the RNG, and a copy of the entropy already in hasher.
498498
unsigned char strengthen_seed[32];
499499
rng.MixExtract(strengthen_seed, sizeof(strengthen_seed), CSHA512(hasher), false);
500500
// Strengthen the seed, and feed it into hasher.
501-
Strengthen(strengthen_seed, microseconds, hasher);
501+
Strengthen(strengthen_seed, dur, hasher);
502502
}
503503

504504
static void SeedPeriodic(CSHA512& hasher, RNGState& rng) noexcept
@@ -518,7 +518,7 @@ static void SeedPeriodic(CSHA512& hasher, RNGState& rng) noexcept
518518
LogPrint(BCLog::RAND, "Feeding %i bytes of dynamic environment data into RNG\n", hasher.Size() - old_size);
519519

520520
// Strengthen for 10 ms
521-
SeedStrengthen(hasher, rng, 10000);
521+
SeedStrengthen(hasher, rng, 10ms);
522522
}
523523

524524
static void SeedStartup(CSHA512& hasher, RNGState& rng) noexcept
@@ -538,7 +538,7 @@ static void SeedStartup(CSHA512& hasher, RNGState& rng) noexcept
538538
LogPrint(BCLog::RAND, "Feeding %i bytes of environment data into RNG\n", hasher.Size() - old_size);
539539

540540
// Strengthen for 100 ms
541-
SeedStrengthen(hasher, rng, 100000);
541+
SeedStrengthen(hasher, rng, 100ms);
542542
}
543543

544544
enum class RNGLevel {

src/util/time.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
#include <compat/compat.h>
1010

11-
#include <chrono>
11+
#include <chrono> // IWYU pragma: export
1212
#include <cstdint>
1313
#include <string>
1414

src/validation.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2478,12 +2478,12 @@ bool Chainstate::FlushStateToDisk(
24782478
}
24792479
}
24802480
}
2481-
const auto nNow = GetTime<std::chrono::microseconds>();
2481+
const auto nNow{SteadyClock::now()};
24822482
// Avoid writing/flushing immediately after startup.
2483-
if (m_last_write.count() == 0) {
2483+
if (m_last_write == decltype(m_last_write){}) {
24842484
m_last_write = nNow;
24852485
}
2486-
if (m_last_flush.count() == 0) {
2486+
if (m_last_flush == decltype(m_last_flush){}) {
24872487
m_last_flush = nNow;
24882488
}
24892489
// The cache is large and we're within 10% and 10 MiB of the limit, but we have time now (not in the middle of a block processing).
@@ -2544,7 +2544,7 @@ bool Chainstate::FlushStateToDisk(
25442544
m_last_flush = nNow;
25452545
full_flush_completed = true;
25462546
TRACE5(utxocache, flush,
2547-
(int64_t)(GetTimeMicros() - nNow.count()), // in microseconds (µs)
2547+
int64_t{Ticks<std::chrono::microseconds>(SteadyClock::now() - nNow)},
25482548
(uint32_t)mode,
25492549
(uint64_t)coins_count,
25502550
(uint64_t)coins_mem_usage,

src/validation.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -808,8 +808,8 @@ class Chainstate
808808
void UpdateTip(const CBlockIndex* pindexNew)
809809
EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
810810

811-
std::chrono::microseconds m_last_write{0};
812-
std::chrono::microseconds m_last_flush{0};
811+
SteadyClock::time_point m_last_write{};
812+
SteadyClock::time_point m_last_flush{};
813813

814814
/**
815815
* In case of an invalid snapshot, rename the coins leveldb directory so

0 commit comments

Comments
 (0)