diff options
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/asmap.cpp | 6 | ||||
-rw-r--r-- | src/util/hash_type.h | 72 | ||||
-rw-r--r-- | src/util/sock.cpp | 4 | ||||
-rw-r--r-- | src/util/sock.h | 29 | ||||
-rw-r--r-- | src/util/strencodings.cpp | 11 | ||||
-rw-r--r-- | src/util/system.cpp | 25 | ||||
-rw-r--r-- | src/util/system.h | 50 | ||||
-rw-r--r-- | src/util/thread.cpp | 27 | ||||
-rw-r--r-- | src/util/thread.h | 18 |
9 files changed, 173 insertions, 69 deletions
diff --git a/src/util/asmap.cpp b/src/util/asmap.cpp index bd77d74218..bacc3690a2 100644 --- a/src/util/asmap.cpp +++ b/src/util/asmap.cpp @@ -93,8 +93,7 @@ uint32_t Interpret(const std::vector<bool> &asmap, const std::vector<bool> &ip) jump = DecodeJump(pos, endpos); if (jump == INVALID) break; // Jump offset straddles EOF if (bits == 0) break; // No input bits left - if (pos + jump < pos) break; // overflow - if (pos + jump >= endpos) break; // Jumping past EOF + if (int64_t{jump} >= int64_t{endpos - pos}) break; // Jumping past EOF if (ip[ip.size() - bits]) { pos += jump; } @@ -156,8 +155,7 @@ bool SanityCheckASMap(const std::vector<bool>& asmap, int bits) } else if (opcode == Instruction::JUMP) { uint32_t jump = DecodeJump(pos, endpos); if (jump == INVALID) return false; // Jump offset straddles EOF - if (pos + jump < pos) return false; // overflow - if (pos + jump > endpos) return false; // Jump out of range + if (int64_t{jump} > int64_t{endpos - pos}) return false; // Jump out of range if (bits == 0) return false; // Consuming bits past the end of the input --bits; uint32_t jump_offset = pos - begin + jump; diff --git a/src/util/hash_type.h b/src/util/hash_type.h new file mode 100644 index 0000000000..13b831cf19 --- /dev/null +++ b/src/util/hash_type.h @@ -0,0 +1,72 @@ +// Copyright (c) 2020-2021 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_HASH_TYPE_H +#define BITCOIN_UTIL_HASH_TYPE_H + +template <typename HashType> +class BaseHash +{ +protected: + HashType m_hash; + +public: + BaseHash() : m_hash() {} + explicit BaseHash(const HashType& in) : m_hash(in) {} + + unsigned char* begin() + { + return m_hash.begin(); + } + + const unsigned char* begin() const + { + return m_hash.begin(); + } + + unsigned char* end() + { + return m_hash.end(); + } + + const unsigned char* end() const + { + return m_hash.end(); + } + + operator std::vector<unsigned char>() const + { + return std::vector<unsigned char>{m_hash.begin(), m_hash.end()}; + } + + std::string ToString() const + { + return m_hash.ToString(); + } + + bool operator==(const BaseHash<HashType>& other) const noexcept + { + return m_hash == other.m_hash; + } + + bool operator!=(const BaseHash<HashType>& other) const noexcept + { + return !(m_hash == other.m_hash); + } + + bool operator<(const BaseHash<HashType>& other) const noexcept + { + return m_hash < other.m_hash; + } + + size_t size() const + { + return m_hash.size(); + } + + unsigned char* data() { return m_hash.data(); } + const unsigned char* data() const { return m_hash.data(); } +}; + +#endif // BITCOIN_UTIL_HASH_TYPE_H diff --git a/src/util/sock.cpp b/src/util/sock.cpp index 0bc9795db3..b6c2a47434 100644 --- a/src/util/sock.cpp +++ b/src/util/sock.cpp @@ -179,7 +179,7 @@ void Sock::SendComplete(const std::string& data, // Wait for a short while (or the socket to become ready for sending) before retrying // if nothing was sent. const auto wait_time = std::min(deadline - now, std::chrono::milliseconds{MAX_WAIT_FOR_IO}); - Wait(wait_time, SEND); + (void)Wait(wait_time, SEND); } } @@ -262,7 +262,7 @@ std::string Sock::RecvUntilTerminator(uint8_t terminator, // Wait for a short while (or the socket to become ready for reading) before retrying. const auto wait_time = std::min(deadline - now, std::chrono::milliseconds{MAX_WAIT_FOR_IO}); - Wait(wait_time, RECV); + (void)Wait(wait_time, RECV); } } diff --git a/src/util/sock.h b/src/util/sock.h index a4df7cd21b..59cc8c0b1d 100644 --- a/src/util/sock.h +++ b/src/util/sock.h @@ -64,7 +64,7 @@ public: * Get the value of the contained socket. * @return socket or INVALID_SOCKET if empty */ - virtual SOCKET Get() const; + [[nodiscard]] virtual SOCKET Get() const; /** * Get the value of the contained socket and drop ownership. It will not be closed by the @@ -82,26 +82,29 @@ public: * send(2) wrapper. Equivalent to `send(this->Get(), data, len, flags);`. Code that uses this * wrapper can be unit tested if this method is overridden by a mock Sock implementation. */ - virtual ssize_t Send(const void* data, size_t len, int flags) const; + [[nodiscard]] virtual ssize_t Send(const void* data, size_t len, int flags) const; /** * recv(2) wrapper. Equivalent to `recv(this->Get(), buf, len, flags);`. Code that uses this * wrapper can be unit tested if this method is overridden by a mock Sock implementation. */ - virtual ssize_t Recv(void* buf, size_t len, int flags) const; + [[nodiscard]] virtual ssize_t Recv(void* buf, size_t len, int flags) const; /** * connect(2) wrapper. Equivalent to `connect(this->Get(), addr, addrlen)`. Code that uses this * wrapper can be unit tested if this method is overridden by a mock Sock implementation. */ - virtual int Connect(const sockaddr* addr, socklen_t addr_len) const; + [[nodiscard]] virtual int Connect(const sockaddr* addr, socklen_t addr_len) const; /** * getsockopt(2) wrapper. Equivalent to * `getsockopt(this->Get(), level, opt_name, opt_val, opt_len)`. Code that uses this * wrapper can be unit tested if this method is overridden by a mock Sock implementation. */ - virtual int GetSockOpt(int level, int opt_name, void* opt_val, socklen_t* opt_len) const; + [[nodiscard]] virtual int GetSockOpt(int level, + int opt_name, + void* opt_val, + socklen_t* opt_len) const; using Event = uint8_t; @@ -124,9 +127,9 @@ public: * value of `true` and `occurred` being set to 0. * @return true on success and false otherwise */ - virtual bool Wait(std::chrono::milliseconds timeout, - Event requested, - Event* occurred = nullptr) const; + [[nodiscard]] virtual bool Wait(std::chrono::milliseconds timeout, + Event requested, + Event* occurred = nullptr) const; /* Higher level, convenience, methods. These may throw. */ @@ -154,17 +157,17 @@ public: * @throws std::runtime_error if the operation cannot be completed. In this case some bytes may * have been consumed from the socket. */ - virtual std::string RecvUntilTerminator(uint8_t terminator, - std::chrono::milliseconds timeout, - CThreadInterrupt& interrupt, - size_t max_data) const; + [[nodiscard]] virtual std::string RecvUntilTerminator(uint8_t terminator, + std::chrono::milliseconds timeout, + CThreadInterrupt& interrupt, + size_t max_data) const; /** * Check if still connected. * @param[out] errmsg The error string, if the socket has been disconnected. * @return true if connected */ - virtual bool IsConnected(std::string& errmsg) const; + [[nodiscard]] virtual bool IsConnected(std::string& errmsg) const; protected: /** diff --git a/src/util/strencodings.cpp b/src/util/strencodings.cpp index 4734de3e0b..f514613f0d 100644 --- a/src/util/strencodings.cpp +++ b/src/util/strencodings.cpp @@ -593,13 +593,14 @@ std::string Capitalize(std::string str) std::string HexStr(const Span<const uint8_t> s) { - std::string rv; + std::string rv(s.size() * 2, '\0'); static constexpr char hexmap[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; - rv.reserve(s.size() * 2); - for (uint8_t v: s) { - rv.push_back(hexmap[v >> 4]); - rv.push_back(hexmap[v & 15]); + auto it = rv.begin(); + for (uint8_t v : s) { + *it++ = hexmap[v >> 4]; + *it++ = hexmap[v & 15]; } + assert(it == rv.end()); return rv; } diff --git a/src/util/system.cpp b/src/util/system.cpp index 9b3bd46b38..5b87806a45 100644 --- a/src/util/system.cpp +++ b/src/util/system.cpp @@ -366,14 +366,12 @@ bool ArgsManager::ParseParameters(int argc, const char* const argv[], std::strin } // we do not allow -includeconf from command line - bool success = true; if (auto* includes = util::FindKey(m_settings.command_line_options, "includeconf")) { - for (const auto& include : util::SettingsSpan(*includes)) { - error += "-includeconf cannot be used from commandline; -includeconf=" + include.get_str() + "\n"; - success = false; - } + const auto& include{*util::SettingsSpan(*includes).begin()}; // pick first value as example + error = "-includeconf cannot be used from commandline; -includeconf=" + include.write(); + return false; } - return success; + return true; } std::optional<unsigned int> ArgsManager::GetArgFlags(const std::string& name) const @@ -388,7 +386,7 @@ std::optional<unsigned int> ArgsManager::GetArgFlags(const std::string& name) co return std::nullopt; } -const fs::path& ArgsManager::GetBlocksDirPath() +const fs::path& ArgsManager::GetBlocksDirPath() const { LOCK(cs_args); fs::path& path = m_cached_blocks_path; @@ -404,7 +402,7 @@ const fs::path& ArgsManager::GetBlocksDirPath() return path; } } else { - path = GetDataDirPath(false); + path = GetDataDirBase(); } path /= BaseParams().DataDir(); @@ -414,7 +412,7 @@ const fs::path& ArgsManager::GetBlocksDirPath() return path; } -const fs::path& ArgsManager::GetDataDirPath(bool net_specific) const +const fs::path& ArgsManager::GetDataDir(bool net_specific) const { LOCK(cs_args); fs::path& path = net_specific ? m_cached_network_datadir_path : m_cached_datadir_path; @@ -513,7 +511,7 @@ bool ArgsManager::GetSettingsPath(fs::path* filepath, bool temp) const } if (filepath) { std::string settings = GetArg("-settings", BITCOIN_SETTINGS_FILENAME); - *filepath = fsbridge::AbsPathJoin(GetDataDirPath(/* net_specific= */ true), temp ? settings + ".tmp" : settings); + *filepath = fsbridge::AbsPathJoin(GetDataDirNet(), temp ? settings + ".tmp" : settings); } return true; } @@ -802,11 +800,6 @@ fs::path GetDefaultDataDir() #endif } -const fs::path &GetDataDir(bool fNetSpecific) -{ - return gArgs.GetDataDirPath(fNetSpecific); -} - bool CheckDataDirOption() { std::string datadir = gArgs.GetArg("-datadir", ""); @@ -1361,7 +1354,7 @@ fs::path AbsPathForConfigVal(const fs::path& path, bool net_specific) if (path.is_absolute()) { return path; } - return fsbridge::AbsPathJoin(GetDataDir(net_specific), path); + return fsbridge::AbsPathJoin(net_specific ? gArgs.GetDataDirNet() : gArgs.GetDataDirBase(), path); } void ScheduleBatchPriority() diff --git a/src/util/system.h b/src/util/system.h index 61f862c93a..c4317c62d0 100644 --- a/src/util/system.h +++ b/src/util/system.h @@ -22,7 +22,6 @@ #include <sync.h> #include <tinyformat.h> #include <util/settings.h> -#include <util/threadnames.h> #include <util/time.h> #include <any> @@ -91,7 +90,6 @@ void ReleaseDirectoryLocks(); bool TryCreateDirectories(const fs::path& p); fs::path GetDefaultDataDir(); -const fs::path &GetDataDir(bool fNetSpecific = true); // Return true if -datadir option points to a valid directory or is not specified. bool CheckDataDirOption(); fs::path GetConfigFile(const std::string& confPath); @@ -120,7 +118,7 @@ UniValue RunCommandParseJSON(const std::string& str_command, const std::string& * the datadir if they are not absolute. * * @param path The path to be conditionally prefixed with datadir. - * @param net_specific Forwarded to GetDataDir(). + * @param net_specific Use network specific datadir variant * @return The normalized path. */ fs::path AbsPathForConfigVal(const fs::path& path, bool net_specific = true); @@ -196,7 +194,7 @@ protected: std::map<OptionsCategory, std::map<std::string, Arg>> m_available_args GUARDED_BY(cs_args); bool m_accept_any_command GUARDED_BY(cs_args){true}; std::list<SectionInfo> m_config_sections GUARDED_BY(cs_args); - fs::path m_cached_blocks_path GUARDED_BY(cs_args); + mutable fs::path m_cached_blocks_path GUARDED_BY(cs_args); mutable fs::path m_cached_datadir_path GUARDED_BY(cs_args); mutable fs::path m_cached_network_datadir_path GUARDED_BY(cs_args); @@ -267,16 +265,23 @@ public: * * @return Blocks path which is network specific */ - const fs::path& GetBlocksDirPath(); + const fs::path& GetBlocksDirPath() const; /** * Get data directory path * - * @param net_specific Append network identifier to the returned path * @return Absolute path on success, otherwise an empty path when a non-directory path would be returned * @post Returned directory path is created unless it is empty */ - const fs::path& GetDataDirPath(bool net_specific = true) const; + const fs::path& GetDataDirBase() const { return GetDataDir(false); } + + /** + * Get data directory path with appended network identifier + * + * @return Absolute path on success, otherwise an empty path when a non-directory path would be returned + * @post Returned directory path is created unless it is empty + */ + const fs::path& GetDataDirNet() const { return GetDataDir(true); } /** * Clear cached directory paths @@ -438,6 +443,15 @@ public: void LogArgs() const; private: + /** + * Get data directory path + * + * @param net_specific Append network identifier to the returned path + * @return Absolute path on success, otherwise an empty path when a non-directory path would be returned + * @post Returned directory path is created unless it is empty + */ + const fs::path& GetDataDir(bool net_specific) const; + // Helper function for LogArgs(). void logArgsPrefix( const std::string& prefix, @@ -478,28 +492,6 @@ std::string HelpMessageOpt(const std::string& option, const std::string& message */ int GetNumCores(); -/** - * .. and a wrapper that just calls func once - */ -template <typename Callable> void TraceThread(const char* name, Callable func) -{ - util::ThreadRename(name); - try - { - LogPrintf("%s thread start\n", name); - func(); - LogPrintf("%s thread exit\n", name); - } - catch (const std::exception& e) { - PrintExceptionContinue(&e, name); - throw; - } - catch (...) { - PrintExceptionContinue(nullptr, name); - throw; - } -} - std::string CopyrightHolders(const std::string& strPrefix); /** diff --git a/src/util/thread.cpp b/src/util/thread.cpp new file mode 100644 index 0000000000..14be668685 --- /dev/null +++ b/src/util/thread.cpp @@ -0,0 +1,27 @@ +// Copyright (c) 2021 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/thread.h> + +#include <logging.h> +#include <util/system.h> +#include <util/threadnames.h> + +#include <exception> + +void util::TraceThread(const char* thread_name, std::function<void()> thread_func) +{ + util::ThreadRename(thread_name); + try { + LogPrintf("%s thread start\n", thread_name); + thread_func(); + LogPrintf("%s thread exit\n", thread_name); + } catch (const std::exception& e) { + PrintExceptionContinue(&e, thread_name); + throw; + } catch (...) { + PrintExceptionContinue(nullptr, thread_name); + throw; + } +} diff --git a/src/util/thread.h b/src/util/thread.h new file mode 100644 index 0000000000..ca2eccc0c3 --- /dev/null +++ b/src/util/thread.h @@ -0,0 +1,18 @@ +// Copyright (c) 2021 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_THREAD_H +#define BITCOIN_UTIL_THREAD_H + +#include <functional> + +namespace util { +/** + * A wrapper for do-something-once thread functions. + */ +void TraceThread(const char* thread_name, std::function<void()> thread_func); + +} // namespace util + +#endif // BITCOIN_UTIL_THREAD_H |