aboutsummaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/util')
-rw-r--r--src/util/asmap.cpp103
-rw-r--r--src/util/asmap.h10
-rw-r--r--src/util/bip32.cpp2
-rw-r--r--src/util/bip32.h2
-rw-r--r--src/util/message.cpp92
-rw-r--r--src/util/message.h76
-rw-r--r--src/util/moneystr.cpp10
-rw-r--r--src/util/moneystr.h2
-rw-r--r--src/util/settings.h12
-rw-r--r--src/util/system.cpp67
-rw-r--r--src/util/system.h22
-rw-r--r--src/util/time.cpp37
-rw-r--r--src/util/time.h4
-rw-r--r--src/util/validation.cpp19
-rw-r--r--src/util/validation.h18
15 files changed, 381 insertions, 95 deletions
diff --git a/src/util/asmap.cpp b/src/util/asmap.cpp
new file mode 100644
index 0000000000..60bd27bf90
--- /dev/null
+++ b/src/util/asmap.cpp
@@ -0,0 +1,103 @@
+// Copyright (c) 2019 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <vector>
+#include <assert.h>
+#include <crypto/common.h>
+
+namespace {
+
+uint32_t DecodeBits(std::vector<bool>::const_iterator& bitpos, const std::vector<bool>::const_iterator& endpos, uint8_t minval, const std::vector<uint8_t> &bit_sizes)
+{
+ uint32_t val = minval;
+ bool bit;
+ for (std::vector<uint8_t>::const_iterator bit_sizes_it = bit_sizes.begin();
+ bit_sizes_it != bit_sizes.end(); ++bit_sizes_it) {
+ if (bit_sizes_it + 1 != bit_sizes.end()) {
+ if (bitpos == endpos) break;
+ bit = *bitpos;
+ bitpos++;
+ } else {
+ bit = 0;
+ }
+ if (bit) {
+ val += (1 << *bit_sizes_it);
+ } else {
+ for (int b = 0; b < *bit_sizes_it; b++) {
+ if (bitpos == endpos) break;
+ bit = *bitpos;
+ bitpos++;
+ val += bit << (*bit_sizes_it - 1 - b);
+ }
+ return val;
+ }
+ }
+ return -1;
+}
+
+const std::vector<uint8_t> TYPE_BIT_SIZES{0, 0, 1};
+uint32_t DecodeType(std::vector<bool>::const_iterator& bitpos, const std::vector<bool>::const_iterator& endpos)
+{
+ return DecodeBits(bitpos, endpos, 0, TYPE_BIT_SIZES);
+}
+
+const std::vector<uint8_t> ASN_BIT_SIZES{15, 16, 17, 18, 19, 20, 21, 22, 23, 24};
+uint32_t DecodeASN(std::vector<bool>::const_iterator& bitpos, const std::vector<bool>::const_iterator& endpos)
+{
+ return DecodeBits(bitpos, endpos, 1, ASN_BIT_SIZES);
+}
+
+
+const std::vector<uint8_t> MATCH_BIT_SIZES{1, 2, 3, 4, 5, 6, 7, 8};
+uint32_t DecodeMatch(std::vector<bool>::const_iterator& bitpos, const std::vector<bool>::const_iterator& endpos)
+{
+ return DecodeBits(bitpos, endpos, 2, MATCH_BIT_SIZES);
+}
+
+
+const std::vector<uint8_t> JUMP_BIT_SIZES{5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30};
+uint32_t DecodeJump(std::vector<bool>::const_iterator& bitpos, const std::vector<bool>::const_iterator& endpos)
+{
+ return DecodeBits(bitpos, endpos, 17, JUMP_BIT_SIZES);
+}
+
+}
+
+uint32_t Interpret(const std::vector<bool> &asmap, const std::vector<bool> &ip)
+{
+ std::vector<bool>::const_iterator pos = asmap.begin();
+ const std::vector<bool>::const_iterator endpos = asmap.end();
+ uint8_t bits = ip.size();
+ uint32_t default_asn = 0;
+ uint32_t opcode, jump, match, matchlen;
+ while (pos != endpos) {
+ opcode = DecodeType(pos, endpos);
+ if (opcode == 0) {
+ return DecodeASN(pos, endpos);
+ } else if (opcode == 1) {
+ jump = DecodeJump(pos, endpos);
+ if (bits == 0) break;
+ if (ip[ip.size() - bits]) {
+ if (jump >= endpos - pos) break;
+ pos += jump;
+ }
+ bits--;
+ } else if (opcode == 2) {
+ match = DecodeMatch(pos, endpos);
+ matchlen = CountBits(match) - 1;
+ for (uint32_t bit = 0; bit < matchlen; bit++) {
+ if (bits == 0) break;
+ if ((ip[ip.size() - bits]) != ((match >> (matchlen - 1 - bit)) & 1)) {
+ return default_asn;
+ }
+ bits--;
+ }
+ } else if (opcode == 3) {
+ default_asn = DecodeASN(pos, endpos);
+ } else {
+ break;
+ }
+ }
+ return 0; // 0 is not a valid ASN
+}
diff --git a/src/util/asmap.h b/src/util/asmap.h
new file mode 100644
index 0000000000..a0e14013c5
--- /dev/null
+++ b/src/util/asmap.h
@@ -0,0 +1,10 @@
+// Copyright (c) 2019 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_UTIL_ASMAP_H
+#define BITCOIN_UTIL_ASMAP_H
+
+uint32_t Interpret(const std::vector<bool> &asmap, const std::vector<bool> &ip);
+
+#endif // BITCOIN_UTIL_ASMAP_H
diff --git a/src/util/bip32.cpp b/src/util/bip32.cpp
index 571c6ec5e1..6f176dd5ec 100644
--- a/src/util/bip32.cpp
+++ b/src/util/bip32.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2019-2018 The Bitcoin Core developers
+// Copyright (c) 2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
diff --git a/src/util/bip32.h b/src/util/bip32.h
index c93940e4eb..7e58b79f38 100644
--- a/src/util/bip32.h
+++ b/src/util/bip32.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2019-2018 The Bitcoin Core developers
+// Copyright (c) 2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
diff --git a/src/util/message.cpp b/src/util/message.cpp
new file mode 100644
index 0000000000..1e7128d225
--- /dev/null
+++ b/src/util/message.cpp
@@ -0,0 +1,92 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2020 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <hash.h> // For CHashWriter
+#include <key.h> // For CKey
+#include <key_io.h> // For DecodeDestination()
+#include <pubkey.h> // For CPubKey
+#include <script/standard.h> // For CTxDestination, IsValidDestination(), PKHash
+#include <serialize.h> // For SER_GETHASH
+#include <util/message.h>
+#include <util/strencodings.h> // For DecodeBase64()
+
+#include <string>
+#include <vector>
+
+/**
+ * Text used to signify that a signed message follows and to prevent
+ * inadvertently signing a transaction.
+ */
+const std::string MESSAGE_MAGIC = "Bitcoin Signed Message:\n";
+
+MessageVerificationResult MessageVerify(
+ const std::string& address,
+ const std::string& signature,
+ const std::string& message)
+{
+ CTxDestination destination = DecodeDestination(address);
+ if (!IsValidDestination(destination)) {
+ return MessageVerificationResult::ERR_INVALID_ADDRESS;
+ }
+
+ if (boost::get<PKHash>(&destination) == nullptr) {
+ return MessageVerificationResult::ERR_ADDRESS_NO_KEY;
+ }
+
+ bool invalid = false;
+ std::vector<unsigned char> signature_bytes = DecodeBase64(signature.c_str(), &invalid);
+ if (invalid) {
+ return MessageVerificationResult::ERR_MALFORMED_SIGNATURE;
+ }
+
+ CPubKey pubkey;
+ if (!pubkey.RecoverCompact(MessageHash(message), signature_bytes)) {
+ return MessageVerificationResult::ERR_PUBKEY_NOT_RECOVERED;
+ }
+
+ if (!(CTxDestination(PKHash(pubkey)) == destination)) {
+ return MessageVerificationResult::ERR_NOT_SIGNED;
+ }
+
+ return MessageVerificationResult::OK;
+}
+
+bool MessageSign(
+ const CKey& privkey,
+ const std::string& message,
+ std::string& signature)
+{
+ std::vector<unsigned char> signature_bytes;
+
+ if (!privkey.SignCompact(MessageHash(message), signature_bytes)) {
+ return false;
+ }
+
+ signature = EncodeBase64(signature_bytes.data(), signature_bytes.size());
+
+ return true;
+}
+
+uint256 MessageHash(const std::string& message)
+{
+ CHashWriter hasher(SER_GETHASH, 0);
+ hasher << MESSAGE_MAGIC << message;
+
+ return hasher.GetHash();
+}
+
+std::string SigningResultString(const SigningResult res)
+{
+ switch (res) {
+ case SigningResult::OK:
+ return "No error";
+ case SigningResult::PRIVATE_KEY_NOT_AVAILABLE:
+ return "Private key not available";
+ case SigningResult::SIGNING_FAILED:
+ return "Sign failed";
+ // no default case, so the compiler can warn about missing cases
+ }
+ assert(false);
+}
diff --git a/src/util/message.h b/src/util/message.h
new file mode 100644
index 0000000000..b31c5f5761
--- /dev/null
+++ b/src/util/message.h
@@ -0,0 +1,76 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2020 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_UTIL_MESSAGE_H
+#define BITCOIN_UTIL_MESSAGE_H
+
+#include <key.h> // For CKey
+#include <uint256.h>
+
+#include <string>
+
+extern const std::string MESSAGE_MAGIC;
+
+/** The result of a signed message verification.
+ * Message verification takes as an input:
+ * - address (with whose private key the message is supposed to have been signed)
+ * - signature
+ * - message
+ */
+enum class MessageVerificationResult {
+ //! The provided address is invalid.
+ ERR_INVALID_ADDRESS,
+
+ //! The provided address is valid but does not refer to a public key.
+ ERR_ADDRESS_NO_KEY,
+
+ //! The provided signature couldn't be parsed (maybe invalid base64).
+ ERR_MALFORMED_SIGNATURE,
+
+ //! A public key could not be recovered from the provided signature and message.
+ ERR_PUBKEY_NOT_RECOVERED,
+
+ //! The message was not signed with the private key of the provided address.
+ ERR_NOT_SIGNED,
+
+ //! The message verification was successful.
+ OK
+};
+
+enum class SigningResult {
+ OK, //!< No error
+ PRIVATE_KEY_NOT_AVAILABLE,
+ SIGNING_FAILED,
+};
+
+/** Verify a signed message.
+ * @param[in] address Signer's bitcoin address, it must refer to a public key.
+ * @param[in] signature The signature in base64 format.
+ * @param[in] message The message that was signed.
+ * @return result code */
+MessageVerificationResult MessageVerify(
+ const std::string& address,
+ const std::string& signature,
+ const std::string& message);
+
+/** Sign a message.
+ * @param[in] privkey Private key to sign with.
+ * @param[in] message The message to sign.
+ * @param[out] signature Signature, base64 encoded, only set if true is returned.
+ * @return true if signing was successful. */
+bool MessageSign(
+ const CKey& privkey,
+ const std::string& message,
+ std::string& signature);
+
+/**
+ * Hashes a message for signing and verification in a manner that prevents
+ * inadvertently signing a transaction.
+ */
+uint256 MessageHash(const std::string& message);
+
+std::string SigningResultString(const SigningResult res);
+
+#endif // BITCOIN_UTIL_MESSAGE_H
diff --git a/src/util/moneystr.cpp b/src/util/moneystr.cpp
index 2797f450ca..40d8918dfc 100644
--- a/src/util/moneystr.cpp
+++ b/src/util/moneystr.cpp
@@ -36,14 +36,14 @@ bool ParseMoney(const std::string& str, CAmount& nRet)
if (!ValidAsCString(str)) {
return false;
}
- return ParseMoney(str.c_str(), nRet);
-}
-bool ParseMoney(const char* pszIn, CAmount& nRet)
-{
+ if (str.empty()) {
+ return false;
+ }
+
std::string strWhole;
int64_t nUnits = 0;
- const char* p = pszIn;
+ const char* p = str.c_str();
while (IsSpace(*p))
p++;
for (; *p; p++)
diff --git a/src/util/moneystr.h b/src/util/moneystr.h
index 027c7e2e53..d8b08adc24 100644
--- a/src/util/moneystr.h
+++ b/src/util/moneystr.h
@@ -18,7 +18,7 @@
* JSON but use AmountFromValue and ValueFromAmount for that.
*/
std::string FormatMoney(const CAmount& n);
+/** Parse an amount denoted in full coins. E.g. "0.0034" supplied on the command line. **/
NODISCARD bool ParseMoney(const std::string& str, CAmount& nRet);
-NODISCARD bool ParseMoney(const char* pszIn, CAmount& nRet);
#endif // BITCOIN_UTIL_MONEYSTR_H
diff --git a/src/util/settings.h b/src/util/settings.h
index 9ca581109d..1d03639fa2 100644
--- a/src/util/settings.h
+++ b/src/util/settings.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2019 The Bitcoin Core developers
+// Copyright (c) 2019-2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -71,11 +71,11 @@ struct SettingsSpan {
explicit SettingsSpan(const SettingsValue& value) noexcept : SettingsSpan(&value, 1) {}
explicit SettingsSpan(const SettingsValue* data, size_t size) noexcept : data(data), size(size) {}
explicit SettingsSpan(const std::vector<SettingsValue>& vec) noexcept;
- const SettingsValue* begin() const; //<! Pointer to first non-negated value.
- const SettingsValue* end() const; //<! Pointer to end of values.
- bool empty() const; //<! True if there are any non-negated values.
- bool last_negated() const; //<! True if the last value is negated.
- size_t negated() const; //<! Number of negated values.
+ const SettingsValue* begin() const; //!< Pointer to first non-negated value.
+ const SettingsValue* end() const; //!< Pointer to end of values.
+ bool empty() const; //!< True if there are any non-negated values.
+ bool last_negated() const; //!< True if the last value is negated.
+ size_t negated() const; //!< Number of negated values.
const SettingsValue* data = nullptr;
size_t size = 0;
diff --git a/src/util/system.cpp b/src/util/system.cpp
index 8d1efc170a..b0a538b527 100644
--- a/src/util/system.cpp
+++ b/src/util/system.cpp
@@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2019 The Bitcoin Core developers
+// Copyright (c) 2009-2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -63,6 +63,7 @@
#include <malloc.h>
#endif
+#include <boost/algorithm/string/replace.hpp>
#include <thread>
#include <typeinfo>
#include <univalue.h>
@@ -312,21 +313,18 @@ bool ArgsManager::ParseParameters(int argc, const char* const argv[], std::strin
std::string section;
util::SettingsValue value = InterpretOption(section, key, val);
Optional<unsigned int> flags = GetArgFlags('-' + key);
- if (flags) {
- if (!CheckValid(key, value, *flags, error)) {
- return false;
- }
- // Weird behavior preserved for backwards compatibility: command
- // line options with section prefixes are allowed but ignored. It
- // would be better if these options triggered the Invalid parameter
- // error below.
- if (section.empty()) {
- m_settings.command_line_options[key].push_back(value);
- }
- } else {
- error = strprintf("Invalid parameter -%s", key);
+
+ // Unknown command line options and command line options with dot
+ // characters (which are returned from InterpretOption with nonempty
+ // section strings) are not valid.
+ if (!flags || !section.empty()) {
+ error = strprintf("Invalid parameter %s", argv[i]);
return false;
}
+
+ if (!CheckValid(key, value, *flags, error)) return false;
+
+ m_settings.command_line_options[key].push_back(value);
}
// we do not allow -includeconf from command line
@@ -864,6 +862,32 @@ std::vector<util::SettingsValue> ArgsManager::GetSettingsList(const std::string&
return util::GetSettingsList(m_settings, m_network, SettingName(arg), !UseDefaultSection(arg));
}
+void ArgsManager::logArgsPrefix(
+ const std::string& prefix,
+ const std::string& section,
+ const std::map<std::string, std::vector<util::SettingsValue>>& args) const
+{
+ std::string section_str = section.empty() ? "" : "[" + section + "] ";
+ for (const auto& arg : args) {
+ for (const auto& value : arg.second) {
+ Optional<unsigned int> flags = GetArgFlags('-' + arg.first);
+ if (flags) {
+ std::string value_str = (*flags & SENSITIVE) ? "****" : value.write();
+ LogPrintf("%s %s%s=%s\n", prefix, section_str, arg.first, value_str);
+ }
+ }
+ }
+}
+
+void ArgsManager::LogArgs() const
+{
+ LOCK(cs_args);
+ for (const auto& section : m_settings.ro_config) {
+ logArgsPrefix("Config file arg:", section.first, section.second);
+ }
+ logArgsPrefix("Command-line arg:", "", m_settings.command_line_options);
+}
+
bool RenameOver(fs::path src, fs::path dest)
{
#ifdef WIN32
@@ -974,17 +998,19 @@ void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length) {
SetEndOfFile(hFile);
#elif defined(MAC_OSX)
// OSX specific version
+ // NOTE: Contrary to other OS versions, the OSX version assumes that
+ // NOTE: offset is the size of the file.
fstore_t fst;
fst.fst_flags = F_ALLOCATECONTIG;
fst.fst_posmode = F_PEOFPOSMODE;
fst.fst_offset = 0;
- fst.fst_length = (off_t)offset + length;
+ fst.fst_length = length; // mac os fst_length takes the # of free bytes to allocate, not desired file size
fst.fst_bytesalloc = 0;
if (fcntl(fileno(file), F_PREALLOCATE, &fst) == -1) {
fst.fst_flags = F_ALLOCATEALL;
fcntl(fileno(file), F_PREALLOCATE, &fst);
}
- ftruncate(fileno(file), fst.fst_length);
+ ftruncate(fileno(file), static_cast<off_t>(offset) + length);
#else
#if defined(__linux__)
// Version using posix_fallocate
@@ -1022,6 +1048,15 @@ fs::path GetSpecialFolderPath(int nFolder, bool fCreate)
}
#endif
+#ifndef WIN32
+std::string ShellEscape(const std::string& arg)
+{
+ std::string escaped = arg;
+ boost::replace_all(escaped, "'", "'\"'\"'");
+ return "'" + escaped + "'";
+}
+#endif
+
#if HAVE_SYSTEM
void runCommand(const std::string& strCommand)
{
diff --git a/src/util/system.h b/src/util/system.h
index 394adb9555..3138522b5c 100644
--- a/src/util/system.h
+++ b/src/util/system.h
@@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2019 The Bitcoin Core developers
+// Copyright (c) 2009-2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -81,6 +81,9 @@ fs::path GetConfigFile(const std::string& confPath);
#ifdef WIN32
fs::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
#endif
+#ifndef WIN32
+std::string ShellEscape(const std::string& arg);
+#endif
#if HAVE_SYSTEM
void runCommand(const std::string& strCommand);
#endif
@@ -145,6 +148,8 @@ public:
* between mainnet and regtest/testnet won't cause problems due to these
* parameters by accident. */
NETWORK_ONLY = 0x200,
+ // This argument's value is sensitive (such as a password).
+ SENSITIVE = 0x400,
};
protected:
@@ -155,7 +160,7 @@ protected:
unsigned int m_flags;
};
- mutable CCriticalSection cs_args;
+ mutable RecursiveMutex cs_args;
util::Settings m_settings GUARDED_BY(cs_args);
std::string m_network GUARDED_BY(cs_args);
std::set<std::string> m_network_only_args GUARDED_BY(cs_args);
@@ -318,6 +323,19 @@ public:
* Return nullopt for unknown arg.
*/
Optional<unsigned int> GetArgFlags(const std::string& name) const;
+
+ /**
+ * Log the config file options and the command line arguments,
+ * useful for troubleshooting.
+ */
+ void LogArgs() const;
+
+private:
+ // Helper function for LogArgs().
+ void logArgsPrefix(
+ const std::string& prefix,
+ const std::string& section,
+ const std::map<std::string, std::vector<util::SettingsValue>>& args) const;
};
extern ArgsManager gArgs;
diff --git a/src/util/time.cpp b/src/util/time.cpp
index 2afff2626b..14937b985e 100644
--- a/src/util/time.cpp
+++ b/src/util/time.cpp
@@ -11,10 +11,13 @@
#include <atomic>
#include <boost/date_time/posix_time/posix_time.hpp>
-#include <boost/thread.hpp>
#include <ctime>
+#include <thread>
+
#include <tinyformat.h>
+void UninterruptibleSleep(const std::chrono::microseconds& n) { std::this_thread::sleep_for(n); }
+
static std::atomic<int64_t> nMockTime(0); //!< For unit testing
int64_t GetTime()
@@ -72,32 +75,16 @@ int64_t GetSystemTimeInSeconds()
return GetTimeMicros()/1000000;
}
-void MilliSleep(int64_t n)
-{
-
-/**
- * Boost's sleep_for was uninterruptible when backed by nanosleep from 1.50
- * until fixed in 1.52. Use the deprecated sleep method for the broken case.
- * See: https://svn.boost.org/trac/boost/ticket/7238
- */
-#if defined(HAVE_WORKING_BOOST_SLEEP_FOR)
- boost::this_thread::sleep_for(boost::chrono::milliseconds(n));
-#elif defined(HAVE_WORKING_BOOST_SLEEP)
- boost::this_thread::sleep(boost::posix_time::milliseconds(n));
-#else
-//should never get here
-#error missing boost sleep implementation
-#endif
-}
-
std::string FormatISO8601DateTime(int64_t nTime) {
struct tm ts;
time_t time_val = nTime;
#ifdef _MSC_VER
- gmtime_s(&ts, &time_val);
+ if (gmtime_s(&ts, &time_val) != 0) {
#else
- gmtime_r(&time_val, &ts);
+ if (gmtime_r(&time_val, &ts) == nullptr) {
#endif
+ return {};
+ }
return strprintf("%04i-%02i-%02iT%02i:%02i:%02iZ", ts.tm_year + 1900, ts.tm_mon + 1, ts.tm_mday, ts.tm_hour, ts.tm_min, ts.tm_sec);
}
@@ -105,10 +92,12 @@ std::string FormatISO8601Date(int64_t nTime) {
struct tm ts;
time_t time_val = nTime;
#ifdef _MSC_VER
- gmtime_s(&ts, &time_val);
+ if (gmtime_s(&ts, &time_val) != 0) {
#else
- gmtime_r(&time_val, &ts);
+ if (gmtime_r(&time_val, &ts) == nullptr) {
#endif
+ return {};
+ }
return strprintf("%04i-%02i-%02i", ts.tm_year + 1900, ts.tm_mon + 1, ts.tm_mday);
}
@@ -124,4 +113,4 @@ int64_t ParseISO8601DateTime(const std::string& str)
if (ptime.is_not_a_date_time() || epoch > ptime)
return 0;
return (ptime - epoch).total_seconds();
-} \ No newline at end of file
+}
diff --git a/src/util/time.h b/src/util/time.h
index af4390aa1c..77de1e047d 100644
--- a/src/util/time.h
+++ b/src/util/time.h
@@ -10,6 +10,8 @@
#include <string>
#include <chrono>
+void UninterruptibleSleep(const std::chrono::microseconds& n);
+
/**
* Helper to count the seconds of a duration.
*
@@ -36,8 +38,6 @@ void SetMockTime(int64_t nMockTimeIn);
/** For testing */
int64_t GetMockTime();
-void MilliSleep(int64_t n);
-
/** Return system time (or mocked time, if set) */
template <typename T>
T GetTime();
diff --git a/src/util/validation.cpp b/src/util/validation.cpp
deleted file mode 100644
index bd52f57751..0000000000
--- a/src/util/validation.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2019 The Bitcoin Core developers
-// Distributed under the MIT software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-#include <util/validation.h>
-
-#include <consensus/validation.h>
-#include <tinyformat.h>
-
-/** Convert ValidationState to a human-readable message for logging */
-std::string FormatStateMessage(const ValidationState &state)
-{
- return strprintf("%s%s",
- state.GetRejectReason(),
- state.GetDebugMessage().empty() ? "" : ", "+state.GetDebugMessage());
-}
-
-const std::string strMessageMagic = "Bitcoin Signed Message:\n";
diff --git a/src/util/validation.h b/src/util/validation.h
deleted file mode 100644
index da2cf9f102..0000000000
--- a/src/util/validation.h
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2019 The Bitcoin Core developers
-// Distributed under the MIT software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-#ifndef BITCOIN_UTIL_VALIDATION_H
-#define BITCOIN_UTIL_VALIDATION_H
-
-#include <string>
-
-class ValidationState;
-
-/** Convert ValidationState to a human-readable message for logging */
-std::string FormatStateMessage(const ValidationState &state);
-
-extern const std::string strMessageMagic;
-
-#endif // BITCOIN_UTIL_VALIDATION_H