aboutsummaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/util')
-rw-r--r--src/util/asmap.cpp44
-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.cpp26
-rw-r--r--src/util/moneystr.h4
-rw-r--r--src/util/strencodings.cpp12
-rw-r--r--src/util/strencodings.h6
-rw-r--r--src/util/string.h16
-rw-r--r--src/util/system.cpp42
-rw-r--r--src/util/system.h4
-rw-r--r--src/util/time.cpp43
-rw-r--r--src/util/time.h6
-rw-r--r--src/util/url.h6
-rw-r--r--src/util/validation.cpp25
-rw-r--r--src/util/validation.h18
17 files changed, 279 insertions, 145 deletions
diff --git a/src/util/asmap.cpp b/src/util/asmap.cpp
index ac230e9ee5..5354cdb962 100644
--- a/src/util/asmap.cpp
+++ b/src/util/asmap.cpp
@@ -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.
@@ -8,13 +8,14 @@
namespace {
-uint32_t DecodeBits(std::vector<bool>::const_iterator& bitpos, uint8_t minval, const std::vector<uint8_t> &bit_sizes)
+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 {
@@ -24,6 +25,7 @@ uint32_t DecodeBits(std::vector<bool>::const_iterator& bitpos, uint8_t minval, c
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);
@@ -35,29 +37,29 @@ uint32_t DecodeBits(std::vector<bool>::const_iterator& bitpos, uint8_t minval, c
}
const std::vector<uint8_t> TYPE_BIT_SIZES{0, 0, 1};
-uint32_t DecodeType(std::vector<bool>::const_iterator& bitpos)
+uint32_t DecodeType(std::vector<bool>::const_iterator& bitpos, const std::vector<bool>::const_iterator& endpos)
{
- return DecodeBits(bitpos, 0, TYPE_BIT_SIZES);
+ 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)
+uint32_t DecodeASN(std::vector<bool>::const_iterator& bitpos, const std::vector<bool>::const_iterator& endpos)
{
- return DecodeBits(bitpos, 1, ASN_BIT_SIZES);
+ 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)
+uint32_t DecodeMatch(std::vector<bool>::const_iterator& bitpos, const std::vector<bool>::const_iterator& endpos)
{
- return DecodeBits(bitpos, 2, MATCH_BIT_SIZES);
+ 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)
+uint32_t DecodeJump(std::vector<bool>::const_iterator& bitpos, const std::vector<bool>::const_iterator& endpos)
{
- return DecodeBits(bitpos, 17, JUMP_BIT_SIZES);
+ return DecodeBits(bitpos, endpos, 17, JUMP_BIT_SIZES);
}
}
@@ -65,33 +67,37 @@ uint32_t DecodeJump(std::vector<bool>::const_iterator& bitpos)
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();
- uint8_t default_asn = 0;
+ uint32_t default_asn = 0;
uint32_t opcode, jump, match, matchlen;
- while (1) {
- assert(pos != asmap.end());
- opcode = DecodeType(pos);
+ while (pos != endpos) {
+ opcode = DecodeType(pos, endpos);
if (opcode == 0) {
- return DecodeASN(pos);
+ return DecodeASN(pos, endpos);
} else if (opcode == 1) {
- jump = DecodeJump(pos);
+ 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);
+ 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);
+ default_asn = DecodeASN(pos, endpos);
} else {
- assert(0);
+ break;
}
}
+ return 0; // 0 is not a valid ASN
}
diff --git a/src/util/bip32.cpp b/src/util/bip32.cpp
index 6f176dd5ec..4c7e948368 100644
--- a/src/util/bip32.cpp
+++ b/src/util/bip32.cpp
@@ -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.
diff --git a/src/util/bip32.h b/src/util/bip32.h
index 7e58b79f38..347e83db9e 100644
--- a/src/util/bip32.h
+++ b/src/util/bip32.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.
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..1bc8d02eab 100644
--- a/src/util/moneystr.cpp
+++ b/src/util/moneystr.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.
@@ -31,21 +31,19 @@ std::string FormatMoney(const CAmount& n)
}
-bool ParseMoney(const std::string& str, CAmount& nRet)
+bool ParseMoney(const std::string& money_string, CAmount& nRet)
{
- if (!ValidAsCString(str)) {
+ if (!ValidAsCString(money_string)) {
+ return false;
+ }
+ const std::string str = TrimString(money_string);
+ if (str.empty()) {
return false;
}
- return ParseMoney(str.c_str(), nRet);
-}
-bool ParseMoney(const char* pszIn, CAmount& nRet)
-{
std::string strWhole;
int64_t nUnits = 0;
- const char* p = pszIn;
- while (IsSpace(*p))
- p++;
+ const char* p = str.c_str();
for (; *p; p++)
{
if (*p == '.')
@@ -60,14 +58,14 @@ bool ParseMoney(const char* pszIn, CAmount& nRet)
break;
}
if (IsSpace(*p))
- break;
+ return false;
if (!IsDigit(*p))
return false;
strWhole.insert(strWhole.end(), *p);
}
- for (; *p; p++)
- if (!IsSpace(*p))
- return false;
+ if (*p) {
+ return false;
+ }
if (strWhole.size() > 10) // guard against 63 bit overflow
return false;
if (nUnits < 0 || nUnits > COIN)
diff --git a/src/util/moneystr.h b/src/util/moneystr.h
index 027c7e2e53..9d2b6da0fc 100644
--- a/src/util/moneystr.h
+++ b/src/util/moneystr.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.
@@ -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/strencodings.cpp b/src/util/strencodings.cpp
index eec1a52e95..3a903b6897 100644
--- a/src/util/strencodings.cpp
+++ b/src/util/strencodings.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.
@@ -407,16 +407,6 @@ std::string FormatParagraph(const std::string& in, size_t width, size_t indent)
return out.str();
}
-std::string i64tostr(int64_t n)
-{
- return strprintf("%d", n);
-}
-
-std::string itostr(int n)
-{
- return strprintf("%d", n);
-}
-
int64_t atoi64(const char* psz)
{
#ifdef _MSC_VER
diff --git a/src/util/strencodings.h b/src/util/strencodings.h
index ccc4edac12..bd988f1410 100644
--- a/src/util/strencodings.h
+++ b/src/util/strencodings.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.
@@ -54,9 +54,7 @@ std::string DecodeBase32(const std::string& str, bool* pf_invalid = nullptr);
std::string EncodeBase32(const unsigned char* pch, size_t len);
std::string EncodeBase32(const std::string& str);
-void SplitHostPort(std::string in, int &portOut, std::string &hostOut);
-std::string i64tostr(int64_t n);
-std::string itostr(int n);
+void SplitHostPort(std::string in, int& portOut, std::string& hostOut);
int64_t atoi64(const char* psz);
int64_t atoi64(const std::string& str);
int atoi(const std::string& str);
diff --git a/src/util/string.h b/src/util/string.h
index 3db8fc8b98..b8e2a06235 100644
--- a/src/util/string.h
+++ b/src/util/string.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.
@@ -8,6 +8,8 @@
#include <attributes.h>
#include <cstring>
+#include <locale>
+#include <sstream>
#include <string>
#include <vector>
@@ -52,4 +54,16 @@ NODISCARD inline bool ValidAsCString(const std::string& str) noexcept
return str.size() == strlen(str.c_str());
}
+/**
+ * Locale-independent version of std::to_string
+ */
+template <typename T>
+std::string ToString(const T& t)
+{
+ std::ostringstream oss;
+ oss.imbue(std::locale::classic());
+ oss << t;
+ return oss.str();
+}
+
#endif // BITCOIN_UTIL_STRENCODINGS_H
diff --git a/src/util/system.cpp b/src/util/system.cpp
index ff3967c577..69a7be96dc 100644
--- a/src/util/system.cpp
+++ b/src/util/system.cpp
@@ -63,6 +63,7 @@
#include <malloc.h>
#endif
+#include <boost/algorithm/string/replace.hpp>
#include <thread>
#include <typeinfo>
#include <univalue.h>
@@ -225,10 +226,11 @@ static bool CheckValid(const std::string& key, const util::SettingsValue& val, u
return true;
}
-ArgsManager::ArgsManager()
-{
- // nothing to do
-}
+// Define default constructor and destructor that are not inline, so code instantiating this class doesn't need to
+// #include class definitions for all members.
+// For example, m_settings has an internal dependency on univalue.
+ArgsManager::ArgsManager() {}
+ArgsManager::~ArgsManager() {}
const std::set<std::string> ArgsManager::GetUnsuitableSectionOnlyArgs() const
{
@@ -312,21 +314,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
@@ -1050,6 +1049,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 bb69181de9..96f51e6074 100644
--- a/src/util/system.h
+++ b/src/util/system.h
@@ -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
@@ -189,6 +192,7 @@ protected:
public:
ArgsManager();
+ ~ArgsManager();
/**
* Select the network in use
diff --git a/src/util/time.cpp b/src/util/time.cpp
index 2afff2626b..e96972fe12 100644
--- a/src/util/time.cpp
+++ b/src/util/time.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.
@@ -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,43 +75,29 @@ 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);
+#ifdef HAVE_GMTIME_R
+ if (gmtime_r(&time_val, &ts) == nullptr) {
#else
- gmtime_r(&time_val, &ts);
+ if (gmtime_s(&ts, &time_val) != 0) {
#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);
}
std::string FormatISO8601Date(int64_t nTime) {
struct tm ts;
time_t time_val = nTime;
-#ifdef _MSC_VER
- gmtime_s(&ts, &time_val);
+#ifdef HAVE_GMTIME_R
+ if (gmtime_r(&time_val, &ts) == nullptr) {
#else
- gmtime_r(&time_val, &ts);
+ if (gmtime_s(&ts, &time_val) != 0) {
#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..b00c25f67c 100644
--- a/src/util/time.h
+++ b/src/util/time.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.
@@ -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/url.h b/src/util/url.h
index e9ea2ab765..5a7b11fa04 100644
--- a/src/util/url.h
+++ b/src/util/url.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2019 The Bitcoin Core developers
+// Copyright (c) 2015-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.
@@ -7,6 +7,8 @@
#include <string>
-std::string urlDecode(const std::string &urlEncoded);
+using UrlDecodeFn = std::string(const std::string& url_encoded);
+UrlDecodeFn urlDecode;
+extern UrlDecodeFn* const URL_DECODE;
#endif // BITCOIN_UTIL_URL_H
diff --git a/src/util/validation.cpp b/src/util/validation.cpp
deleted file mode 100644
index 89bc6665a4..0000000000
--- a/src/util/validation.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-// 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 <util/validation.h>
-
-#include <consensus/validation.h>
-#include <tinyformat.h>
-
-std::string FormatStateMessage(const ValidationState &state)
-{
- if (state.IsValid()) {
- return "Valid";
- }
-
- const std::string debug_message = state.GetDebugMessage();
- if (!debug_message.empty()) {
- return strprintf("%s, %s", state.GetRejectReason(), debug_message);
- }
-
- return state.GetRejectReason();
-}
-
-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