-
Notifications
You must be signed in to change notification settings - Fork 0
Merge bitcoin/bitcoin#27405: util: Use steady clock instead of system clock to measure durations #1144
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: backport-0.25-batch-415
Are you sure you want to change the base?
Merge bitcoin/bitcoin#27405: util: Use steady clock instead of system clock to measure durations #1144
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -494,13 +494,14 @@ bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (Unlock(_vMasterKey)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| int64_t nStartTime = TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| constexpr MillisecondsDouble target{100}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| auto start{SteadyClock::now()}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pMasterKey.second.nDeriveIterations = static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * (100 / ((double)(TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()) - nStartTime)))); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pMasterKey.second.nDeriveIterations = static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * target / (SteadyClock::now() - start)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| nStartTime = TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| start = SteadyClock::now(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * 100 / ((double)(TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()) - nStartTime)))) / 2; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * target / (SteadyClock::now() - start))) / 2; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+497
to
505
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chainUse a standard chrono type; avoid undefined MillisecondsDouble
- constexpr MillisecondsDouble target{100};
+ constexpr std::chrono::milliseconds target{100};
auto start{SteadyClock::now()};
...
- pMasterKey.second.nDeriveIterations = static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * target / (SteadyClock::now() - start));
+ pMasterKey.second.nDeriveIterations = static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * (target / (SteadyClock::now() - start)));
...
- start = SteadyClock::now();
+ start = SteadyClock::now();
...
- pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * target / (SteadyClock::now() - start))) / 2;
+ pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * (target / (SteadyClock::now() - start)))) / 2;This keeps the intended ratio (100 ms per measurement window) while eliminating a likely missing alias. Quick check for alias presence: 🏁 Script executed: #!/bin/bash
rg -n 'MillisecondsDouble' src/util src/walletLength of output: 155 🏁 Script executed: #!/bin/bash
set -e
# Locate util/time.h
file=$(fd --full-path time.h src/util)
echo "Inspecting $file"
# Check for Double aliases
rg -n 'using .*Double' "$file"
rg -n 'typedef .*Double' "$file"Length of output: 194 Replace undefined MillisecondsDouble with std::chrono::duration<double, std::milli> MillisecondsDouble isn’t defined in src/util/time.h. Replace both occurrences with a double-precision duration and wrap the ratio in parentheses for correct precision: --- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ lines 497,704
- constexpr MillisecondsDouble target{100};
+ constexpr std::chrono::duration<double, std::milli> target{100.0};
@@ lines 500,707
- pMasterKey.second.nDeriveIterations = static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * target / (SteadyClock::now() - start));
+ pMasterKey.second.nDeriveIterations = static_cast<unsigned int>(
+ pMasterKey.second.nDeriveIterations * (target / (SteadyClock::now() - start))
+ );
@@ lines 504,711
- pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * target / (SteadyClock::now() - start))) / 2;
+ pMasterKey.second.nDeriveIterations = static_cast<unsigned int>(
+ (pMasterKey.second.nDeriveIterations +
+ pMasterKey.second.nDeriveIterations * (target / (SteadyClock::now() - start)))
+ / 2
+ );This eliminates the undefined alias while preserving fractional-millisecond precision. 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (pMasterKey.second.nDeriveIterations < 25000) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pMasterKey.second.nDeriveIterations = 25000; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -700,13 +701,14 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| GetStrongRandBytes(kMasterKey.vchSalt); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CCrypter crypter; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| int64_t nStartTime = TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| constexpr MillisecondsDouble target{100}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| auto start{SteadyClock::now()}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| kMasterKey.nDeriveIterations = static_cast<unsigned int>(2500000 / ((double)(TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()) - nStartTime))); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| kMasterKey.nDeriveIterations = static_cast<unsigned int>(25000 * target / (SteadyClock::now() - start)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| nStartTime = TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| start = SteadyClock::now(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + static_cast<unsigned int>(kMasterKey.nDeriveIterations * 100 / ((double)(TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()) - nStartTime)))) / 2; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + static_cast<unsigned int>(kMasterKey.nDeriveIterations * target / (SteadyClock::now() - start))) / 2; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (kMasterKey.nDeriveIterations < 25000) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
703
to
713
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same MillisecondsDouble issue here Mirror the change as above: - constexpr MillisecondsDouble target{100};
+ constexpr std::chrono::milliseconds target{100};
auto start{SteadyClock::now()};
...
- kMasterKey.nDeriveIterations = static_cast<unsigned int>(25000 * target / (SteadyClock::now() - start));
+ kMasterKey.nDeriveIterations = static_cast<unsigned int>(25000 * (target / (SteadyClock::now() - start)));
...
- start = SteadyClock::now();
+ start = SteadyClock::now();
...
- kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + static_cast<unsigned int>(kMasterKey.nDeriveIterations * target / (SteadyClock::now() - start))) / 2;
+ kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + static_cast<unsigned int>(kMasterKey.nDeriveIterations * (target / (SteadyClock::now() - start)))) / 2;📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| kMasterKey.nDeriveIterations = 25000; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -267,7 +267,8 @@ class CWallet final : public WalletStorage, public interfaces::Chain::Notificati | |||||||||||||
| std::atomic<bool> fAbortRescan{false}; // reset by WalletRescanReserver::reserve() | ||||||||||||||
| std::atomic<bool> fScanningWallet{false}; // controlled by WalletRescanReserver | ||||||||||||||
| std::atomic<bool> m_attaching_chain{false}; | ||||||||||||||
| std::atomic<int64_t> m_scanning_start{0}; | ||||||||||||||
| std::atomic<bool> m_scanning_with_passphrase{false}; | ||||||||||||||
| std::atomic<SteadyClock::time_point> m_scanning_start{SteadyClock::time_point{}}; | ||||||||||||||
| std::atomic<double> m_scanning_progress{0}; | ||||||||||||||
|
Comment on lines
+270
to
272
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing include for SteadyClock types used in header
Add at the top near other util includes: +#include <util/time.h>📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
| friend class WalletRescanReserver; | ||||||||||||||
|
|
||||||||||||||
|
|
@@ -576,7 +577,8 @@ class CWallet final : public WalletStorage, public interfaces::Chain::Notificati | |||||||||||||
| void AbortRescan() { fAbortRescan = true; } | ||||||||||||||
| bool IsAbortingRescan() const { return fAbortRescan; } | ||||||||||||||
| bool IsScanning() const { return fScanningWallet; } | ||||||||||||||
| int64_t ScanningDuration() const { return fScanningWallet ? TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()) - m_scanning_start : 0; } | ||||||||||||||
| bool IsScanningWithPassphrase() const { return m_scanning_with_passphrase; } | ||||||||||||||
| SteadyClock::duration ScanningDuration() const { return fScanningWallet ? SteadyClock::now() - m_scanning_start.load() : SteadyClock::duration{}; } | ||||||||||||||
| double ScanningProgress() const { return fScanningWallet ? (double) m_scanning_progress : 0; } | ||||||||||||||
|
|
||||||||||||||
| //! Upgrade stored CKeyMetadata objects to store key origin info as KeyOriginInfo | ||||||||||||||
|
|
@@ -1085,7 +1087,8 @@ class WalletRescanReserver | |||||||||||||
| if (m_wallet.fScanningWallet.exchange(true)) { | ||||||||||||||
| return false; | ||||||||||||||
| } | ||||||||||||||
| m_wallet.m_scanning_start = TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()); | ||||||||||||||
| m_wallet.m_scanning_with_passphrase.exchange(with_passphrase); | ||||||||||||||
| m_wallet.m_scanning_start = SteadyClock::now(); | ||||||||||||||
| m_wallet.m_scanning_progress = 0; | ||||||||||||||
|
Comment on lines
+1090
to
1092
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Compile error: undefined identifier ‘with_passphrase’
- m_wallet.m_scanning_with_passphrase.exchange(with_passphrase);
+ m_wallet.m_scanning_with_passphrase = false; // or plumb a parameter from the call sites if neededAlternatively, extend 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
| m_wallet.fAbortRescan = false; | ||||||||||||||
| m_could_reserve = true; | ||||||||||||||
|
|
||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add required header for chrono types
This TU now uses std::chrono::milliseconds; explicitly include to avoid relying on transitive includes:
+#include <chrono>📝 Committable suggestion
🤖 Prompt for AI Agents