diff options
author | fanquake <fanquake@gmail.com> | 2023-03-08 08:40:21 +0100 |
---|---|---|
committer | fanquake <fanquake@gmail.com> | 2023-03-08 08:48:41 +0100 |
commit | 2de0559f2cb3e02881c0b1a132481fce51a18448 (patch) | |
tree | cc8e2cf1f7deb796a30a153ce7847660fee71ebe /src | |
parent | d5e4f9a43952f294e165381116773d2aab00100d (diff) | |
parent | fa1b4e5c3294fc9aec033892a4a4d7b5cfc015aa (diff) |
Merge bitcoin/bitcoin#27189: util: Use steady clock in SeedStrengthen, FindBestImplementation, FlushStateToDisk
fa1b4e5c3294fc9aec033892a4a4d7b5cfc015aa Use steady clock in FlushStateToDisk (MarcoFalke)
1111e2f8b43cd9ed62dcf6b571a224b84fc421fd 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 fa1b4e5c3294fc9aec033892a4a4d7b5cfc015aa
willcl-ark:
ACK fa1b4e5c3
Tree-SHA512: cc625e796b186accd53222bd64eb57d0512bc7e588312d254349b542bbc5e5daac348ff2b3b3f7dc5ae0bbbae2ec11fdbf3022cf2164211633765a4b0108e83e
Diffstat (limited to 'src')
-rw-r--r-- | src/node/minisketchwrapper.cpp | 8 | ||||
-rw-r--r-- | src/random.cpp | 14 | ||||
-rw-r--r-- | src/util/time.h | 2 | ||||
-rw-r--r-- | src/validation.cpp | 8 | ||||
-rw-r--r-- | src/validation.h | 4 |
5 files changed, 18 insertions, 18 deletions
diff --git a/src/node/minisketchwrapper.cpp b/src/node/minisketchwrapper.cpp index 67e823cb68..96707f7a0a 100644 --- a/src/node/minisketchwrapper.cpp +++ b/src/node/minisketchwrapper.cpp @@ -23,17 +23,17 @@ static constexpr uint32_t BITS = 32; uint32_t FindBestImplementation() { - std::optional<std::pair<int64_t, uint32_t>> best; + std::optional<std::pair<SteadyClock::duration, uint32_t>> best; uint32_t max_impl = Minisketch::MaxImplementation(); for (uint32_t impl = 0; impl <= max_impl; ++impl) { - std::vector<int64_t> benches; + std::vector<SteadyClock::duration> benches; uint64_t offset = 0; /* Run a little benchmark with capacity 32, adding 184 entries, and decoding 11 of them once. */ for (int b = 0; b < 11; ++b) { if (!Minisketch::ImplementationSupported(BITS, impl)) break; Minisketch sketch(BITS, impl, 32); - auto start = GetTimeMicros(); + auto start = SteadyClock::now(); for (uint64_t e = 0; e < 100; ++e) { sketch.Add(e*1337 + b*13337 + offset); } @@ -41,7 +41,7 @@ uint32_t FindBestImplementation() sketch.Add(e*1337 + b*13337 + offset); } offset += (*sketch.Decode(32))[0]; - auto stop = GetTimeMicros(); + auto stop = SteadyClock::now(); benches.push_back(stop - start); } /* Remember which implementation has the best median benchmark time. */ diff --git a/src/random.cpp b/src/random.cpp index 432592589a..f4c51574cc 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -221,14 +221,14 @@ static void SeedHardwareSlow(CSHA512& hasher) noexcept { } /** Use repeated SHA512 to strengthen the randomness in seed32, and feed into hasher. */ -static void Strengthen(const unsigned char (&seed)[32], int microseconds, CSHA512& hasher) noexcept +static void Strengthen(const unsigned char (&seed)[32], SteadyClock::duration dur, CSHA512& hasher) noexcept { CSHA512 inner_hasher; inner_hasher.Write(seed, sizeof(seed)); // Hash loop unsigned char buffer[64]; - int64_t stop = GetTimeMicros() + microseconds; + const auto stop{SteadyClock::now() + dur}; do { for (int i = 0; i < 1000; ++i) { inner_hasher.Finalize(buffer); @@ -238,7 +238,7 @@ static void Strengthen(const unsigned char (&seed)[32], int microseconds, CSHA51 // Benchmark operation and feed it into outer hasher. int64_t perf = GetPerformanceCounter(); hasher.Write((const unsigned char*)&perf, sizeof(perf)); - } while (GetTimeMicros() < stop); + } while (SteadyClock::now() < stop); // Produce output from inner state and feed it to outer hasher. inner_hasher.Finalize(buffer); @@ -492,13 +492,13 @@ static void SeedSlow(CSHA512& hasher, RNGState& rng) noexcept } /** Extract entropy from rng, strengthen it, and feed it into hasher. */ -static void SeedStrengthen(CSHA512& hasher, RNGState& rng, int microseconds) noexcept +static void SeedStrengthen(CSHA512& hasher, RNGState& rng, SteadyClock::duration dur) noexcept { // Generate 32 bytes of entropy from the RNG, and a copy of the entropy already in hasher. unsigned char strengthen_seed[32]; rng.MixExtract(strengthen_seed, sizeof(strengthen_seed), CSHA512(hasher), false); // Strengthen the seed, and feed it into hasher. - Strengthen(strengthen_seed, microseconds, hasher); + Strengthen(strengthen_seed, dur, hasher); } static void SeedPeriodic(CSHA512& hasher, RNGState& rng) noexcept @@ -518,7 +518,7 @@ static void SeedPeriodic(CSHA512& hasher, RNGState& rng) noexcept LogPrint(BCLog::RAND, "Feeding %i bytes of dynamic environment data into RNG\n", hasher.Size() - old_size); // Strengthen for 10 ms - SeedStrengthen(hasher, rng, 10000); + SeedStrengthen(hasher, rng, 10ms); } static void SeedStartup(CSHA512& hasher, RNGState& rng) noexcept @@ -538,7 +538,7 @@ static void SeedStartup(CSHA512& hasher, RNGState& rng) noexcept LogPrint(BCLog::RAND, "Feeding %i bytes of environment data into RNG\n", hasher.Size() - old_size); // Strengthen for 100 ms - SeedStrengthen(hasher, rng, 100000); + SeedStrengthen(hasher, rng, 100ms); } enum class RNGLevel { diff --git a/src/util/time.h b/src/util/time.h index d45baaa378..fcf85c1e03 100644 --- a/src/util/time.h +++ b/src/util/time.h @@ -8,7 +8,7 @@ #include <compat/compat.h> -#include <chrono> +#include <chrono> // IWYU pragma: export #include <cstdint> #include <string> diff --git a/src/validation.cpp b/src/validation.cpp index 823d326d18..f3c0401c0f 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2478,12 +2478,12 @@ bool Chainstate::FlushStateToDisk( } } } - const auto nNow = GetTime<std::chrono::microseconds>(); + const auto nNow{SteadyClock::now()}; // Avoid writing/flushing immediately after startup. - if (m_last_write.count() == 0) { + if (m_last_write == decltype(m_last_write){}) { m_last_write = nNow; } - if (m_last_flush.count() == 0) { + if (m_last_flush == decltype(m_last_flush){}) { m_last_flush = nNow; } // 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( m_last_flush = nNow; full_flush_completed = true; TRACE5(utxocache, flush, - (int64_t)(GetTimeMicros() - nNow.count()), // in microseconds (µs) + int64_t{Ticks<std::chrono::microseconds>(SteadyClock::now() - nNow)}, (uint32_t)mode, (uint64_t)coins_count, (uint64_t)coins_mem_usage, diff --git a/src/validation.h b/src/validation.h index b5ad1aff08..b0cef0d37b 100644 --- a/src/validation.h +++ b/src/validation.h @@ -808,8 +808,8 @@ private: void UpdateTip(const CBlockIndex* pindexNew) EXCLUSIVE_LOCKS_REQUIRED(::cs_main); - std::chrono::microseconds m_last_write{0}; - std::chrono::microseconds m_last_flush{0}; + SteadyClock::time_point m_last_write{}; + SteadyClock::time_point m_last_flush{}; /** * In case of an invalid snapshot, rename the coins leveldb directory so |