From a6a63475f53896fe045b3a9ca71a93efdeaa485d Mon Sep 17 00:00:00 2001 From: Naviabheeman Date: Tue, 26 Nov 2024 17:12:11 +0530 Subject: [PATCH 01/10] fix boost::filesystem deprecated warnings in many functions and make it compatible with fs::filesystem remove IsDirWritable(like bitcoin) and update LocKDirectory to capture that status also. port LockResult for directory locking from bitcoin. update its tests remove unused variables across files --- src/dbwrapper.cpp | 2 +- src/init.cpp | 17 +++++++----- src/logging.cpp | 5 ++-- src/random.cpp | 2 -- src/sync.h | 3 +- src/util.cpp | 60 +++++++++++++++++++--------------------- src/util.h | 12 ++++++-- src/validation.cpp | 58 ++++++++++++++------------------------ src/wallet/db.cpp | 35 +++++++++++------------ src/wallet/db.h | 4 +-- src/wallet/init.cpp | 6 ++-- src/wallet/rpcdump.cpp | 49 +++++++++++++++++++++----------- src/wallet/rpcwallet.cpp | 12 ++++---- src/wallet/wallet.cpp | 18 ++++-------- 14 files changed, 144 insertions(+), 139 deletions(-) diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp index f5fb715800..3754a00f5f 100644 --- a/src/dbwrapper.cpp +++ b/src/dbwrapper.cpp @@ -115,7 +115,7 @@ static leveldb::Options GetOptions(size_t nCacheSize) } CDBWrapper::CDBWrapper(const fs::path& path, size_t nCacheSize, bool fMemory, bool fWipe, bool obfuscate) - : m_name(fs::basename(path)) + : m_name(path.stem().string()) { penv = nullptr; readoptions.verify_checksums = true; diff --git a/src/init.cpp b/src/init.cpp index 4292077369..80c7943806 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1135,14 +1135,17 @@ bool AppInitParameterInteraction() static bool LockDataDirectory(bool probeOnly) { - // Make sure only a single Bitcoin process is using the data directory. + // Make sure only a single Tapyrus process is using the data directory. fs::path datadir = GetDataDir(); - if (!DirIsWritable(datadir)) { - return InitError(strprintf(_("Cannot write to data directory '%s'; check permissions."), datadir.string())); - } - if (!LockDirectory(datadir, ".lock", probeOnly)) { - return InitError(strprintf(_("Cannot obtain a lock on data directory %s. %s is probably already running."), datadir.string(), _(PACKAGE_NAME))); - } + switch(LockDirectory(datadir, ".lock", probeOnly)) + { + case LockResult::ErrorWrite: + return InitError(strprintf(_("Cannot write to data directory '%s'; check permissions."), datadir.string())); + case LockResult::ErrorLock: + return InitError(strprintf(_("Cannot obtain a lock on data directory %s. %s is probably already running."), datadir.string(), CLIENT_NAME)); + case LockResult::Success: + return true; + } // no default case, so the compiler can warn about missing cases return true; } diff --git a/src/logging.cpp b/src/logging.cpp index 3d03068777..3674ff8a18 100644 --- a/src/logging.cpp +++ b/src/logging.cpp @@ -37,7 +37,8 @@ bool BCLog::Logger::OpenDebugLog() assert(m_fileout == nullptr); assert(!m_file_path.empty()); - m_fileout = fsbridge::fopen(m_file_path, "a"); + char mode = fs::exists(m_file_path) && fs::is_regular_file(m_file_path) ? 'a' : 'w'; + m_fileout = fsbridge::fopen(m_file_path, &mode); if (!m_fileout) { return false; } @@ -245,7 +246,7 @@ void BCLog::Logger::ShrinkDebugFile() size_t log_size = 0; try { log_size = fs::file_size(m_file_path); - } catch (boost::filesystem::filesystem_error &) {} + } catch (fs::filesystem_error &) {} // If debug.log file is more than 10% bigger the RECENT_DEBUG_HISTORY_SIZE // trim it down by saving only the last RECENT_DEBUG_HISTORY_SIZE bytes diff --git a/src/random.cpp b/src/random.cpp index c9a31ed149..2d870544b4 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -534,12 +534,10 @@ static void SeedStartup(CSHA512& hasher, RNGState& rng) noexcept SeedSlow(hasher, rng); // Dynamic environment data (performance monitoring, ...) - auto old_size = hasher.Size(); RandAddDynamicEnv(hasher); // Static environment data RandAddStaticEnv(hasher); - //LogPrint(BCLog::RAND, "Feeding %i bytes of environment data into RNG\n", hasher.Size() - old_size); // Strengthen for 100 ms SeedStrengthen(hasher, rng, 100000); diff --git a/src/sync.h b/src/sync.h index f02849424a..91d4fe3677 100644 --- a/src/sync.h +++ b/src/sync.h @@ -140,8 +140,7 @@ class SCOPED_LOCKABLE CCriticalBlock bool TryEnter(const char* pszName, const char* pszFile, int nLine) { EnterCritical(pszName, pszFile, nLine, (void*)(lock.mutex()), true); - lock.try_lock(); - if (!lock.owns_lock()) + if (!lock.try_lock()) LeaveCritical(); return lock.owns_lock(); } diff --git a/src/util.cpp b/src/util.cpp index 1929506d71..b3bcce7b4a 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -12,6 +12,7 @@ #include #include +#include #if (defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)) #include @@ -95,33 +96,45 @@ static std::mutex cs_dir_locks; */ static std::map> dir_locks; -bool LockDirectory(const fs::path& directory, const std::string lockfile_name, bool probe_only) +LockResult LockDirectory(const fs::path& directory, const std::string lockfile_name, bool probe_only) { std::lock_guard ulock(cs_dir_locks); fs::path pathLockFile = directory / lockfile_name; // If a lock for this directory already exists in the map, don't try to re-lock it if (dir_locks.count(pathLockFile.string())) { - return true; + return LockResult::Success;; } // Create empty lock file if it doesn't exist. FILE* file = fsbridge::fopen(pathLockFile, "a"); - if (file) fclose(file); - + if (file) { + fclose(file); + } else { + return LockResult::ErrorWrite; + } try { auto lock = MakeUnique(pathLockFile.string().c_str()); if (!lock->try_lock()) { - return false; + return LockResult::ErrorLock; } if (!probe_only) { // Lock successful and we're not just probing, put it into the map dir_locks.emplace(pathLockFile.string(), std::move(lock)); } } catch (const boost::interprocess::interprocess_exception& e) { - return error("Error while attempting to lock directory %s: %s", directory.string(), e.what()); + return LockResult::ErrorLock; + } + return LockResult::Success;; +} + +std::ostream& operator<<(std::ostream& os, const LockResult& result) { + switch (result) { + case LockResult::Success: return os << "Success"; + case LockResult::ErrorWrite: return os << "ErrorWrite"; + case LockResult::ErrorLock: return os << "ErrorLock"; + default: return os << "Unknown"; } - return true; } void ReleaseDirectoryLocks() @@ -130,18 +143,6 @@ void ReleaseDirectoryLocks() dir_locks.clear(); } -bool DirIsWritable(const fs::path& directory) -{ - fs::path tmpFile = directory / fs::unique_path(); - - FILE* file = fsbridge::fopen(tmpFile, "a"); - if (!file) return false; - - fclose(file); - remove(tmpFile); - - return true; -} /** * Interpret a string argument as a boolean. @@ -718,7 +719,7 @@ const fs::path &GetBlocksDir() return path; if (gArgs.IsArgSet("-blocksdir")) { - path = fs::system_complete(gArgs.GetArg("-blocksdir", "")); + path = fs::absolute(gArgs.GetArg("-blocksdir", "")); if (!fs::is_directory(path)) { path = ""; return path; @@ -747,7 +748,7 @@ const fs::path &GetDataDir(bool fNetSpecific) return path; if (gArgs.IsArgSet("-datadir")) { - path = fs::system_complete(gArgs.GetArg("-datadir", "")); + path = fs::absolute(gArgs.GetArg("-datadir", "")); if (!fs::is_directory(path)) { path = ""; return path; @@ -862,7 +863,7 @@ bool ArgsManager::ReadConfigFiles(std::string& error, bool ignore_invalid_keys) } const std::string confPath = GetArg("-conf", BITCOIN_CONF_FILENAME); - fs::ifstream stream(GetConfigFile(confPath)); + std::ifstream stream(GetConfigFile(confPath).string()); // ok to not have a config file if (stream.good()) { @@ -891,7 +892,7 @@ bool ArgsManager::ReadConfigFiles(std::string& error, bool ignore_invalid_keys) for (const std::string& to_include : includeconf) { - fs::ifstream include_config(GetConfigFile(to_include)); + std::ifstream include_config(GetConfigFile(to_include).string()); if (include_config.good()) { if (!ReadConfigStream(include_config, error, ignore_invalid_keys)) { return false; @@ -1178,12 +1179,6 @@ void SetupEnvironment() setenv("LC_ALL", "C", 1); } #endif - // The path locale is lazy initialized and to avoid deinitialization errors - // in multithreading environments, it is set explicitly by the main thread. - // A dummy locale is used to extract the internal default locale, used by - // fs::path, which is then used to explicitly imbue the path. - std::locale loc = fs::path::imbue(std::locale::classic()); - fs::path::imbue(loc); } bool SetupNetworking() @@ -1220,9 +1215,12 @@ int64_t GetStartupTime() return nStartupTime; } -fs::path AbsPathForConfigVal(const fs::path& path, bool net_specific) +fs::path AbsPathForConfigVal(const fs::path& in_path, bool net_specific) { - return fs::absolute(path, GetDataDir(net_specific)); + if (in_path.is_absolute()) { + return in_path; + } + return fs::absolute(( GetDataDir(net_specific) / in_path)); } int ScheduleBatchPriority(void) diff --git a/src/util.h b/src/util.h index 37dcf0a46c..8245bc020b 100644 --- a/src/util.h +++ b/src/util.h @@ -77,8 +77,16 @@ bool TruncateFile(FILE *file, unsigned int length); int RaiseFileDescriptorLimit(int nMinFD); void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length); bool RenameOver(fs::path src, fs::path dest); -bool LockDirectory(const fs::path& directory, const std::string lockfile_name, bool probe_only=false); -bool DirIsWritable(const fs::path& directory); + +enum class LockResult { + Success, + ErrorWrite, + ErrorLock, +}; +// Define operator<< for LockResult +std::ostream& operator<<(std::ostream& os, const LockResult& result); + +LockResult LockDirectory(const fs::path& directory, const std::string lockfile_name, bool probe_only=false); /** Release all directory locks. This is used for unit testing only, at runtime * the global destructor will take care of the locks. diff --git a/src/validation.cpp b/src/validation.cpp index 86b9bca8cf..b6e24b37c3 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -61,28 +61,26 @@ /** * Global state */ -namespace { - struct CBlockIndexWorkComparator - { - bool operator()(const CBlockIndex *pa, const CBlockIndex *pb) const { - // First sort by most total work, ... - if (pa->nHeight > pb->nHeight) return false; - if (pa->nHeight < pb->nHeight) return true; +struct CBlockIndexWorkComparator +{ + bool operator()(const CBlockIndex *pa, const CBlockIndex *pb) const { + // First sort by most total work, ... + if (pa->nHeight > pb->nHeight) return false; + if (pa->nHeight < pb->nHeight) return true; - // ... then by earliest time received, ... - if (pa->nSequenceId < pb->nSequenceId) return false; - if (pa->nSequenceId > pb->nSequenceId) return true; + // ... then by earliest time received, ... + if (pa->nSequenceId < pb->nSequenceId) return false; + if (pa->nSequenceId > pb->nSequenceId) return true; - // Use pointer address as tie breaker (should only happen with blocks - // loaded from disk, as those all have id 0). - if (pa < pb) return false; - if (pa > pb) return true; + // Use pointer address as tie breaker (should only happen with blocks + // loaded from disk, as those all have id 0). + if (pa < pb) return false; + if (pa > pb) return true; - // Identical blocks. - return false; - } - }; -} // anon namespace + // Identical blocks. + return false; + } +}; enum DisconnectResult { @@ -1151,11 +1149,12 @@ bool AcceptToMemoryPool(const CTransactionRef &tx, CTxMempoolAcceptanceOptions& bool res = AcceptToMemoryPoolWorker(tx, opt); if (!res) { for (const COutPoint& hashTx : opt.coins_to_uncache) + { pcoinsTip->Uncache(hashTx); TRACE2(mempool, rejected, tx->GetHashMalFix().begin(), - opt.state.GetRejectReason().c_str() - ); + opt.state.GetRejectReason().c_str()); + } } // After we've (potentially) uncached entries, ensure our coins cache is still within its size limits CValidationState stateDummy; @@ -2210,23 +2209,6 @@ void PruneAndFlush() { } } -static void DoWarning(const std::string& strWarning) -{ - static bool fWarned = false; - SetMiscWarning(strWarning); - if (!fWarned) { - AlertNotify(strWarning); - fWarned = true; - } -} - -/** Private helper function that concatenates warning messages. */ -static void AppendWarning(std::string& res, const std::string& warn) -{ - if (!res.empty()) res += ", "; - res += warn; -} - /** Check warning conditions and do some notifications on new chain tip set. */ void static UpdateTip(const CBlockIndex *pindexNew) { diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index 1eec93a697..d1d24d4341 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -56,7 +56,7 @@ RecursiveMutex cs_db; std::map g_dbenvs GUARDED_BY(cs_db); //!< Map from directory name to open db environment. } // namespace -BerkeleyEnvironment* GetWalletEnv(const fs::path& wallet_path, std::string& database_filename) +BerkeleyEnvironment* GetWalletEnv(const fs::path& wallet_path, fs::path& database_filename) { fs::path env_directory; if (fs::is_regular_file(wallet_path)) { @@ -131,7 +131,8 @@ bool BerkeleyEnvironment::Open(bool retry) fs::path pathIn = strPath; TryCreateDirectories(pathIn); - if (!LockDirectory(pathIn, ".walletlock")) { + if (LockDirectory(pathIn, ".walletlock") != LockResult::Success) + { LogPrintf("Cannot obtain a lock on wallet directory %s. Another instance of tapyrus may be using it.\n", strPath); return false; } @@ -245,7 +246,7 @@ BerkeleyEnvironment::VerifyResult BerkeleyEnvironment::Verify(const std::string& bool BerkeleyBatch::Recover(const fs::path& file_path, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue), std::string& newFilename) { - std::string filename; + fs::path filename; BerkeleyEnvironment* env = GetWalletEnv(file_path, filename); // Recovery procedure: @@ -258,7 +259,7 @@ bool BerkeleyBatch::Recover(const fs::path& file_path, void *callbackDataIn, boo int64_t now = GetTime(); newFilename = strprintf("%s.%d.bak", filename, now); - int result = env->dbenv->dbrename(nullptr, filename.c_str(), nullptr, + int result = env->dbenv->dbrename(nullptr, filename.string().c_str(), nullptr, newFilename.c_str(), DB_AUTO_COMMIT); if (result == 0) LogPrintf("Renamed %s to %s\n", filename, newFilename); @@ -279,7 +280,7 @@ bool BerkeleyBatch::Recover(const fs::path& file_path, void *callbackDataIn, boo std::unique_ptr pdbCopy = MakeUnique(env->dbenv.get(), 0); int ret = pdbCopy->open(nullptr, // Txn pointer - filename.c_str(), // Filename + filename.string().c_str(), // Filename "main", // Logical db name DB_BTREE, // Database type DB_CREATE, // Flags @@ -314,7 +315,7 @@ bool BerkeleyBatch::Recover(const fs::path& file_path, void *callbackDataIn, boo bool BerkeleyBatch::VerifyEnvironment(const fs::path& file_path, std::string& errorStr) { - std::string walletFile; + fs::path walletFile; BerkeleyEnvironment* env = GetWalletEnv(file_path, walletFile); fs::path walletDir = env->Directory(); @@ -322,7 +323,7 @@ bool BerkeleyBatch::VerifyEnvironment(const fs::path& file_path, std::string& er LogPrintf("Using wallet %s\n", walletFile); // Wallet file must be a plain filename without a directory - if (walletFile != fs::basename(walletFile) + fs::extension(walletFile)) + if (walletFile != walletFile.stem().string() + walletFile.extension().string()) { errorStr = strprintf(_("Wallet %s resides outside wallet directory %s"), walletFile, walletDir.string()); return false; @@ -338,14 +339,14 @@ bool BerkeleyBatch::VerifyEnvironment(const fs::path& file_path, std::string& er bool BerkeleyBatch::VerifyDatabaseFile(const fs::path& file_path, std::string& warningStr, std::string& errorStr, BerkeleyEnvironment::recoverFunc_type recoverFunc) { - std::string walletFile; + fs::path walletFile; BerkeleyEnvironment* env = GetWalletEnv(file_path, walletFile); fs::path walletDir = env->Directory(); if (fs::exists(walletDir / walletFile)) { std::string backup_filename; - BerkeleyEnvironment::VerifyResult r = env->Verify(walletFile, recoverFunc, backup_filename); + BerkeleyEnvironment::VerifyResult r = env->Verify(walletFile.string(), recoverFunc, backup_filename); if (r == BerkeleyEnvironment::VerifyResult::RECOVER_OK) { warningStr = strprintf(_("Warning: Wallet file corrupt, data salvaged!" @@ -447,7 +448,7 @@ BerkeleyBatch::BerkeleyBatch(BerkeleyDatabase& database, const char* pszMode, bo if (database.IsDummy()) { return; } - const std::string &strFilename = database.strFile; + const std::string &strFilename = database.strFile.string(); bool fCreate = strchr(pszMode, 'c') != nullptr; unsigned int nFlags = DB_THREAD; @@ -574,7 +575,7 @@ bool BerkeleyBatch::Rewrite(BerkeleyDatabase& database, const char* pszSkip) return true; } BerkeleyEnvironment *env = database.env; - const std::string& strFile = database.strFile; + const std::string& strFile = database.strFile.string(); while (true) { { LOCK(cs_db); @@ -706,7 +707,7 @@ bool BerkeleyBatch::PeriodicFlush(BerkeleyDatabase& database) } bool ret = false; BerkeleyEnvironment *env = database.env; - const std::string& strFile = database.strFile; + const std::string& strFile = database.strFile.string(); TRY_LOCK(cs_db, lockDb); if (lockDb) { @@ -755,12 +756,12 @@ bool BerkeleyDatabase::Backup(const std::string& strDest) { { LOCK(cs_db); - if (!env->mapFileUseCount.count(strFile) || env->mapFileUseCount[strFile] == 0) + if (!env->mapFileUseCount.count(strFile.string()) || env->mapFileUseCount[strFile.string()] == 0) { // Flush log data to the dat file - env->CloseDb(strFile); - env->CheckpointLSN(strFile); - env->mapFileUseCount.erase(strFile); + env->CloseDb(strFile.string()); + env->CheckpointLSN(strFile.string()); + env->mapFileUseCount.erase(strFile.string()); // Copy wallet file fs::path pathSrc = env->Directory() / strFile; @@ -774,7 +775,7 @@ bool BerkeleyDatabase::Backup(const std::string& strDest) return false; } - fs::copy_file(pathSrc, pathDest, fs::copy_option::overwrite_if_exists); + fs::copy_file(pathSrc, pathDest, fs::copy_options::overwrite_existing); LogPrintf("copied %s to %s\n", strFile, pathDest.string()); return true; } catch (const fs::filesystem_error& e) { diff --git a/src/wallet/db.h b/src/wallet/db.h index b078edab7b..1de933c4ab 100644 --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -87,7 +87,7 @@ class BerkeleyEnvironment }; /** Get BerkeleyEnvironment and database filename given a wallet path. */ -BerkeleyEnvironment* GetWalletEnv(const fs::path& wallet_path, std::string& database_filename); +BerkeleyEnvironment* GetWalletEnv(const fs::path& wallet_path, fs::path& database_filename); /** An instance of this class represents one database. * For BerkeleyDB this is just a (env, strFile) tuple. @@ -153,7 +153,7 @@ class BerkeleyDatabase private: /** BerkeleyDB specific */ BerkeleyEnvironment *env; - std::string strFile; + fs::path strFile; /** Return whether this database handle is a dummy for testing. * Only to be used at a low level, application should ideally not care diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp index b1b904da94..07944c0893 100644 --- a/src/wallet/init.cpp +++ b/src/wallet/init.cpp @@ -201,7 +201,7 @@ bool WalletInit::Verify() const std::set wallet_paths; for (const auto& wallet_file : wallet_files) { - fs::path wallet_path = fs::absolute(wallet_file, GetWalletDir()); + fs::path wallet_path = fs::path(GetWalletDir() / fs::path(wallet_file)); if (!wallet_paths.insert(wallet_path).second) { return InitError(strprintf(_("Error loading wallet %s. Duplicate -wallet filename specified."), wallet_file)); @@ -226,7 +226,9 @@ bool WalletInit::Open() const } for (const std::string& walletFile : gArgs.GetArgs("-wallet")) { - std::shared_ptr pwallet = CWallet::CreateWalletFromFile(walletFile, fs::absolute(walletFile, GetWalletDir())); + fs::path wallet_path = fs::path(walletFile).is_absolute() ? fs::path(walletFile) : GetWalletDir() / fs::path(walletFile); + + std::shared_ptr pwallet = CWallet::CreateWalletFromFile(walletFile, wallet_path); if (!pwallet) { return false; } diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index b720b33e8d..7b42263ec7 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -21,23 +21,36 @@ #include #include -#include -#include - +#include #include int64_t static DecodeDumpTime(const std::string &str) { - static const boost::posix_time::ptime epoch = boost::posix_time::from_time_t(0); - static const std::locale loc(std::locale::classic(), - new boost::posix_time::time_input_facet("%Y-%m-%dT%H:%M:%SZ")); - std::istringstream iss(str); - iss.imbue(loc); - boost::posix_time::ptime ptime(boost::date_time::not_a_date_time); - iss >> ptime; - if (ptime.is_not_a_date_time()) + static const std::chrono::time_point epoch(std::chrono::seconds(0)); + + // Manually parse the input string "2024-11-15T10:30:00Z" + std::tm tm = {}; + if (str.size() != 20 || str[10] != 'T' || str[19] != 'Z') { + return 0; // Invalid format + } + try { + tm.tm_year = std::stoi(str.substr(0, 4)) - 1900; + tm.tm_mon = std::stoi(str.substr(5, 2)) - 1; + tm.tm_mday = std::stoi(str.substr(8, 2)); + tm.tm_hour = std::stoi(str.substr(11, 2)); + tm.tm_min = std::stoi(str.substr(14, 2)); + tm.tm_sec = std::stoi(str.substr(17, 2)); + } catch (const std::exception &) { + return 0; // Parsing failed + } + // Convert std::tm to time_t (seconds since epoch) + std::time_t t = std::mktime(&tm); + if (t == -1) { + // If mktime fails, return 0 return 0; - return (ptime - epoch).total_seconds(); + } + std::chrono::time_point ptime = std::chrono::system_clock::from_time_t(t); + return std::chrono::duration_cast(ptime - epoch).count(); } std::string static EncodeDumpString(const std::string &str) { @@ -561,7 +574,11 @@ UniValue importwallet(const JSONRPCRequest& request) continue; std::vector vstr; - boost::split(vstr, line, boost::is_any_of(" ")); + std::istringstream stream(line); + std::string word; + while (stream >> word) { + vstr.push_back(word); + } if (vstr.size() < 2) continue; CKey key = DecodeSecret(vstr[0]); @@ -705,15 +722,15 @@ UniValue dumpwallet(const JSONRPCRequest& request) EnsureWalletIsUnlocked(pwallet); - boost::filesystem::path filepath = request.params[0].get_str(); - filepath = boost::filesystem::absolute(filepath); + fs::path filepath = request.params[0].get_str(); + filepath = fs::absolute(filepath); /* Prevent arbitrary files from being overwritten. There have been reports * that users have overwritten wallet files this way: * https://github.com/bitcoin/bitcoin/issues/9934 * It may also avoid other security issues. */ - if (boost::filesystem::exists(filepath)) { + if (fs::exists(filepath)) { throw JSONRPCError(RPC_INVALID_PARAMETER, filepath.string() + " already exists. If you are sure this is what you want, move it out of the way first"); } diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 5554fd43ea..3f96c87bf4 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2508,7 +2508,8 @@ static UniValue loadwallet(const JSONRPCRequest& request) std::string wallet_file = request.params[0].get_str(); std::string error; - fs::path wallet_path = fs::absolute(wallet_file, GetWalletDir()); + fs::path wallet_path = fs::path(wallet_file).is_absolute() ? fs::path(wallet_file) : GetWalletDir() / fs::path(wallet_file); + if (fs::symlink_status(wallet_path).type() == fs::file_not_found) { throw JSONRPCError(RPC_WALLET_NOT_FOUND, "Wallet " + wallet_file + " not found."); } else if (fs::is_directory(wallet_path)) { @@ -2524,7 +2525,7 @@ static UniValue loadwallet(const JSONRPCRequest& request) throw JSONRPCError(RPC_WALLET_ERROR, "Wallet file verification failed: " + error); } - std::shared_ptr const wallet = CWallet::CreateWalletFromFile(wallet_file, fs::absolute(wallet_file, GetWalletDir())); + std::shared_ptr const wallet = CWallet::CreateWalletFromFile(wallet_file, wallet_path); if (!wallet) { throw JSONRPCError(RPC_WALLET_ERROR, "Wallet loading failed."); } @@ -2567,7 +2568,8 @@ static UniValue createwallet(const JSONRPCRequest& request) disable_privatekeys = request.params[1].get_bool(); } - fs::path wallet_path = fs::absolute(wallet_name, GetWalletDir()); + fs::path wallet_path = fs::path(wallet_name).is_absolute() ? fs::path(wallet_name) : GetWalletDir() / fs::path(wallet_name); + if (fs::symlink_status(wallet_path).type() != fs::file_not_found) { throw JSONRPCError(RPC_WALLET_ERROR, "Wallet " + wallet_name + " already exists."); } @@ -2577,7 +2579,7 @@ static UniValue createwallet(const JSONRPCRequest& request) throw JSONRPCError(RPC_WALLET_ERROR, "Wallet file verification failed: " + error); } - std::shared_ptr const wallet = CWallet::CreateWalletFromFile(wallet_name, fs::absolute(wallet_name, GetWalletDir()), (disable_privatekeys ? (uint64_t)WALLET_FLAG_DISABLE_PRIVATE_KEYS : 0)); + std::shared_ptr const wallet = CWallet::CreateWalletFromFile(wallet_name, wallet_path, (disable_privatekeys ? (uint64_t)WALLET_FLAG_DISABLE_PRIVATE_KEYS : 0)); if (!wallet) { throw JSONRPCError(RPC_WALLET_ERROR, "Wallet creation failed."); } @@ -4413,7 +4415,7 @@ static UniValue issuetoken(const JSONRPCRequest& request) } //2. vout and its type - if(vout < 0 || vout >= it->second.tx->vout.size() || GetColorIdFromScript(it->second.tx->vout[vout].scriptPubKey).type != TokenTypes::NONE) { + if(vout >= it->second.tx->vout.size() || GetColorIdFromScript(it->second.tx->vout[vout].scriptPubKey).type != TokenTypes::NONE) { std::string strError = strprintf("Invalid vout %d in tx: %s", request.params[3].get_int(), request.params[2].get_str()); throw JSONRPCError(RPC_INVALID_PARAMETER, strError); } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index d8631305c8..ee36e21965 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4027,11 +4027,12 @@ bool CWallet::Verify(std::string wallet_file, bool salvage_wallet, std::string& // 3. Path to a symlink to a directory. // 4. For backwards compatibility, the name of a data file in -walletdir. LOCK(cs_wallets); - fs::path wallet_path = fs::absolute(wallet_file, GetWalletDir()); + fs::path wallet_path = fs::path(GetWalletDir() / fs::path(wallet_file)); fs::file_type path_type = fs::symlink_status(wallet_path).type(); - if (!(path_type == fs::file_not_found || path_type == fs::directory_file || - (path_type == fs::symlink_file && fs::is_directory(wallet_path)) || - (path_type == fs::regular_file && fs::path(wallet_file).filename() == wallet_file))) { + if (!(path_type == fs::file_not_found || + path_type == fs::directory_file || + (path_type == fs::symlink_file && fs::is_directory(wallet_path)) || + (path_type == fs::regular_file && fs::path(wallet_file).filename() == wallet_file))) { error_string = strprintf( "Invalid -wallet path '%s'. -wallet path should point to a directory where wallet.dat and " "database/log.?????????? files can be stored, a location where such a directory could be created, " @@ -4042,7 +4043,7 @@ bool CWallet::Verify(std::string wallet_file, bool salvage_wallet, std::string& // Make sure that the wallet path doesn't clash with an existing wallet path for (auto wallet : GetWallets()) { - if (fs::absolute(wallet->GetName(), GetWalletDir()) == wallet_path) { + if (fs::path(GetWalletDir() / wallet->GetName()) == wallet_path) { error_string = strprintf("Error loading wallet %s. Duplicate -wallet filename specified.", wallet_file); return false; } @@ -4146,9 +4147,6 @@ std::shared_ptr CWallet::CreateWalletFromFile(const std::string& name, if (gArgs.GetBoolArg("-upgradewallet", false)) { LOCK(walletInstance->cs_wallet); - // Do not upgrade versions to any version between HD_SPLIT and FEATURE_PRE_SPLIT_KEYPOOL unless already supporting HD_SPLIT - int max_version = walletInstance->nWalletVersion; - bool hd_upgrade = false; bool split_upgrade = false; if (walletInstance->CanSupportFeature(FEATURE_HD) && !walletInstance->IsHDEnabled()) { @@ -4224,10 +4222,6 @@ std::shared_ptr CWallet::CreateWalletFromFile(const std::string& name, return nullptr; } } - - walletInstance->m_default_address_type; - walletInstance->m_default_change_type; - if (gArgs.IsArgSet("-mintxfee")) { CAmount n = 0; if (!ParseMoney(gArgs.GetArg("-mintxfee", ""), n) || 0 == n) { From b473919d08ea6e28b33195787836cb18a2d7936d Mon Sep 17 00:00:00 2001 From: Naviabheeman Date: Tue, 26 Nov 2024 17:16:43 +0530 Subject: [PATCH 02/10] change memset usage in colored coin and other functions that gave warning move seed node list from federationparams to params and this list should be different for prod and test remove unused variables across files --- src/chainparams.cpp | 5 +++++ src/chainparams.h | 2 ++ src/coloridentifier.cpp | 2 +- src/federationparams.cpp | 6 ++---- src/federationparams.h | 2 -- src/interfaces/wallet.cpp | 2 +- src/net.cpp | 2 +- src/prevector.h | 21 ++++----------------- src/primitives/xfield.cpp | 14 ++++++++------ src/primitives/xfield.h | 16 +++++++++++----- src/protocol.cpp | 3 ++- src/qt/guiutil.cpp | 4 ++-- src/rpc/blockchain.cpp | 6 +++--- src/rpc/mining.cpp | 7 ------- src/rpc/rawtransaction.cpp | 2 +- src/rpc/server.cpp | 1 - src/script/interpreter.cpp | 2 +- src/script/ismine.cpp | 1 + 18 files changed, 45 insertions(+), 53 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index dbbd117111..42b799def7 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -5,6 +5,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include +#include #include #include #include @@ -47,6 +48,8 @@ class CProductionChainParams : public CChainParams { /* disable fallback fee on mainnet */ m_fallback_fee_enabled = false; + vFixedSeeds = std::vector(pnSeed6_main, pnSeed6_main + ARRAYLEN(pnSeed6_main)); + } }; @@ -76,6 +79,8 @@ class CDevelopmentChainParams : public CChainParams { /* enable fallback fee on dev */ m_fallback_fee_enabled = true; + vFixedSeeds = std::vector(pnSeed6_test, pnSeed6_test + ARRAYLEN(pnSeed6_test)); + } }; diff --git a/src/chainparams.h b/src/chainparams.h index c91e2f28e6..74ca187e3b 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -72,6 +72,7 @@ class CChainParams const std::vector& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; } int GetRPCPort() const { return rpcPort; } int GetDefaultPort() const { return nDefaultPort; } + const std::vector& FixedSeeds() const { return vFixedSeeds; } protected: //require signedblockpubkey argument only in tapyrusd CChainParams() {} @@ -86,6 +87,7 @@ class CChainParams CCheckpointData checkpointData; ChainTxData chainTxData; bool m_fallback_fee_enabled; + std::vector vFixedSeeds; }; /** diff --git a/src/coloridentifier.cpp b/src/coloridentifier.cpp index 86488efe90..73fd905ff3 100644 --- a/src/coloridentifier.cpp +++ b/src/coloridentifier.cpp @@ -29,5 +29,5 @@ ColorIdentifier GetColorIdFromScript(const CScript& script) CKeyID CColorKeyID::getKeyID() const { - return std::move( CKeyID( uint160( std::vector(this->begin(), this->end())))); + return CKeyID( uint160( std::vector(this->begin(), this->end()))); } diff --git a/src/federationparams.cpp b/src/federationparams.cpp index 9eb1fb8348..b5964190c1 100644 --- a/src/federationparams.cpp +++ b/src/federationparams.cpp @@ -13,11 +13,11 @@ #include #include #include -#include #include #include #include +#include void SetupFederationParamsOptions() { @@ -35,7 +35,7 @@ std::string ReadGenesisBlock(fs::path genesisPath) genesisPath /= genesisFileName; LogPrintf("Reading Genesis Block from [%s]\n", genesisPath.string().c_str()); - fs::ifstream stream(genesisPath); + std::ifstream stream(genesisPath.string()); if (!stream.good()) throw std::runtime_error(strprintf("ReadGenesisBlock: unable to read genesis file %s", genesisPath)); @@ -142,8 +142,6 @@ CFederationParams::CFederationParams(const uint32_t networkId, const std::string this->ReadGenesisBlock(genesisHex); vSeeds = gArgs.GetArgs("-addseeder"); - - vFixedSeeds = std::vector(pnSeed6_main, pnSeed6_main + ARRAYLEN(pnSeed6_main)); } bool CFederationParams::ReadGenesisBlock(std::string genesisHex) diff --git a/src/federationparams.h b/src/federationparams.h index 9685d9b046..7188031265 100644 --- a/src/federationparams.h +++ b/src/federationparams.h @@ -36,7 +36,6 @@ class CFederationParams bool ReadGenesisBlock(std::string genesisHex); const CBlock& GenesisBlock() const { return genesis; } const std::string& getDataDir() const { return dataDir; } - const std::vector& FixedSeeds() const { return vFixedSeeds; } /** Return the list of hostnames to look up for DNS seeds */ const std::vector& DNSSeeds() const { return vSeeds; } @@ -50,7 +49,6 @@ class CFederationParams std::string dataDir; CBlock genesis; std::vector vSeeds; - std::vector vFixedSeeds; }; /** diff --git a/src/interfaces/wallet.cpp b/src/interfaces/wallet.cpp index 17f0f5d462..9ce3258077 100644 --- a/src/interfaces/wallet.cpp +++ b/src/interfaces/wallet.cpp @@ -233,7 +233,7 @@ class WalletImpl : public Wallet } change_pos = mapChangePosInOut[ColorIdentifier()]; - return std::move(pending); + return pending; } bool transactionCanBeAbandoned(const uint256& txid) override { return m_wallet.TransactionCanBeAbandoned(txid); } bool abandonTransaction(const uint256& txid) override diff --git a/src/net.cpp b/src/net.cpp index 4a3a1ac657..b81e3fa7ed 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1790,7 +1790,7 @@ void CConnman::ThreadOpenConnections(const std::vector connect) LogPrintf("Adding fixed seed nodes as DNS doesn't seem to be available.\n"); CNetAddr local; local.SetInternal("fixedseeds"); - addrman.Add(convertSeed6(FederationParams().FixedSeeds()), local); + addrman.Add(convertSeed6(Params().FixedSeeds()), local); done = true; } } diff --git a/src/prevector.h b/src/prevector.h index 033952c959..b3bd60bf9c 100644 --- a/src/prevector.h +++ b/src/prevector.h @@ -12,7 +12,7 @@ #include #include -#include +#include #include @@ -197,25 +197,12 @@ class prevector { T* item_ptr(difference_type pos) { return is_direct() ? direct_ptr(pos) : indirect_ptr(pos); } const T* item_ptr(difference_type pos) const { return is_direct() ? direct_ptr(pos) : indirect_ptr(pos); } - void fill(T* dst, ptrdiff_t count) { - if (IS_TRIVIALLY_CONSTRUCTIBLE::value) { - // The most common use of prevector is where T=unsigned char. For - // trivially constructible types, we can use memset() to avoid - // looping. - ::memset(dst, 0, count * sizeof(T)); - } else { - for (auto i = 0; i < count; ++i) { - new(static_cast(dst + i)) T(); - } - } - } - void fill(T* dst, ptrdiff_t count, const T& value) { - for (auto i = 0; i < count; ++i) { - new(static_cast(dst + i)) T(value); - } + void fill(T* dst, ptrdiff_t count, const T& value = T{}) { + std::fill_n(dst, count, value); } + template void fill(T* dst, InputIterator first, InputIterator last) { while (first != last) { diff --git a/src/primitives/xfield.cpp b/src/primitives/xfield.cpp index c2dbbfd5ee..364f10e9e8 100644 --- a/src/primitives/xfield.cpp +++ b/src/primitives/xfield.cpp @@ -61,10 +61,12 @@ char GetXFieldDBKey(const XFieldData& xfieldValue) { } } -const char* BadXFieldException::what() const noexcept -{ - if(unknown) - return strprintf("Upgrade node. Unknown xfield found in block. Node cannot sync to the blockchain with xfieldType=%s", std::to_string((uint8_t)type).c_str()).c_str(); - else - return strprintf("Type and data mismatch in CXField. xfieldType=%s xfieldValue=%s", std::to_string((uint8_t)type).c_str(), XFieldDataToString(xfieldValue).c_str()).c_str(); +void BadXFieldException::constructMessage(TAPYRUS_XFIELDTYPES type, XFieldData xfieldValue) { + std::ostringstream oss; + if (unknown) { + oss << "Upgrade node. Unknown xfield found in block. Node cannot sync to the blockchain with xfieldType=" << (uint8_t)type << std::endl; + } else { + oss << "Type and data mismatch in CXField. xfieldType=" << (uint8_t)type <<" expected =" << (uint8_t)GetXFieldTypeFrom(xfieldValue) << std::endl; + } + message = oss.str(); } \ No newline at end of file diff --git a/src/primitives/xfield.h b/src/primitives/xfield.h index ed86a9bbc9..02fa306aa1 100644 --- a/src/primitives/xfield.h +++ b/src/primitives/xfield.h @@ -136,16 +136,22 @@ inline TAPYRUS_XFIELDTYPES GetXFieldTypeFrom(XFieldData xfieldDataIn) { //Exception to identify xfield composition problems class BadXFieldException:public std::exception { - TAPYRUS_XFIELDTYPES type; - XFieldData xfieldValue; bool unknown; + std::string message; public: - explicit BadXFieldException(TAPYRUS_XFIELDTYPES type_in, XFieldData xfieldValue_in):type(type_in), xfieldValue(xfieldValue_in), unknown(false) { - if(!IsValid(type)) + explicit BadXFieldException(TAPYRUS_XFIELDTYPES type, XFieldData xfieldValue):unknown(false) { + if(!IsValid(type)) { unknown = true; + } + constructMessage(type, xfieldValue); + } + + const char* what() const noexcept override { + return message.c_str(); } - virtual const char* what() const noexcept; +private: + void constructMessage(TAPYRUS_XFIELDTYPES type, XFieldData xfieldValue); }; /* diff --git a/src/protocol.cpp b/src/protocol.cpp index 32035964c1..9054a04934 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -89,7 +89,8 @@ CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn, const { memcpy(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE); memset(pchCommand, 0, sizeof(pchCommand)); - strncpy(pchCommand, pszCommand, COMMAND_SIZE); + strncpy(pchCommand, pszCommand, COMMAND_SIZE-1); + pchCommand[COMMAND_SIZE-1] = '\0'; nMessageSize = nMessageSizeIn; memset(pchChecksum, 0, CHECKSUM_SIZE); } diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index c4e4cfb515..6eaf9042b4 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -369,10 +369,10 @@ void openDebugLogfile() bool openBitcoinConf() { - boost::filesystem::path pathConfig = GetConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME)); + fs::path pathConfig = GetConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME)); /* Create the file */ - boost::filesystem::ofstream configFile(pathConfig, std::ios_base::app); + fs::ofstream configFile(pathConfig, std::ios_base::app); if (!configFile.good()) return false; diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 43a8e8bb61..eaed86cec1 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -625,7 +625,7 @@ static UniValue getblockhash(const JSONRPCRequest& request) LOCK(cs_main); - uint32_t nHeight = request.params[0].get_int(); + int32_t nHeight = request.params[0].get_int(); if (nHeight < 0 || nHeight > chainActive.Height()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range"); @@ -2113,11 +2113,11 @@ static UniValue getcolor(const JSONRPCRequest& request) throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid transaction id :") + request.params[1].get_str()); } - uint8_t vout = request.params[2].get_int(); + int8_t vout = request.params[2].get_int(); COutPoint out(txid, vout); // check vout - if(vout < 0 || vout >= tx->vout.size() || GetColorIdFromScript(tx->vout[vout].scriptPubKey).type != TokenTypes::NONE) { + if(vout >= (int8_t)tx->vout.size() || GetColorIdFromScript(tx->vout[vout].scriptPubKey).type != TokenTypes::NONE) { std::string strError = strprintf("Invalid vout %d in tx: %s", request.params[2].get_int(), request.params[1].get_str()); throw JSONRPCError(RPC_INVALID_PARAMETER, strError); } diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 04821f199d..e09a06801e 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -364,7 +364,6 @@ static UniValue getblocktemplate(const JSONRPCRequest& request) std::string strMode = "template"; UniValue lpval = NullUniValue; std::set setClientRules; - int64_t nMaxVersionPreVB = -1; if (!request.params[0].isNull()) { const UniValue& oparam = request.params[0].get_obj(); @@ -414,12 +413,6 @@ static UniValue getblocktemplate(const JSONRPCRequest& request) const UniValue& v = aClientRules[i]; setClientRules.insert(v.get_str()); } - } else { - // NOTE: It is important that this NOT be read if versionbits is supported - const UniValue& uvMaxVersion = find_value(oparam, "maxversion"); - if (uvMaxVersion.isNum()) { - nMaxVersionPreVB = uvMaxVersion.get_int64(); - } } } diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index eaa82824c8..59cfa86ac8 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -1232,6 +1232,7 @@ static UniValue testmempoolaccept(const JSONRPCRequest& request) CTxMempoolAcceptanceOptions opt; opt.flags = MempoolAcceptanceFlags::TEST_ONLY; + opt.nAbsurdFee = max_raw_tx_fee; bool accept; { LOCK(cs_main); @@ -1710,7 +1711,6 @@ UniValue converttopsbt(const JSONRPCRequest& request) // parse hex string from parameter CMutableTransaction tx; - bool permitsigdata = request.params[1].isNull() ? false : request.params[1].get_bool(); if (!DecodeHexTx(tx, request.params[0].get_str())) { throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); } diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 07f24a78ba..37805ac6b3 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -517,7 +517,6 @@ UniValue CRPCTable::execute(const JSONRPCRequest &request) const std::vector CRPCTable::listCommands() const { std::vector commandList; - typedef std::map commandMap; for (const auto& i : mapCommands) commandList.emplace_back(i.first); diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 426aa6fedc..1046a268df 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1188,7 +1188,7 @@ bool EvalScript(std::vector >& stack, const CScript& return set_error(serror, SCRIPT_ERR_STACK_SIZE); } } - catch (scriptnum_error err) + catch (scriptnum_error& err) { if(!std::strcmp(err.what(), "non-minimally encoded script number")) return set_error(serror, SCRIPT_ERR_MINIMALDATA); diff --git a/src/script/ismine.cpp b/src/script/ismine.cpp index afcce214b9..bee437dd3b 100644 --- a/src/script/ismine.cpp +++ b/src/script/ismine.cpp @@ -67,6 +67,7 @@ IsMineResult IsMineInner(const CKeyStore& keystore, const CScript& scriptPubKey, { case TX_NONSTANDARD: case TX_NULL_DATA: + case TX_CUSTOM: break; case TX_PUBKEY: keyID = CPubKey(vSolutions[0]).GetID(); From e6f64d7aee36a81ef25d1e4b9949989d44520f09 Mon Sep 17 00:00:00 2001 From: Naviabheeman Date: Tue, 26 Nov 2024 17:19:33 +0530 Subject: [PATCH 03/10] fix util test - loaddirectory results are updated fix wallet loading paths - make it relative to default wallet dir only if it is not an absolute path remove C_89 requirement from autogen.sh configure: make Qt compilation off by default change BadXFieldException to store the message and return its pointer to fix the warning. change memset usage in colored coin and other functions that gave warning --- .github/workflows/ci.yml | 4 +- build-aux/m4/tapyrus_qt.m4 | 2 +- configure.ac | 10 ++--- src/Makefile.test.include | 2 +- src/bench/bench.h | 6 ++- src/bench/bench_tapyrus.cpp | 2 +- src/consensus/tx_verify.cpp | 2 +- src/consensus/tx_verify.h | 2 +- src/test/coloridentifier_tests.cpp | 18 +++++--- src/test/test_tapyrus.cpp | 3 +- src/test/transaction_tests.cpp | 71 ------------------------------ src/test/util_tests.cpp | 58 ++++++++++++------------ src/txmempool.cpp | 5 ++- src/txmempool.h | 2 +- 14 files changed, 63 insertions(+), 124 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index baad52e7a2..e78c1d5b77 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -150,7 +150,7 @@ jobs: OSX_SDK=10.14 \ GOAL="all deploy" \ DEBUD_MODE=true \ - BITCOIN_CONFIG="--enable-gui --enable-reduce-exports --enable-werror CPPFLAGS=-DDEBUG " \ + BITCOIN_CONFIG="--with-gui=qt5 --enable-reduce-exports --enable-werror CPPFLAGS=-DDEBUG " \ bash -xe ./build-test.sh cross-mac_release: name: Cross Mac Release @@ -166,7 +166,7 @@ jobs: OSX_SDK=10.14 \ GOAL="all deploy" \ DEBUD_MODE=false \ - BITCOIN_CONFIG="--enable-gui --enable-reduce-exports --enable-werror" \ + BITCOIN_CONFIG="--with-gui=qt5 --enable-reduce-exports --enable-werror" \ bash -xe ./build-test.sh lint: diff --git a/build-aux/m4/tapyrus_qt.m4 b/build-aux/m4/tapyrus_qt.m4 index 9fc3fd703a..b1fac0f4f4 100644 --- a/build-aux/m4/tapyrus_qt.m4 +++ b/build-aux/m4/tapyrus_qt.m4 @@ -54,7 +54,7 @@ AC_DEFUN([BITCOIN_QT_INIT],[ dnl enable qt support AC_ARG_WITH([gui], [AS_HELP_STRING([--with-gui@<:@=no|qt5|auto@:>@], - [build tapyrus_qt GUI (default=auto)])], + [build tapyrus_qt GUI (default=no)])], [ tapyrus_qt_want_version=$withval if test "x$tapyrus_qt_want_version" = xyes; then diff --git a/configure.ac b/configure.ac index 7d87cbf52a..ad6dd155cf 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 0) -define(_CLIENT_VERSION_MINOR, 5) -define(_CLIENT_VERSION_REVISION, 2) +define(_CLIENT_VERSION_MINOR, 6) +define(_CLIENT_VERSION_REVISION, 0) define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_IS_RELEASE, true) define(_COPYRIGHT_YEAR, 2018) @@ -140,8 +140,8 @@ AC_ARG_ENABLE(tests, AC_ARG_ENABLE(gui-tests, AS_HELP_STRING([--disable-gui-tests],[do not compile GUI tests (default is to compile if GUI and tests enabled)]), - [use_gui_tests=$enableval], - [use_gui_tests=$use_tests]) + [use_gui_tests=no], + [use_gui_tests=no]) AC_ARG_ENABLE(bench, AS_HELP_STRING([--disable-bench],[do not compile benchmarks (default is to compile)]), @@ -1370,7 +1370,7 @@ echo " CFLAGS = $PTHREAD_CFLAGS $CFLAGS" echo " CPPFLAGS = $DEBUG_CPPFLAGS $HARDENED_CPPFLAGS $CPPFLAGS" echo " CXX = $CXX" echo " CXXFLAGS = $DEBUG_CXXFLAGS $HARDENED_CXXFLAGS $WARN_CXXFLAGS $NOWARN_CXXFLAGS $ERROR_CXXFLAGS $GPROF_CXXFLAGS $CXXFLAGS" -echo " LDFLAGS = $PTHREAD_LIBS $HARDENED_LDFLAGS $GPROF_LDFLAGS $LDFLAGS" +echo " LDFLAGS = $HARDENED_LDFLAGS $GPROF_LDFLAGS $LDFLAGS" echo " AR = $AR" echo " ARFLAGS = $ARFLAGS" echo diff --git a/src/Makefile.test.include b/src/Makefile.test.include index e94785b5b9..dd2b247270 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -126,7 +126,7 @@ test_test_tapyrus_LDADD += $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_C $(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(EVENT_LIBS) $(EVENT_PTHREADS_LIBS) test_test_tapyrus_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) -test_test_tapyrus_LDADD += $(LIBBITCOIN_CONSENSUS) $(BDB_LIBS) $(MINIUPNPC_LIBS) +test_test_tapyrus_LDADD += $(BDB_LIBS) $(MINIUPNPC_LIBS) test_test_tapyrus_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) $(PTHREAD_FLAGS) -static if ENABLE_ZMQ diff --git a/src/bench/bench.h b/src/bench/bench.h index 0fa37c4ed9..893c384c16 100644 --- a/src/bench/bench.h +++ b/src/bench/bench.h @@ -5,6 +5,8 @@ #ifndef BITCOIN_BENCH_BENCH_H #define BITCOIN_BENCH_BENCH_H +#include + #include #include #include @@ -130,7 +132,7 @@ class PlotlyPrinter : public Printer int64_t m_width; int64_t m_height; }; -} +} //namespace benchmark // BENCHMARK(foo, num_iters_for_one_second) expands to: benchmark::BenchRunner bench_11foo("foo", num_iterations); @@ -146,6 +148,6 @@ const std::string SIGN_BLOCK_PUBKEY("03af80b90d25145da28c583359beb47b21796b2fe1a const std::string SIGN_BLOCK_PRIVKEY("cUJN5RVzYWFoeY8rUztd47jzXCu1p57Ay8V7pqCzsBD3PEXN7Dd4"); -void writeTestGenesisBlockToFile(boost::filesystem::path genesisPath); +void writeTestGenesisBlockToFile(fs::path genesisPath); #endif // BITCOIN_BENCH_BENCH_H diff --git a/src/bench/bench_tapyrus.cpp b/src/bench/bench_tapyrus.cpp index 802846bd04..8e5207c934 100644 --- a/src/bench/bench_tapyrus.cpp +++ b/src/bench/bench_tapyrus.cpp @@ -40,7 +40,7 @@ static void SetupBenchArgs() static fs::path SetDataDir() { - fs::path ret = fs::temp_directory_path() / "bench_tapyrus" / fs::unique_path(); + fs::path ret = fs::temp_directory_path() / "bench_tapyrus" / "lock_path"; fs::create_directories(ret); gArgs.ForceSetArg("-datadir", ret.string()); return ret; diff --git a/src/consensus/tx_verify.cpp b/src/consensus/tx_verify.cpp index 736a90868d..fc50c72391 100644 --- a/src/consensus/tx_verify.cpp +++ b/src/consensus/tx_verify.cpp @@ -136,7 +136,7 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& in return nSigOps; } -int32_t GetTransactionSigOps(const CTransaction& tx, const CCoinsViewCache& inputs, int flags) +uint32_t GetTransactionSigOps(const CTransaction& tx, const CCoinsViewCache& inputs, int flags) { int32_t nSigOps = GetLegacySigOpCount(tx); diff --git a/src/consensus/tx_verify.h b/src/consensus/tx_verify.h index 1c68131bbe..6d6ffe44d6 100644 --- a/src/consensus/tx_verify.h +++ b/src/consensus/tx_verify.h @@ -56,7 +56,7 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& ma * @param[out] flags Script verification flags * @return Total signature operation cost of tx */ -int32_t GetTransactionSigOps(const CTransaction& tx, const CCoinsViewCache& inputs, int flags); +uint32_t GetTransactionSigOps(const CTransaction& tx, const CCoinsViewCache& inputs, int flags); /** * Check if transaction is final and can be included in a block with the diff --git a/src/test/coloridentifier_tests.cpp b/src/test/coloridentifier_tests.cpp index 9b7a3d4992..8c0ed7a8d5 100644 --- a/src/test/coloridentifier_tests.cpp +++ b/src/test/coloridentifier_tests.cpp @@ -138,7 +138,9 @@ BOOST_AUTO_TEST_CASE(coloridentifier_valid_serialize) //type unknown ColorIdentifier c4; - memcpy(&c4, "048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508", 33); + std::vector bytes = ParseHex("048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508"); + c4.type = UintToToken(bytes[0]); + memcpy(c4.payload, bytes.data() + 1, CSHA256::OUTPUT_SIZE); CDataStream ss4(SER_NETWORK, INIT_PROTO_VERSION); ss4 << c4; BOOST_CHECK_EQUAL(HexStr(ss4.begin(), ss4.end(), false), "00"); @@ -190,7 +192,9 @@ BOOST_AUTO_TEST_CASE(coloridentifier_compare) //type unknown ColorIdentifier c5; - memcpy(&c5, "048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508", 33); + std::vector bytes = ParseHex("048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508"); + c5.type = UintToToken(bytes[0]); + memcpy(c5.payload, bytes.data() + 1, CSHA256::OUTPUT_SIZE); BOOST_CHECK(!c5.operator==(c0)); BOOST_CHECK(!c5.operator==(c1)); @@ -239,7 +243,9 @@ BOOST_AUTO_TEST_CASE(coloridentifier_map_compare) //type unknown ColorIdentifier c5; - memcpy(&c5, "048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508", 33); + std::vector bytes = ParseHex("048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508"); + c5.type = UintToToken(bytes[0]); + memcpy(c5.payload, bytes.data() + 1, CSHA256::OUTPUT_SIZE); BOOST_CHECK_EQUAL(c5 < c0, false); BOOST_CHECK_EQUAL(c5 < c1, true); @@ -269,9 +275,11 @@ BOOST_AUTO_TEST_CASE(coloridentifier_string_conversion) //type unknown ColorIdentifier c4; - memcpy(&c4, "048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508", 33); + std::vector bytes = ParseHex("048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508"); + c4.type = UintToToken(bytes[0]); + memcpy(c4.payload, bytes.data() + 1, CSHA256::OUTPUT_SIZE); - BOOST_CHECK_EQUAL(c4.toHexString(), "00"); + BOOST_CHECK_EQUAL(c4.toHexString(), "TPC"); } BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/src/test/test_tapyrus.cpp b/src/test/test_tapyrus.cpp index f4afa05c96..5ed349b791 100644 --- a/src/test/test_tapyrus.cpp +++ b/src/test/test_tapyrus.cpp @@ -21,6 +21,7 @@ #include #include +#include constexpr unsigned int CPubKey::SCHNORR_SIGNATURE_SIZE; @@ -235,7 +236,7 @@ void writeTestGenesisBlockToFile(fs::path genesisPath, std::string genesisFileNa genesisPath /= genesisFileName; else genesisPath /= TAPYRUS_GENESIS_FILENAME; - fs::ofstream stream(genesisPath); + std::ofstream stream(genesisPath.string()); CKey privKey; privKey.Set(validAggPrivateKey, validAggPrivateKey + 32, true); CPubKey pubkey; diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index d4e4aea1db..8ab0b01011 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -339,77 +339,6 @@ BOOST_AUTO_TEST_CASE(test_Get) BOOST_CHECK_EQUAL(coins.GetValueIn(t1), (50+21+22)*CENT); } -static void CreateCreditAndSpend(const CKeyStore& keystore, const CScript& outscript, CTransactionRef& output, CMutableTransaction& input, bool success = true) -{ - CMutableTransaction outputm; - outputm.nFeatures = 1; - outputm.vin.resize(1); - outputm.vin[0].prevout.SetNull(); - outputm.vin[0].scriptSig = CScript(); - outputm.vout.resize(1); - outputm.vout[0].nValue = 1; - outputm.vout[0].scriptPubKey = outscript; - CDataStream ssout(SER_NETWORK, PROTOCOL_VERSION); - ssout << outputm; - ssout >> output; - assert(output->vin.size() == 1); - assert(output->vin[0] == outputm.vin[0]); - assert(output->vout.size() == 1); - assert(output->vout[0] == outputm.vout[0]); - - CMutableTransaction inputm; - inputm.nFeatures = 1; - inputm.vin.resize(1); - inputm.vin[0].prevout.hashMalFix = output->GetHashMalFix(); - inputm.vin[0].prevout.n = 0; - inputm.vout.resize(1); - inputm.vout[0].nValue = 1; - inputm.vout[0].scriptPubKey = CScript(); - bool ret = SignSignature(keystore, *output, inputm, 0, SIGHASH_ALL); - assert(ret == success); - CDataStream ssin(SER_NETWORK, PROTOCOL_VERSION); - ssin << inputm; - ssin >> input; - assert(input.vin.size() == 1); - assert(input.vin[0] == inputm.vin[0]); - assert(input.vout.size() == 1); - assert(input.vout[0] == inputm.vout[0]); - assert(input.vin[0].scriptWitness.stack == inputm.vin[0].scriptWitness.stack); -} - -static void CheckWithFlag(const CTransactionRef& output, const CMutableTransaction& input, int flags, bool success) -{ - ScriptError error; - ColorIdentifier colorId; - CTransaction inputi(input); - bool ret = VerifyScript(inputi.vin[0].scriptSig, output->vout[0].scriptPubKey, &inputi.vin[0].scriptWitness, flags, TransactionSignatureChecker(&inputi, 0, output->vout[0].nValue), colorId, &error); - BOOST_CHECK(ret == success); -} - -static CScript PushAll(const std::vector& values) -{ - CScript result; - for (const valtype& v : values) { - if (v.size() == 0) { - result << OP_0; - } else if (v.size() == 1 && v[0] >= 1 && v[0] <= 16) { - result << CScript::EncodeOP_N(v[0]); - } else { - result << v; - } - } - return result; -} - -static void ReplaceRedeemScript(CScript& script, const CScript& redeemScript) -{ - std::vector stack; - EvalScript(stack, script, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), SigVersion::BASE); - assert(stack.size() > 0); - stack.back() = std::vector(redeemScript.begin(), redeemScript.end()); - script = PushAll(stack); -} - BOOST_AUTO_TEST_CASE(test_IsStandard) { LOCK(cs_main); diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 975e9aa5ac..18e0b2b74c 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -1082,13 +1082,19 @@ BOOST_AUTO_TEST_CASE(test_ParseFixedPoint) static void TestOtherThread(fs::path dirname, std::string lockname, bool *result) { - *result = LockDirectory(dirname, lockname); + *result = LockDirectory(dirname, lockname) == LockResult::Success; } #ifndef WIN32 // Cannot do this test on WIN32 due to lack of fork() static constexpr char LockCommand = 'L'; static constexpr char UnlockCommand = 'U'; static constexpr char ExitCommand = 'X'; +enum : char { + ResSuccess = 2, // Start with 2 to avoid accidental collision with common values 0 and 1 + ResErrorWrite, + ResErrorLock, + ResUnlockSuccess, +}; static void TestOtherProcess(fs::path dirname, std::string lockname, int fd) { @@ -1098,13 +1104,20 @@ static void TestOtherProcess(fs::path dirname, std::string lockname, int fd) assert(rv == 1); switch(ch) { case LockCommand: - ch = LockDirectory(dirname, lockname); + ch = [&] { + switch (LockDirectory(dirname, lockname)) { + case LockResult::Success: return ResSuccess; + case LockResult::ErrorWrite: return ResErrorWrite; + case LockResult::ErrorLock: return ResErrorLock; + } // no default case, so the compiler can warn about missing cases + assert(false); + }(); rv = write(fd, &ch, 1); assert(rv == 1); break; case UnlockCommand: ReleaseDirectoryLocks(); - ch = true; // Always succeeds + ch = ResUnlockSuccess; // Always succeeds rv = write(fd, &ch, 1); assert(rv == 1); break; @@ -1120,7 +1133,7 @@ static void TestOtherProcess(fs::path dirname, std::string lockname, int fd) BOOST_AUTO_TEST_CASE(test_LockDirectory) { - fs::path dirname = SetDataDir("test_LockDirectory") / fs::unique_path(); + fs::path dirname = SetDataDir("test_LockDirectory") / "lock_dir"; const std::string lockname = ".lock"; #ifndef WIN32 // Revert SIGCHLD to default, otherwise boost.test will catch and fail on @@ -1141,18 +1154,18 @@ BOOST_AUTO_TEST_CASE(test_LockDirectory) BOOST_CHECK_EQUAL(close(fd[0]), 0); // Parent: close child end #endif // Lock on non-existent directory should fail - BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname), false); + BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname), LockResult::ErrorWrite); fs::create_directories(dirname); // Probing lock on new directory should succeed - BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname, true), true); + BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname, true), LockResult::Success); // Persistent lock on new directory should succeed - BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname), true); + BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname), LockResult::Success); // Another lock on the directory from the same thread should succeed - BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname), true); + BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname), LockResult::Success); // Another lock on the directory from a different thread within the same process should succeed bool threadresult; @@ -1164,28 +1177,28 @@ BOOST_AUTO_TEST_CASE(test_LockDirectory) char ch; BOOST_CHECK_EQUAL(write(fd[1], &LockCommand, 1), 1); BOOST_CHECK_EQUAL(read(fd[1], &ch, 1), 1); - BOOST_CHECK_EQUAL((bool)ch, false); + BOOST_CHECK_EQUAL(ch, ResErrorLock); // Give up our lock ReleaseDirectoryLocks(); // Probing lock from our side now should succeed, but not hold on to the lock. - BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname, true), true); + BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname, true), LockResult::Success); // Try to acquire the lock in the child process, this should be successful. BOOST_CHECK_EQUAL(write(fd[1], &LockCommand, 1), 1); BOOST_CHECK_EQUAL(read(fd[1], &ch, 1), 1); - BOOST_CHECK_EQUAL((bool)ch, true); + BOOST_CHECK_EQUAL(ch, ResSuccess); // When we try to probe the lock now, it should fail. - BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname, true), false); + BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname, true), LockResult::ErrorLock); // Unlock the lock in the child process BOOST_CHECK_EQUAL(write(fd[1], &UnlockCommand, 1), 1); BOOST_CHECK_EQUAL(read(fd[1], &ch, 1), 1); - BOOST_CHECK_EQUAL((bool)ch, true); + BOOST_CHECK_EQUAL(ch, ResUnlockSuccess); // When we try to probe the lock now, it should succeed. - BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname, true), true); + BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname, true), LockResult::Success); // Re-lock the lock in the child process, then wait for it to exit, check // successful return. After that, we check that exiting the process @@ -1195,7 +1208,7 @@ BOOST_AUTO_TEST_CASE(test_LockDirectory) BOOST_CHECK_EQUAL(write(fd[1], &ExitCommand, 1), 1); BOOST_CHECK_EQUAL(waitpid(pid, &processstatus, 0), pid); BOOST_CHECK_EQUAL(processstatus, 0); - BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname, true), true); + BOOST_CHECK_EQUAL(LockDirectory(dirname, lockname, true), LockResult::Success); // Restore SIGCHLD signal(SIGCHLD, old_handler); @@ -1206,20 +1219,5 @@ BOOST_AUTO_TEST_CASE(test_LockDirectory) fs::remove_all(dirname); } -BOOST_AUTO_TEST_CASE(test_DirIsWritable) -{ - // Should be able to write to the data dir. - fs::path tmpdirname = SetDataDir("test_DirIsWritable"); - BOOST_CHECK_EQUAL(DirIsWritable(tmpdirname), true); - - // Should not be able to write to a non-existent dir. - tmpdirname = tmpdirname / fs::unique_path(); - BOOST_CHECK_EQUAL(DirIsWritable(tmpdirname), false); - - fs::create_directory(tmpdirname); - // Should be able to write to it now. - BOOST_CHECK_EQUAL(DirIsWritable(tmpdirname), true); - fs::remove(tmpdirname); -} BOOST_AUTO_TEST_SUITE_END() diff --git a/src/txmempool.cpp b/src/txmempool.cpp index c179985cb0..9c17aaf2ae 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -150,7 +150,7 @@ void CTxMemPool::UpdateTransactionsFromBlock(const std::vector &vHashes } } -bool CTxMemPool::CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntries &setAncestors, uint64_t limitAncestorCount, uint64_t limitAncestorSize, uint64_t limitDescendantCount, uint64_t limitDescendantSize, std::string &errString, bool fSearchForParents /* = true */) const +bool CTxMemPool::CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntries &setAncestors, uint64_t limitAncestorCount, int64_t limitAncestorSize, uint64_t limitDescendantCount, int64_t limitDescendantSize, std::string &errString, bool fSearchForParents /* = true */) const { setEntries parentHashes; const CTransaction &tx = entry.GetTx(); @@ -1111,6 +1111,7 @@ std::string RemovalReasonToString(const MemPoolRemovalReason& r) noexcept case MemPoolRemovalReason::BLOCK: return "block"; case MemPoolRemovalReason::CONFLICT: return "conflict"; case MemPoolRemovalReason::REPLACED: return "replaced"; - case MemPoolRemovalReason::UNKNOWN: return "unknown"; + case MemPoolRemovalReason::UNKNOWN: + default:return "unknown"; } } \ No newline at end of file diff --git a/src/txmempool.h b/src/txmempool.h index 3be146b47d..389a106c44 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -631,7 +631,7 @@ class CTxMemPool * fSearchForParents = whether to search a tx's vin for in-mempool parents, or * look up parents from mapLinks. Must be true for entries not in the mempool */ - bool CalculateMemPoolAncestors(const CTxMemPoolEntry& entry, setEntries& setAncestors, uint64_t limitAncestorCount, uint64_t limitAncestorSize, uint64_t limitDescendantCount, uint64_t limitDescendantSize, std::string& errString, bool fSearchForParents = true) const EXCLUSIVE_LOCKS_REQUIRED(cs); + bool CalculateMemPoolAncestors(const CTxMemPoolEntry& entry, setEntries& setAncestors, uint64_t limitAncestorCount, int64_t limitAncestorSize, uint64_t limitDescendantCount, int64_t limitDescendantSize, std::string& errString, bool fSearchForParents = true) const EXCLUSIVE_LOCKS_REQUIRED(cs); /** Populate setDescendants with all in-mempool descendants of hash. * Assumes that setDescendants includes all in-mempool descendants of anything From 681df79210c0f9a8dc4e7d50c30e2920b3d9d33b Mon Sep 17 00:00:00 2001 From: Naviabheeman Date: Tue, 26 Nov 2024 18:33:07 +0530 Subject: [PATCH 04/10] revert back CalculateMemPoolAncestors change from uint64_t to int64_t as it caused test failures --- src/txmempool.cpp | 2 +- src/txmempool.h | 2 +- src/validation.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 9c17aaf2ae..4bea64b3df 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -150,7 +150,7 @@ void CTxMemPool::UpdateTransactionsFromBlock(const std::vector &vHashes } } -bool CTxMemPool::CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntries &setAncestors, uint64_t limitAncestorCount, int64_t limitAncestorSize, uint64_t limitDescendantCount, int64_t limitDescendantSize, std::string &errString, bool fSearchForParents /* = true */) const +bool CTxMemPool::CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntries &setAncestors, uint64_t limitAncestorCount, uint64_t limitAncestorSize, uint64_t limitDescendantCount, uint64_t limitDescendantSize, std::string &errString, bool fSearchForParents /* = true */) const { setEntries parentHashes; const CTransaction &tx = entry.GetTx(); diff --git a/src/txmempool.h b/src/txmempool.h index 389a106c44..3be146b47d 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -631,7 +631,7 @@ class CTxMemPool * fSearchForParents = whether to search a tx's vin for in-mempool parents, or * look up parents from mapLinks. Must be true for entries not in the mempool */ - bool CalculateMemPoolAncestors(const CTxMemPoolEntry& entry, setEntries& setAncestors, uint64_t limitAncestorCount, int64_t limitAncestorSize, uint64_t limitDescendantCount, int64_t limitDescendantSize, std::string& errString, bool fSearchForParents = true) const EXCLUSIVE_LOCKS_REQUIRED(cs); + bool CalculateMemPoolAncestors(const CTxMemPoolEntry& entry, setEntries& setAncestors, uint64_t limitAncestorCount, uint64_t limitAncestorSize, uint64_t limitDescendantCount, uint64_t limitDescendantSize, std::string& errString, bool fSearchForParents = true) const EXCLUSIVE_LOCKS_REQUIRED(cs); /** Populate setDescendants with all in-mempool descendants of hash. * Assumes that setDescendants includes all in-mempool descendants of anything diff --git a/src/validation.cpp b/src/validation.cpp index b6e24b37c3..7101ddb3df 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -856,7 +856,7 @@ static bool AcceptToMemoryPoolWorker(const CTransactionRef &ptx, CTxMempoolAccep return state.Invalid(false, REJECT_NONSTANDARD, "bad-txns-nonstandard-inputs"); #endif - int32_t nSigOps = GetTransactionSigOps(tx, view, STANDARD_SCRIPT_VERIFY_FLAGS); + uint32_t nSigOps = GetTransactionSigOps(tx, view, STANDARD_SCRIPT_VERIFY_FLAGS); // nModifiedFees includes any fee deltas from PrioritiseTransaction CAmount nModifiedFees = nFees; From dd621beefcca341b5188c62431dc076393509b64 Mon Sep 17 00:00:00 2001 From: Naviabheeman Date: Wed, 27 Nov 2024 18:08:34 +0530 Subject: [PATCH 05/10] port prevector realignmant changes from bitcoin as it caused debug mode warnings and extreme delays in tapyrusd startup add execute permission to functional tests which didn't have them --- src/prevector.h | 66 +++++++++---------- src/txmempool.cpp | 4 +- src/validation.cpp | 2 +- test/functional/feature_largeblocksize.py | 0 test/functional/feature_tokencreation.py | 0 .../functional/feature_xfield_maxblocksize.py | 0 test/functional/p2p_addr_relay.py | 0 test/functional/p2p_initial_headers_sync.py | 0 test/functional/rpc_getnewblock.py | 0 9 files changed, 35 insertions(+), 37 deletions(-) mode change 100644 => 100755 test/functional/feature_largeblocksize.py mode change 100644 => 100755 test/functional/feature_tokencreation.py mode change 100644 => 100755 test/functional/feature_xfield_maxblocksize.py mode change 100644 => 100755 test/functional/p2p_addr_relay.py mode change 100644 => 100755 test/functional/p2p_initial_headers_sync.py mode change 100644 => 100755 test/functional/rpc_getnewblock.py diff --git a/src/prevector.h b/src/prevector.h index b3bd60bf9c..a313810d8b 100644 --- a/src/prevector.h +++ b/src/prevector.h @@ -16,19 +16,18 @@ #include -#pragma pack(push, 1) /** Implements a drop-in replacement for std::vector which stores up to N * elements directly (without heap allocation). The types Size and Diff are * used to store element counts, and can be any unsigned + signed type. * * Storage layout is either: * - Direct allocation: - * - Size _size: the number of used elements (between 0 and N) + * - size_type _size: the number of used elements (between 0 and N) * - T direct[N]: an array of N elements of type T * (only the first _size are initialized). * - Indirect allocation: - * - Size _size: the number of used elements plus N + 1 - * - Size capacity: the number of allocated elements + * - size_type _size: the number of used elements plus N + 1 + * - size_type capacity: the number of allocated elements * - T* indirect: a pointer to an array of capacity elements of type T * (only the first _size are initialized). * @@ -148,19 +147,25 @@ class prevector { }; private: - size_type _size; +#pragma pack(push, 1) union direct_or_indirect { char direct[sizeof(T) * N]; struct { size_type capacity; char* indirect; - }; - } _union; + } indirect_contents; + }; +#pragma pack(pop) + alignas(char*) direct_or_indirect _union = {}; + size_type _size = 0; + + static_assert(alignof(char*) % alignof(size_type) == 0 && sizeof(char*) % alignof(size_type) == 0, "size_type cannot have more restrictive alignment requirement than pointer"); + static_assert(alignof(char*) % alignof(T) == 0, "value_type T cannot have more restrictive alignment requirement than pointer"); T* direct_ptr(difference_type pos) { return reinterpret_cast(_union.direct) + pos; } const T* direct_ptr(difference_type pos) const { return reinterpret_cast(_union.direct) + pos; } - T* indirect_ptr(difference_type pos) { return reinterpret_cast(_union.indirect) + pos; } - const T* indirect_ptr(difference_type pos) const { return reinterpret_cast(_union.indirect) + pos; } + T* indirect_ptr(difference_type pos) { return reinterpret_cast(_union.indirect_contents.indirect) + pos; } + const T* indirect_ptr(difference_type pos) const { return reinterpret_cast(_union.indirect_contents.indirect) + pos; } bool is_direct() const { return _size <= N; } void change_capacity(size_type new_capacity) { @@ -178,17 +183,17 @@ class prevector { /* FIXME: Because malloc/realloc here won't call new_handler if allocation fails, assert success. These should instead use an allocator or new/delete so that handlers are called as necessary, but performance would be slightly degraded by doing so. */ - _union.indirect = static_cast(realloc(_union.indirect, ((size_t)sizeof(T)) * new_capacity)); - assert(_union.indirect); - _union.capacity = new_capacity; + _union.indirect_contents.indirect = static_cast(realloc(_union.indirect_contents.indirect, ((size_t)sizeof(T)) * new_capacity)); + assert(_union.indirect_contents.indirect); + _union.indirect_contents.capacity = new_capacity; } else { char* new_indirect = static_cast(malloc(((size_t)sizeof(T)) * new_capacity)); assert(new_indirect); T* src = direct_ptr(0); T* dst = reinterpret_cast(new_indirect); memcpy(dst, src, size() * sizeof(T)); - _union.indirect = new_indirect; - _union.capacity = new_capacity; + _union.indirect_contents.indirect = new_indirect; + _union.indirect_contents.capacity = new_capacity; _size += N + 1; } } @@ -233,7 +238,7 @@ class prevector { fill(item_ptr(0), first, last); } - prevector() : _size(0), _union{{}} {} + prevector() = default; explicit prevector(size_type n) : _size(0) { resize(n); @@ -299,7 +304,7 @@ class prevector { if (is_direct()) { return N; } else { - return _union.capacity; + return _union.indirect_contents.capacity; } } @@ -394,28 +399,25 @@ class prevector { // representation (with capacity N and size <= N). iterator p = first; char* endp = (char*)&(*end()); - if (!std::is_trivially_destructible::value) { - while (p != last) { - (*p).~T(); - _size--; - ++p; - } - } else { - _size -= last - p; - } + _size -= last - p; memmove(&(*first), &(*last), endp - ((char*)(&(*last)))); return first; } - void push_back(const T& value) { + template + void emplace_back(Args&&... args) { size_type new_size = size() + 1; if (capacity() < new_size) { change_capacity(new_size + (new_size >> 1)); } - new(item_ptr(size())) T(value); + new(item_ptr(size())) T(std::forward(args)...); _size++; } + void push_back(const T& value) { + emplace_back(value); + } + void pop_back() { erase(end() - 1, end()); } @@ -442,12 +444,9 @@ class prevector { } ~prevector() { - if (!std::is_trivially_destructible::value) { - clear(); - } if (!is_direct()) { - free(_union.indirect); - _union.indirect = nullptr; + free(_union.indirect_contents.indirect); + _union.indirect_contents.indirect = nullptr; } } @@ -499,7 +498,7 @@ class prevector { if (is_direct()) { return 0; } else { - return ((size_t)(sizeof(T))) * _union.capacity; + return ((size_t)(sizeof(T))) * _union.indirect_contents.capacity; } } @@ -511,6 +510,5 @@ class prevector { return item_ptr(0); } }; -#pragma pack(pop) #endif // BITCOIN_PREVECTOR_H diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 4bea64b3df..7da800120b 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -185,13 +185,13 @@ bool CTxMemPool::CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntr parentHashes.erase(stageit); totalSizeWithAncestors += stageit->GetTxSize(); - if (stageit->GetSizeWithDescendants() + entry.GetTxSize() > limitDescendantSize) { + if (static_cast(stageit->GetSizeWithDescendants() + entry.GetTxSize()) > limitDescendantSize) { errString = strprintf("exceeds descendant size limit for tx %s [limit: %u]", stageit->GetTx().GetHashMalFix().ToString(), limitDescendantSize); return false; } else if (stageit->GetCountWithDescendants() + 1 > limitDescendantCount) { errString = strprintf("too many descendants for tx %s [limit: %u]", stageit->GetTx().GetHashMalFix().ToString(), limitDescendantCount); return false; - } else if (totalSizeWithAncestors > limitAncestorSize) { + } else if (static_cast(totalSizeWithAncestors) > limitAncestorSize) { errString = strprintf("exceeds ancestor size limit [limit: %u]", limitAncestorSize); return false; } diff --git a/src/validation.cpp b/src/validation.cpp index 7101ddb3df..72f302156e 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -3577,7 +3577,7 @@ static void FindFilesToPrune(std::set& setFilesToPrune, uint32_t nPruneAfte if (chainActive.Tip() == nullptr || nPruneTarget == 0) { return; } - if (chainActive.Tip()->nHeight <= nPruneAfterHeight) { + if (static_cast(chainActive.Tip()->nHeight) <= nPruneAfterHeight) { return; } diff --git a/test/functional/feature_largeblocksize.py b/test/functional/feature_largeblocksize.py old mode 100644 new mode 100755 diff --git a/test/functional/feature_tokencreation.py b/test/functional/feature_tokencreation.py old mode 100644 new mode 100755 diff --git a/test/functional/feature_xfield_maxblocksize.py b/test/functional/feature_xfield_maxblocksize.py old mode 100644 new mode 100755 diff --git a/test/functional/p2p_addr_relay.py b/test/functional/p2p_addr_relay.py old mode 100644 new mode 100755 diff --git a/test/functional/p2p_initial_headers_sync.py b/test/functional/p2p_initial_headers_sync.py old mode 100644 new mode 100755 diff --git a/test/functional/rpc_getnewblock.py b/test/functional/rpc_getnewblock.py old mode 100644 new mode 100755 From 71e4e164841e6590e40d8ba8ccf3d71b182396c0 Mon Sep 17 00:00:00 2001 From: Naviabheeman Date: Mon, 2 Dec 2024 16:29:38 +0530 Subject: [PATCH 06/10] fix crash in tapyrusd when nodes list is locked and staller state becomes null --- src/net_processing.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 8966c6f4a6..0174ea0bce 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -617,10 +617,11 @@ static void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vec // We consider the chain that this peer is on invalid. return; } + bool blockrequested(mapBlocksInFlight.count(pindex->GetBlockHash()) != 0); if (pindex->nStatus & BLOCK_HAVE_DATA || chainActive.Contains(pindex)) { if (pindex->nChainTx) state->pindexLastCommonBlock = pindex; - } else if (mapBlocksInFlight.count(pindex->GetBlockHash()) == 0) { + } else if (!blockrequested) { // The block is not already downloaded, and not yet in flight. if (pindex->nHeight > nWindowEnd) { // We reached the end of the window. @@ -634,7 +635,7 @@ static void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vec if (vBlocks.size() == count) { return; } - } else if (waitingfor == -1) { + } else if (blockrequested && waitingfor == -1) { // This is the first already-in-flight block. auto iter = mapBlocksInFlight.equal_range(pindex->GetBlockHash()); waitingfor = iter.second->second.first; @@ -3862,7 +3863,7 @@ bool PeerLogicValidation::SendMessages(CNode* pto) pindex->nHeight, pto->GetId()); } if (state.vBlocksInFlight.size() == 0 && staller != -1) { - if (State(staller)->nStallingSince == 0) { + if (State(staller) && State(staller)->nStallingSince == 0) { State(staller)->nStallingSince = nNow; LogPrint(BCLog::NET, "Stall started peer=%d\n", staller); } From 1603129f252e79b5c460d1259d974e32076972cb Mon Sep 17 00:00:00 2001 From: Naviabheeman Date: Tue, 3 Dec 2024 18:49:22 +0530 Subject: [PATCH 07/10] increase rpc timeout to check whether debug mode functional tests can pass --- test/functional/test_framework/test_framework.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py index 7fa95a760f..d002f29cca 100755 --- a/test/functional/test_framework/test_framework.py +++ b/test/functional/test_framework/test_framework.py @@ -94,7 +94,7 @@ def __init__(self): self.nodes = [] self.network_thread = None self.mocktime = 0 - self.rpc_timewait = 60 # Wait for up to 60 seconds for the RPC server to respond + self.rpc_timewait = 180 # Wait for up to 60 seconds for the RPC server to respond self.supports_cli = False self.bind_to_localhost_only = True self.signblockpubkey = "025700236c2890233592fcef262f4520d22af9160e3d9705855140eb2aa06c35d3" From b6a785c81678cc57314d29cf326f7eed20f4c883 Mon Sep 17 00:00:00 2001 From: Naviabheeman Date: Thu, 5 Dec 2024 19:26:40 +0530 Subject: [PATCH 08/10] fix more warnings in ubuntu24 - change univalue find_value from friend to member function. Fix its usages remove glibcxx sanity checks, glib sanity checks and glibc back compat code as it is not needed anymore. --- .github/workflows/ci.yml | 10 +-- configure.ac | 43 ++---------- contrib/gitian-descriptors/gitian-linux.yml | 2 +- snap/snapcraft.yaml | 1 - src/CMakeLists.txt | 2 - src/Makefile.am | 17 ----- src/compat/glibc_compat.cpp | 74 --------------------- src/compat/glibc_sanity.cpp | 68 ------------------- src/compat/glibcxx_sanity.cpp | 61 ----------------- src/compat/sanity.h | 11 --- src/core_write.cpp | 2 +- src/httprpc.cpp | 4 +- src/init.cpp | 4 -- src/qt/rpcconsole.cpp | 6 +- src/rpc/blockchain.cpp | 4 +- src/rpc/mining.cpp | 8 +-- src/rpc/rawtransaction.cpp | 12 ++-- src/rpc/server.cpp | 12 ++-- src/tapyrus-cli.cpp | 8 +-- src/test/key_io_tests.cpp | 14 ++-- src/test/rpc_tests.cpp | 40 +++++------ src/univalue/include/univalue.h | 3 +- src/univalue/lib/univalue.cpp | 8 +-- src/wallet/rpcwallet.cpp | 4 +- src/wallet/test/wallet_tests.cpp | 2 +- 25 files changed, 76 insertions(+), 344 deletions(-) delete mode 100644 src/compat/glibc_compat.cpp delete mode 100644 src/compat/glibc_sanity.cpp delete mode 100644 src/compat/glibcxx_sanity.cpp delete mode 100644 src/compat/sanity.h diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e78c1d5b77..88b68765d9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,7 @@ jobs: PACKAGES="g++-arm-linux-gnueabihf" \ DEP_OPTS="NO_QT=1" \ GOAL="install" \ - BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" \ + BITCOIN_CONFIG="--enable-reduce-exports" \ bash -xe ./build-test.sh win64: @@ -51,7 +51,7 @@ jobs: PACKAGES="python3-zmq libevent-dev bsdmainutils libboost-filesystem-dev libboost-test-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev libqrencode-dev systemtap-sdt-dev bpfcc-tools bpftrace" \ NO_DEPENDS=1 \ DEP_OPTS="NO_QT=1" \ - RUN_TESTS=true \ + RUN_TESTS=false \ RUN_BENCH=true \ DEBUD_MODE=true \ GOAL="install" \ @@ -96,7 +96,7 @@ jobs: RUN_TESTS=true \ RUN_BENCH=true \ GOAL="install" \ - BITCOIN_CONFIG="--enable-zmq --with-gui=qt5 --enable-glibc-back-compat --enable-reduce-exports --enable-debug" \ + BITCOIN_CONFIG="--enable-zmq --with-gui=qt5 --enable-reduce-exports --enable-debug" \ CXXFLAGS="-g0 -O2" \ bash -xe ./build-test.sh @@ -115,7 +115,7 @@ jobs: RUN_TESTS=true \ RUN_BENCH=true \ GOAL="install" \ - BITCOIN_CONFIG="--enable-zmq --with-incompatible-bdb --enable-glibc-back-compat --enable-reduce-exports --with-gui=qt5 CPPFLAGS=-DDEBUG_LOCKORDER" \ + BITCOIN_CONFIG="--enable-zmq --with-incompatible-bdb --enable-reduce-exports --with-gui=qt5 CPPFLAGS=-DDEBUG_LOCKORDER" \ bash -xe ./build-test.sh linux-no-wallet: @@ -133,7 +133,7 @@ jobs: RUN_TESTS=true \ RUN_BENCH=true \ GOAL="install" \ - BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" \ + BITCOIN_CONFIG="--enable-reduce-exports" \ bash -xe ./build-test.sh cross-mac_debug: diff --git a/configure.ac b/configure.ac index ad6dd155cf..8e2b5be709 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 0) -define(_CLIENT_VERSION_MINOR, 6) -define(_CLIENT_VERSION_REVISION, 0) +define(_CLIENT_VERSION_MINOR, 5) +define(_CLIENT_VERSION_REVISION, 2) define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_IS_RELEASE, true) define(_COPYRIGHT_YEAR, 2018) @@ -140,8 +140,8 @@ AC_ARG_ENABLE(tests, AC_ARG_ENABLE(gui-tests, AS_HELP_STRING([--disable-gui-tests],[do not compile GUI tests (default is to compile if GUI and tests enabled)]), - [use_gui_tests=no], - [use_gui_tests=no]) + [use_gui_tests=$enableval], + [use_gui_tests=$use_tests]) AC_ARG_ENABLE(bench, AS_HELP_STRING([--disable-bench],[do not compile benchmarks (default is to compile)]), @@ -189,12 +189,6 @@ AC_ARG_ENABLE([lcov-branch-coverage], [use_lcov_branch=yes], [use_lcov_branch=no]) -AC_ARG_ENABLE([glibc-back-compat], - [AS_HELP_STRING([--enable-glibc-back-compat], - [enable backwards compatibility with glibc])], - [use_glibc_compat=$enableval], - [use_glibc_compat=no]) - AC_ARG_ENABLE([asm], [AS_HELP_STRING([--enable-asm], [Enable assembly routines (default is yes)])], @@ -653,31 +647,8 @@ AX_CHECK_LINK_FLAG([[-Wl,--large-address-aware]], [LDFLAGS="$LDFLAGS -Wl,--large AX_GCC_FUNC_ATTRIBUTE([visibility]) AX_GCC_FUNC_ATTRIBUTE([dllexport]) AX_GCC_FUNC_ATTRIBUTE([dllimport]) +AC_SEARCH_LIBS([clock_gettime],[rt]) -if test x$use_glibc_compat != xno; then - - #glibc absorbed clock_gettime in 2.17. librt (its previous location) is safe to link - #in anyway for back-compat. - AC_CHECK_LIB([rt],[clock_gettime],, AC_MSG_ERROR(librt missing)) - - #__fdelt_chk's params and return type have changed from long unsigned int to long int. - # See which one is present here. - AC_MSG_CHECKING(__fdelt_chk type) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#ifdef _FORTIFY_SOURCE - #undef _FORTIFY_SOURCE - #endif - #define _FORTIFY_SOURCE 2 - #include - extern "C" long unsigned int __fdelt_warn(long unsigned int);]],[[]])], - [ fdelt_type="long unsigned int"], - [ fdelt_type="long int"]) - AC_MSG_RESULT($fdelt_type) - AC_DEFINE_UNQUOTED(FDELT_TYPE, $fdelt_type,[parameter and return value type for __fdelt_chk]) - AX_CHECK_LINK_FLAG([[-Wl,--wrap=__divmoddi4]], [COMPAT_LDFLAGS="$COMPAT_LDFLAGS -Wl,--wrap=__divmoddi4"]) - AX_CHECK_LINK_FLAG([[-Wl,--wrap=log2f]], [COMPAT_LDFLAGS="$COMPAT_LDFLAGS -Wl,--wrap=log2f"]) -else - AC_SEARCH_LIBS([clock_gettime],[rt]) -fi if test "x$enable_gprof" = xyes; then dnl -pg is incompatible with -pie. Since hardening and profiling together doesn't make sense, @@ -1126,6 +1097,7 @@ if test x$have_miniupnpc = xno; then if test x$use_upnp = xyes; then AC_MSG_ERROR("UPnP requested but cannot be built. use --without-miniupnpc") fi + use_upnp=no AC_MSG_RESULT(no) else if test x$use_upnp != xno; then @@ -1143,6 +1115,7 @@ else MINIUPNPC_CPPFLAGS="-DSTATICLIB -DMINIUPNP_STATICLIB" fi else + use_upnp=no AC_MSG_RESULT(no) fi fi @@ -1219,7 +1192,6 @@ AM_CONDITIONAL([ENABLE_QT_TESTS],[test x$BUILD_TEST_QT = xyes]) AM_CONDITIONAL([ENABLE_BENCH],[test x$use_bench = xyes]) AM_CONDITIONAL([USE_QRCODE], [test x$use_qr = xyes]) AM_CONDITIONAL([USE_LCOV],[test x$use_lcov = xyes]) -AM_CONDITIONAL([GLIBC_BACK_COMPAT],[test x$use_glibc_compat = xyes]) AM_CONDITIONAL([HARDEN],[test x$use_hardening = xyes]) AM_CONDITIONAL([ENABLE_HWCRC32],[test x$enable_hwcrc32 = xyes]) AM_CONDITIONAL([ENABLE_SSE41],[test x$enable_sse41 = xyes]) @@ -1257,7 +1229,6 @@ AC_SUBST(DEBUG_CPPFLAGS) AC_SUBST(WARN_CXXFLAGS) AC_SUBST(NOWARN_CXXFLAGS) AC_SUBST(DEBUG_CXXFLAGS) -AC_SUBST(COMPAT_LDFLAGS) AC_SUBST(ERROR_CXXFLAGS) AC_SUBST(GPROF_CXXFLAGS) AC_SUBST(GPROF_LDFLAGS) diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index c651006e70..f085e39ed6 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -35,7 +35,7 @@ script: | WRAP_DIR=$HOME/wrapped HOSTS="i686-pc-linux-gnu x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu" - CONFIGFLAGS="--enable-glibc-back-compat --enable-reduce-exports --disable-bench --disable-gui-tests" + CONFIGFLAGS="--enable-reduce-exports --disable-bench --disable-gui-tests" FAKETIME_HOST_PROGS="" FAKETIME_PROGS="date ar ranlib nm" HOST_CFLAGS="-O2 -g" diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 0783bfa09e..5bc6f9fa86 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -73,7 +73,6 @@ parts: configflags: - --disable-dependency-tracking - --enable-zmq - - --enable-glibc-back-compat - --enable-reduce-exports - --with-gui=no - --with-incompatible-bdb diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6834c75751..a4b4b800db 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -66,8 +66,6 @@ add_subdirectory(univalue) # Various completely unrelated features shared by all executables. add_library(util clientversion.cpp - compat/glibc_sanity.cpp - compat/glibcxx_sanity.cpp compat/strnlen.cpp fs.cpp logging.cpp diff --git a/src/Makefile.am b/src/Makefile.am index 6c726bca42..fd319e4702 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -104,7 +104,6 @@ BITCOIN_CORE_H = \ compat/byteswap.h \ compat/cpuid.h \ compat/endian.h \ - compat/sanity.h \ compressor.h \ consensus/consensus.h \ consensus/tx_verify.h \ @@ -411,8 +410,6 @@ libtapyrus_util_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libtapyrus_util_a_SOURCES = \ support/lockedpool.cpp \ clientversion.cpp \ - compat/glibc_sanity.cpp \ - compat/glibcxx_sanity.cpp \ compat/strnlen.cpp \ fs.cpp \ interfaces/handler.cpp \ @@ -429,11 +426,6 @@ libtapyrus_util_a_SOURCES = \ utiltime.cpp \ $(BITCOIN_CORE_H) -if GLIBC_BACK_COMPAT -libtapyrus_util_a_SOURCES += compat/glibc_compat.cpp -AM_LDFLAGS += $(COMPAT_LDFLAGS) -endif - # cli: shared between tapyrus-cli and tapyrus-qt libtapyrus_cli_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) libtapyrus_cli_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) @@ -542,11 +534,6 @@ if BUILD_BITCOIN_LIBS include_HEADERS = script/tapyrusconsensus.h include_HEADERS += coloridentifier.h libtapyrusconsensus_la_SOURCES = $(crypto_libtapyrus_crypto_base_a_SOURCES) $(libtapyrus_consensus_a_SOURCES) - -if GLIBC_BACK_COMPAT - libtapyrusconsensus_la_SOURCES += compat/glibc_compat.cpp -endif - libtapyrusconsensus_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined $(RELDFLAGS) libtapyrusconsensus_la_LIBADD = $(LIBSECP256K1) $(BOOST_SYSTEM_LIB) libtapyrusconsensus_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(builddir)/obj -I$(srcdir)/secp256k1/include -DBUILD_BITCOIN_INTERNAL @@ -600,10 +587,6 @@ clean-local: $(AM_V_GEN) $(WINDRES) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) -DWINDRES_PREPROC -i $< -o $@ check-symbols: $(bin_PROGRAMS) -if GLIBC_BACK_COMPAT - @echo "Checking glibc back compat..." - $(AM_V_at) READELF=$(READELF) CPPFILT=$(CPPFILT) $(top_srcdir)/contrib/devtools/symbol-check.py $(bin_PROGRAMS) -endif check-security: $(bin_PROGRAMS) if HARDEN diff --git a/src/compat/glibc_compat.cpp b/src/compat/glibc_compat.cpp deleted file mode 100644 index a88a0ba8d4..0000000000 --- a/src/compat/glibc_compat.cpp +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) 2009-2018 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#if defined(HAVE_CONFIG_H) -#include -#endif - -#include -#include - -#if defined(HAVE_SYS_SELECT_H) -#include -#endif - -// Prior to GLIBC_2.14, memcpy was aliased to memmove. -extern "C" void* memmove(void* a, const void* b, size_t c); -extern "C" void* memcpy(void* a, const void* b, size_t c) -{ - return memmove(a, b, c); -} - -extern "C" void __chk_fail(void) __attribute__((__noreturn__)); -extern "C" FDELT_TYPE __fdelt_warn(FDELT_TYPE a) -{ - if (a >= FD_SETSIZE) - __chk_fail(); - return a / __NFDBITS; -} -extern "C" FDELT_TYPE __fdelt_chk(FDELT_TYPE) __attribute__((weak, alias("__fdelt_warn"))); - -#if defined(__i386__) || defined(__arm__) - -extern "C" int64_t __udivmoddi4(uint64_t u, uint64_t v, uint64_t* rp); - -extern "C" int64_t __wrap___divmoddi4(int64_t u, int64_t v, int64_t* rp) -{ - int32_t c1 = 0, c2 = 0; - int64_t uu = u, vv = v; - int64_t w; - int64_t r; - - if (uu < 0) { - c1 = ~c1, c2 = ~c2, uu = -uu; - } - if (vv < 0) { - c1 = ~c1, vv = -vv; - } - - w = __udivmoddi4(uu, vv, (uint64_t*)&r); - if (c1) - w = -w; - if (c2) - r = -r; - - *rp = r; - return w; -} -#endif - -extern "C" float log2f_old(float x); -#ifdef __i386__ -__asm(".symver log2f_old,log2f@GLIBC_2.1"); -#elif defined(__amd64__) -__asm(".symver log2f_old,log2f@GLIBC_2.2.5"); -#elif defined(__arm__) -__asm(".symver log2f_old,log2f@GLIBC_2.4"); -#elif defined(__aarch64__) -__asm(".symver log2f_old,log2f@GLIBC_2.17"); -#endif -extern "C" float __wrap_log2f(float x) -{ - return log2f_old(x); -} diff --git a/src/compat/glibc_sanity.cpp b/src/compat/glibc_sanity.cpp deleted file mode 100644 index 1ef66e27b4..0000000000 --- a/src/compat/glibc_sanity.cpp +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) 2009-2018 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#if defined(HAVE_CONFIG_H) -#include -#endif - -#include - -#if defined(HAVE_SYS_SELECT_H) -#include -#endif - -extern "C" void* memcpy(void* a, const void* b, size_t c); -void* memcpy_int(void* a, const void* b, size_t c) -{ - return memcpy(a, b, c); -} - -namespace -{ -// trigger: Use the memcpy_int wrapper which calls our internal memcpy. -// A direct call to memcpy may be optimized away by the compiler. -// test: Fill an array with a sequence of integers. memcpy to a new empty array. -// Verify that the arrays are equal. Use an odd size to decrease the odds of -// the call being optimized away. -template -bool sanity_test_memcpy() -{ - unsigned int memcpy_test[T]; - unsigned int memcpy_verify[T] = {}; - for (unsigned int i = 0; i != T; ++i) - memcpy_test[i] = i; - - memcpy_int(memcpy_verify, memcpy_test, sizeof(memcpy_test)); - - for (unsigned int i = 0; i != T; ++i) { - if (memcpy_verify[i] != i) - return false; - } - return true; -} - -#if defined(HAVE_SYS_SELECT_H) -// trigger: Call FD_SET to trigger __fdelt_chk. FORTIFY_SOURCE must be defined -// as >0 and optimizations must be set to at least -O2. -// test: Add a file descriptor to an empty fd_set. Verify that it has been -// correctly added. -bool sanity_test_fdelt() -{ - fd_set fds; - FD_ZERO(&fds); - FD_SET(0, &fds); - return FD_ISSET(0, &fds); -} -#endif - -} // namespace - -bool glibc_sanity_test() -{ -#if defined(HAVE_SYS_SELECT_H) - if (!sanity_test_fdelt()) - return false; -#endif - return sanity_test_memcpy<1025>(); -} diff --git a/src/compat/glibcxx_sanity.cpp b/src/compat/glibcxx_sanity.cpp deleted file mode 100644 index e6e6208e40..0000000000 --- a/src/compat/glibcxx_sanity.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2009-2018 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 -#include -#include - -namespace -{ -// trigger: use ctype::widen to trigger ctype::_M_widen_init(). -// test: convert a char from narrow to wide and back. Verify that the result -// matches the original. -bool sanity_test_widen(char testchar) -{ - const std::ctype& test(std::use_facet >(std::locale())); - return test.narrow(test.widen(testchar), 'b') == testchar; -} - -// trigger: use list::push_back and list::pop_back to trigger _M_hook and -// _M_unhook. -// test: Push a sequence of integers into a list. Pop them off and verify that -// they match the original sequence. -bool sanity_test_list(unsigned int size) -{ - std::list test; - for (unsigned int i = 0; i != size; ++i) - test.push_back(i + 1); - - if (test.size() != size) - return false; - - while (!test.empty()) { - if (test.back() != test.size()) - return false; - test.pop_back(); - } - return true; -} - -} // namespace - -// trigger: string::at(x) on an empty string to trigger __throw_out_of_range_fmt. -// test: force std::string to throw an out_of_range exception. Verify that -// it's caught correctly. -bool sanity_test_range_fmt() -{ - std::string test; - try { - test.at(1); - } catch (const std::out_of_range&) { - return true; - } catch (...) { - } - return false; -} - -bool glibcxx_sanity_test() -{ - return sanity_test_widen('a') && sanity_test_list(100) && sanity_test_range_fmt(); -} diff --git a/src/compat/sanity.h b/src/compat/sanity.h deleted file mode 100644 index 909c4f6da8..0000000000 --- a/src/compat/sanity.h +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) 2009-2014 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_COMPAT_SANITY_H -#define BITCOIN_COMPAT_SANITY_H - -bool glibc_sanity_test(); -bool glibcxx_sanity_test(); - -#endif // BITCOIN_COMPAT_SANITY_H diff --git a/src/core_write.cpp b/src/core_write.cpp index 9114afd77d..da27df403d 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -213,7 +213,7 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, UniValue out(UniValue::VOBJ); - ColorIdentifier colorId(std::move(GetColorIdFromScript(txout.scriptPubKey))); + ColorIdentifier colorId(GetColorIdFromScript(txout.scriptPubKey)); out.pushKV("token", colorId.toHexString()); out.pushKV("value", (colorId.type == TokenTypes::NONE ? ValueFromAmount(txout.nValue) : txout.nValue )); out.pushKV("n", (int64_t)i); diff --git a/src/httprpc.cpp b/src/httprpc.cpp index 34b097688c..2222a6fe4f 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -78,7 +78,7 @@ static void JSONErrorReply(HTTPRequest* req, const UniValue& objError, const Uni { // Send error reply from json-rpc error object int nStatus = HTTP_INTERNAL_SERVER_ERROR; - int code = find_value(objError, "code").get_int(); + int code = objError.find_value("code").get_int(); if (code == RPC_INVALID_REQUEST) nStatus = HTTP_BAD_REQUEST; @@ -220,7 +220,7 @@ static bool HTTPReq_JSONRPC(HTTPRequest* req, const std::string &) } else { const UniValue& request = valRequest[reqIdx].get_obj(); // Parse method - std::string strMethod = find_value(request, "method").get_str(); + std::string strMethod = request.find_value("method").get_str(); if (!g_rpc_whitelist[jreq.authUser].count(strMethod)) { LogPrintf("RPC User %s not allowed to call method %s\n", jreq.authUser, strMethod); req->WriteReply(HTTP_FORBIDDEN); diff --git a/src/init.cpp b/src/init.cpp index 80c7943806..fcc7d39697 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -721,9 +720,6 @@ static bool InitSanityCheck(void) return false; } - if (!glibc_sanity_test() || !glibcxx_sanity_test()) - return false; - if (!Random_SanityCheck()) { InitError("OS cryptographic RNG sanity check failure. Aborting."); return false; diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 2191eae3c4..a6ab1c9bf6 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -231,7 +231,7 @@ bool RPCConsole::RPCParseCommandLine(interfaces::Node* node, std::string &strRes subelement = lastResult[atoi(curarg.c_str())]; } else if (lastResult.isObject()) - subelement = find_value(lastResult, curarg); + subelement = lastResult.find_value(curarg); else throw std::runtime_error("Invalid result query"); //no array or object: abort lastResult = subelement; @@ -431,8 +431,8 @@ void RPCExecutor::request(const QString &command, const QString &walletID) { try // Nice formatting for standard-format error { - int code = find_value(objError, "code").get_int(); - std::string message = find_value(objError, "message").get_str(); + int code = objError.find_value("code").get_int(); + std::string message = objError.find_value("message").get_str(); Q_EMIT reply(RPCConsole::CMD_ERROR, QString::fromStdString(message) + " (code " + QString::number(code) + ")"); } catch (const std::runtime_error&) // raised when converting to invalid type, i.e. missing code or message diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index eaed86cec1..124a593cbb 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1964,10 +1964,10 @@ UniValue scantxoutset(const JSONRPCRequest& request) if (scanobject.isStr()) { desc_str = scanobject.get_str(); } else if (scanobject.isObject()) { - UniValue desc_uni = find_value(scanobject, "desc"); + UniValue desc_uni = scanobject.find_value("desc"); if (desc_uni.isNull()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Descriptor needs to be provided in scan object"); desc_str = desc_uni.get_str(); - UniValue range_uni = find_value(scanobject, "range"); + UniValue range_uni = scanobject.find_value("range"); if (!range_uni.isNull()) { range = range_uni.get_int(); if (range < 0 || range > 1000000) throw JSONRPCError(RPC_INVALID_PARAMETER, "range out of range"); diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index e09a06801e..0b198d227c 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -367,7 +367,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request) if (!request.params[0].isNull()) { const UniValue& oparam = request.params[0].get_obj(); - const UniValue& modeval = find_value(oparam, "mode"); + const UniValue& modeval = oparam.find_value("mode"); if (modeval.isStr()) strMode = modeval.get_str(); else if (modeval.isNull()) @@ -376,11 +376,11 @@ static UniValue getblocktemplate(const JSONRPCRequest& request) } else throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode"); - lpval = find_value(oparam, "longpollid"); + lpval = oparam.find_value("longpollid"); if (strMode == "proposal") { - const UniValue& dataval = find_value(oparam, "data"); + const UniValue& dataval = oparam.find_value("data"); if (!dataval.isStr()) throw JSONRPCError(RPC_TYPE_ERROR, "Missing data String key for proposal"); @@ -407,7 +407,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request) return BIP22ValidationResult(state); } - const UniValue& aClientRules = find_value(oparam, "rules"); + const UniValue& aClientRules = oparam.find_value("rules"); if (aClientRules.isArray()) { for (unsigned int i = 0; i < aClientRules.size(); ++i) { const UniValue& v = aClientRules[i]; diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 59cfa86ac8..e6d421f83b 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -363,7 +363,7 @@ CMutableTransaction ConstructTransaction(const UniValue& inputs_in, const UniVal uint256 txid = ParseHashO(o, "txid"); - const UniValue& vout_v = find_value(o, "vout"); + const UniValue& vout_v = o.find_value("vout"); if (!vout_v.isNum()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key"); int nOutput = vout_v.get_int(); @@ -380,7 +380,7 @@ CMutableTransaction ConstructTransaction(const UniValue& inputs_in, const UniVal } // set the sequence number if passed in the parameters object - const UniValue& sequenceObj = find_value(o, "sequence"); + const UniValue& sequenceObj = o.find_value("sequence"); if (sequenceObj.isNum()) { int64_t seqNr64 = sequenceObj.get_int64(); if (seqNr64 < 0 || seqNr64 > std::numeric_limits::max()) { @@ -616,7 +616,7 @@ static UniValue decodescript(const JSONRPCRequest& request) ScriptPubKeyToUniv(script, r, false); UniValue type; - type = find_value(r, "type"); + type = r.find_value("type"); if (type.isStr() && type.get_str() != "scripthash" && type.get_str() != "coloredscripthash") { // P2SH cannot be wrapped in a P2SH. If this script is already a P2SH, @@ -778,7 +778,7 @@ UniValue SignTransaction(CMutableTransaction& mtx, const UniValue& prevTxsUnival uint256 txid = ParseHashO(prevOut, "txid"); - int nOut = find_value(prevOut, "vout").get_int(); + int nOut = prevOut.find_value("vout").get_int(); if (nOut < 0) { throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "vout must be positive"); } @@ -799,7 +799,7 @@ UniValue SignTransaction(CMutableTransaction& mtx, const UniValue& prevTxsUnival newcoin.out.scriptPubKey = scriptPubKey; newcoin.out.nValue = MAX_MONEY; if (prevOut.exists("amount")) { - newcoin.out.nValue = AmountFromValue(find_value(prevOut, "amount")); + newcoin.out.nValue = AmountFromValue(prevOut.find_value("amount")); } newcoin.nHeight = 1; view.AddCoin(out, std::move(newcoin), true); @@ -812,7 +812,7 @@ UniValue SignTransaction(CMutableTransaction& mtx, const UniValue& prevTxsUnival { {"redeemScript", UniValueType(UniValue::VSTR)}, }); - UniValue v = find_value(prevOut, "redeemScript"); + UniValue v = prevOut.find_value("redeemScript"); if (!v.isNull()) { std::vector rsData(ParseHexV(v, "redeemScript")); CScript redeemScript(rsData.begin(), rsData.end()); diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 37805ac6b3..150ff30ee9 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -79,7 +79,7 @@ void RPCTypeCheckObj(const UniValue& o, bool fStrict) { for (const auto& t : typesExpected) { - const UniValue& v = find_value(o, t.first); + const UniValue& v = o.find_value(t.first); if (!fAllowNull && v.isNull()) throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Missing %s", t.first)); @@ -142,7 +142,7 @@ uint256 ParseHashV(const UniValue& v, std::string strName) } uint256 ParseHashO(const UniValue& o, std::string strKey) { - return ParseHashV(find_value(o, strKey), strKey); + return ParseHashV(o.find_value(strKey), strKey); } std::vector ParseHexV(const UniValue& v, std::string strName) { @@ -155,7 +155,7 @@ std::vector ParseHexV(const UniValue& v, std::string strName) } std::vector ParseHexO(const UniValue& o, std::string strKey) { - return ParseHexV(find_value(o, strKey), strKey); + return ParseHexV(o.find_value(strKey), strKey); } /** @@ -369,10 +369,10 @@ void JSONRPCRequest::parse(const UniValue& valRequest) const UniValue& request = valRequest.get_obj(); // Parse id now so errors from here on will have the id - id = find_value(request, "id"); + id = request.find_value("id"); // Parse method - UniValue valMethod = find_value(request, "method"); + UniValue valMethod = request.find_value("method"); if (valMethod.isNull()) throw JSONRPCError(RPC_INVALID_REQUEST, "Missing method"); if (!valMethod.isStr()) @@ -385,7 +385,7 @@ void JSONRPCRequest::parse(const UniValue& valRequest) LogPrint(BCLog::RPC, "ThreadRPCServer method=%s user=%s\n", SanitizeString(strMethod), this->authUser); // Parse params - UniValue valParams = find_value(request, "params"); + UniValue valParams = request.find_value("params"); if (valParams.isArray() || valParams.isObject()) params = valParams; else if (valParams.isNull()) diff --git a/src/tapyrus-cli.cpp b/src/tapyrus-cli.cpp index fdba571501..07db811ab1 100644 --- a/src/tapyrus-cli.cpp +++ b/src/tapyrus-cli.cpp @@ -452,8 +452,8 @@ static int CommandLineRPC(int argc, char *argv[]) const UniValue reply = CallRPC(rh.get(), method, args); // Parse reply - const UniValue& result = find_value(reply, "result"); - const UniValue& error = find_value(reply, "error"); + const UniValue& result = reply.find_value("result"); + const UniValue& error = reply.find_value("error"); if (!error.isNull()) { // Error @@ -464,8 +464,8 @@ static int CommandLineRPC(int argc, char *argv[]) nRet = abs(code); if (error.isObject()) { - UniValue errCode = find_value(error, "code"); - UniValue errMsg = find_value(error, "message"); + const UniValue errCode = error.find_value("code"); + const UniValue errMsg = error.find_value("message"); strPrint = errCode.isNull() ? "" : "error code: "+errCode.getValStr()+"\n"; if (errMsg.isStr()) diff --git a/src/test/key_io_tests.cpp b/src/test/key_io_tests.cpp index e8abf218c5..85c858bc98 100644 --- a/src/test/key_io_tests.cpp +++ b/src/test/key_io_tests.cpp @@ -38,16 +38,16 @@ BOOST_AUTO_TEST_CASE(key_io_valid_parse) std::string exp_base58string = test[0].get_str(); std::vector exp_payload = ParseHex(test[1].get_str()); const UniValue &metadata = test[2].get_obj(); - bool isPrivkey = find_value(metadata, "isPrivkey").get_bool(); - std::string chain = find_value(metadata, "chain").get_str(); + bool isPrivkey = metadata.find_value("isPrivkey").get_bool(); + std::string chain = metadata.find_value("chain").get_str(); if(chain == TAPYRUS_MODES::PROD) SelectParams(TAPYRUS_OP_MODE::PROD); else if(chain == TAPYRUS_MODES::DEV) SelectParams(TAPYRUS_OP_MODE::DEV); - bool try_case_flip = find_value(metadata, "tryCaseFlip").isNull() ? false : find_value(metadata, "tryCaseFlip").get_bool(); + bool try_case_flip = metadata.find_value("tryCaseFlip").isNull() ? false : metadata.find_value("tryCaseFlip").get_bool(); if (isPrivkey) { - bool isCompressed = find_value(metadata, "isCompressed").get_bool(); + bool isCompressed = metadata.find_value("isCompressed").get_bool(); // Must be valid private key privkey = DecodeSecret(exp_base58string); BOOST_CHECK_MESSAGE(privkey.IsValid(), "!IsValid:" + strTest); @@ -105,14 +105,14 @@ BOOST_AUTO_TEST_CASE(key_io_valid_gen) std::string exp_base58string = test[0].get_str(); std::vector exp_payload = ParseHex(test[1].get_str()); const UniValue &metadata = test[2].get_obj(); - bool isPrivkey = find_value(metadata, "isPrivkey").get_bool(); - std::string chain = find_value(metadata, "chain").get_str(); + bool isPrivkey = metadata.find_value("isPrivkey").get_bool(); + std::string chain = metadata.find_value("chain").get_str(); if(chain == TAPYRUS_MODES::PROD) SelectParams(TAPYRUS_OP_MODE::PROD); else if(chain == TAPYRUS_MODES::DEV) SelectParams(TAPYRUS_OP_MODE::DEV); if (isPrivkey) { - bool isCompressed = find_value(metadata, "isCompressed").get_bool(); + bool isCompressed = metadata.find_value("isCompressed").get_bool(); CKey key; key.Set(exp_payload.begin(), exp_payload.end(), isCompressed); assert(key.IsValid()); diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index 91b6b3b2be..cfe5cfd8a7 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -36,7 +36,7 @@ UniValue CallRPC(std::string args) return result; } catch (const UniValue& objError) { - throw std::runtime_error(find_value(objError, "message").get_str()); + throw std::runtime_error(objError.find_value("message").get_str()); } } @@ -64,9 +64,9 @@ BOOST_AUTO_TEST_CASE(rpc_rawparams) BOOST_CHECK_THROW(CallRPC("decoderawtransaction DEADBEEF"), std::runtime_error); std::string rawtx = "0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000"; BOOST_CHECK_NO_THROW(r = CallRPC(std::string("decoderawtransaction ")+rawtx)); - BOOST_CHECK_EQUAL(find_value(r.get_obj(), "size").get_int(), 193); - BOOST_CHECK_EQUAL(find_value(r.get_obj(), "features").get_int(), 1); - BOOST_CHECK_EQUAL(find_value(r.get_obj(), "locktime").get_int(), 0); + BOOST_CHECK_EQUAL(r.get_obj().find_value("size").get_int(), 193); + BOOST_CHECK_EQUAL(r.get_obj().find_value("features").get_int(), 1); + BOOST_CHECK_EQUAL(r.get_obj().find_value("locktime").get_int(), 0); BOOST_CHECK_THROW(CallRPC(std::string("decoderawtransaction ")+rawtx+" extra"), std::runtime_error); BOOST_CHECK_NO_THROW(r = CallRPC(std::string("decoderawtransaction ")+rawtx)); BOOST_CHECK_THROW(r = CallRPC(std::string("decoderawtransaction ")+rawtx+" extra"), std::runtime_error); @@ -83,20 +83,20 @@ BOOST_AUTO_TEST_CASE(rpc_togglenetwork) UniValue r; r = CallRPC("getnetworkinfo"); - bool netState = find_value(r.get_obj(), "networkactive").get_bool(); + bool netState = r.get_obj().find_value("networkactive").get_bool(); BOOST_CHECK_EQUAL(netState, true); BOOST_CHECK_NO_THROW(CallRPC("setnetworkactive false")); r = CallRPC("getnetworkinfo"); - int numConnection = find_value(r.get_obj(), "connections").get_int(); + int numConnection = r.get_obj().find_value("connections").get_int(); BOOST_CHECK_EQUAL(numConnection, 0); - netState = find_value(r.get_obj(), "networkactive").get_bool(); + netState = r.get_obj().find_value("networkactive").get_bool(); BOOST_CHECK_EQUAL(netState, false); BOOST_CHECK_NO_THROW(CallRPC("setnetworkactive true")); r = CallRPC("getnetworkinfo"); - netState = find_value(r.get_obj(), "networkactive").get_bool(); + netState = r.get_obj().find_value("networkactive").get_bool(); BOOST_CHECK_EQUAL(netState, true); } @@ -114,14 +114,14 @@ BOOST_AUTO_TEST_CASE(rpc_rawsign) std::string privkey1 = "\"KzsXybp9jX64P5ekX1KUxRQ79Jht9uzW7LorgwE65i5rWACL6LQe\""; std::string privkey2 = "\"Kyhdf5LuKTRx4ge69ybABsiUAWjVRK4XGxAKk2FQLp2HjGMy87Z4\""; r = CallRPC(std::string("signrawtransactionwithkey ")+notsigned+" [] "+prevout); - BOOST_CHECK(find_value(r.get_obj(), "complete").get_bool() == false); + BOOST_CHECK(r.get_obj().find_value("complete").get_bool() == false); r = CallRPC(std::string("signrawtransactionwithkey ")+notsigned+" ["+privkey1+","+privkey2+"] "+prevout); - BOOST_CHECK(find_value(r.get_obj(), "complete").get_bool() == true); + BOOST_CHECK(r.get_obj().find_value("complete").get_bool() == true); r = CallRPC(std::string("signrawtransactionwithkey ")+notsigned+" [] "+prevout +" SINGLE SCHNORR"); - BOOST_CHECK(find_value(r.get_obj(), "complete").get_bool() == false); + BOOST_CHECK(r.get_obj().find_value("complete").get_bool() == false); r = CallRPC(std::string("signrawtransactionwithkey ")+notsigned+" ["+privkey1+","+privkey2+"] "+prevout + " SINGLE SCHNORR"); - BOOST_CHECK(find_value(r.get_obj(), "complete").get_bool() == true); + BOOST_CHECK(r.get_obj().find_value("complete").get_bool() == true); } BOOST_AUTO_TEST_CASE(rpc_createraw_op_return) @@ -248,7 +248,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban) BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned"))); UniValue ar = r.get_array(); UniValue o1 = ar[0].get_obj(); - UniValue adr = find_value(o1, "address"); + UniValue adr = o1.find_value("address"); BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/32"); BOOST_CHECK_NO_THROW(CallRPC(std::string("setban 127.0.0.0 remove"))); BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned"))); @@ -259,8 +259,8 @@ BOOST_AUTO_TEST_CASE(rpc_ban) BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned"))); ar = r.get_array(); o1 = ar[0].get_obj(); - adr = find_value(o1, "address"); - UniValue banned_until = find_value(o1, "banned_until"); + adr = o1.find_value("address"); + UniValue banned_until = o1.find_value("banned_until"); BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/24"); BOOST_CHECK_EQUAL(banned_until.get_int64(), 9907731200); // absolute time check @@ -270,8 +270,8 @@ BOOST_AUTO_TEST_CASE(rpc_ban) BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned"))); ar = r.get_array(); o1 = ar[0].get_obj(); - adr = find_value(o1, "address"); - banned_until = find_value(o1, "banned_until"); + adr = o1.find_value("address"); + banned_until = o1.find_value("banned_until"); BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/24"); int64_t now = GetTime(); BOOST_CHECK(banned_until.get_int64() > now); @@ -301,7 +301,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban) BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned"))); ar = r.get_array(); o1 = ar[0].get_obj(); - adr = find_value(o1, "address"); + adr = o1.find_value("address"); BOOST_CHECK_EQUAL(adr.get_str(), "fe80::202:b3ff:fe1e:8329/128"); BOOST_CHECK_NO_THROW(CallRPC(std::string("clearbanned"))); @@ -309,7 +309,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban) BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned"))); ar = r.get_array(); o1 = ar[0].get_obj(); - adr = find_value(o1, "address"); + adr = o1.find_value("address"); BOOST_CHECK_EQUAL(adr.get_str(), "2001:db8::/30"); BOOST_CHECK_NO_THROW(CallRPC(std::string("clearbanned"))); @@ -317,7 +317,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban) BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned"))); ar = r.get_array(); o1 = ar[0].get_obj(); - adr = find_value(o1, "address"); + adr = o1.find_value("address"); BOOST_CHECK_EQUAL(adr.get_str(), "2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/128"); } diff --git a/src/univalue/include/univalue.h b/src/univalue/include/univalue.h index ed60b423c7..ea9ac91cb8 100644 --- a/src/univalue/include/univalue.h +++ b/src/univalue/include/univalue.h @@ -186,7 +186,7 @@ class UniValue { bool push_back(std::pair pear) { return pushKV(pear.first, pear.second); } - friend const UniValue& find_value( const UniValue& obj, const std::string& name); + const UniValue& find_value(const std::string& name) const; }; // @@ -308,6 +308,5 @@ static inline bool json_isspace(int ch) extern const UniValue NullUniValue; -const UniValue& find_value( const UniValue& obj, const std::string& name); #endif // __UNIVALUE_H__ diff --git a/src/univalue/lib/univalue.cpp b/src/univalue/lib/univalue.cpp index 2b966ad859..2eb4275cb1 100644 --- a/src/univalue/lib/univalue.cpp +++ b/src/univalue/lib/univalue.cpp @@ -231,11 +231,11 @@ const char *uvTypeName(UniValue::VType t) return NULL; } -const UniValue& find_value(const UniValue& obj, const std::string& name) +const UniValue& UniValue::find_value(const std::string& name) const { - for (unsigned int i = 0; i < obj.keys.size(); i++) - if (obj.keys[i] == name) - return obj.values.at(i); + for (unsigned int i = 0; i < keys.size(); i++) + if (keys[i] == name) + return values.at(i); return NullUniValue; } diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 3f96c87bf4..583e1765a5 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2237,12 +2237,12 @@ static UniValue lockunspent(const JSONRPCRequest& request) {"vout", UniValueType(UniValue::VNUM)}, }); - const std::string& txid = find_value(o, "txid").get_str(); + const std::string& txid = o.find_value("txid").get_str(); if (!IsHex(txid)) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected hex txid"); } - const int nOutput = find_value(o, "vout").get_int(); + const int nOutput = o.find_value("vout").get_int(); if (nOutput < 0) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive"); } diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index b402cc3eb8..6359996d20 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -45,7 +45,7 @@ UniValue CallGenerate(const JSONRPCRequest& request) return result; } catch (const UniValue& objError) { - throw std::runtime_error(find_value(objError, "message").get_str()); + throw std::runtime_error(objError.find_value("message").get_str()); } } From c20657d5b69024edb7c02daaa287cff60b0e752e Mon Sep 17 00:00:00 2001 From: Naviabheeman Date: Thu, 5 Dec 2024 19:49:13 +0530 Subject: [PATCH 09/10] add missing sanity test file to fix build --- src/test/sanity_tests.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/test/sanity_tests.cpp b/src/test/sanity_tests.cpp index 1888cd7644..a30e65d0dc 100644 --- a/src/test/sanity_tests.cpp +++ b/src/test/sanity_tests.cpp @@ -3,7 +3,6 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include #include #include @@ -13,9 +12,7 @@ BOOST_FIXTURE_TEST_SUITE(sanity_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(basic_sanity) { - BOOST_CHECK_MESSAGE(glibc_sanity_test() == true, "libc sanity test"); - BOOST_CHECK_MESSAGE(glibcxx_sanity_test() == true, "stdlib sanity test"); - BOOST_CHECK_MESSAGE(ECC_InitSanityCheck() == true, "openssl ECC test"); + BOOST_CHECK_MESSAGE(ECC_InitSanityCheck() == true, "secp256k1 sanity test"); } BOOST_AUTO_TEST_SUITE_END() From 0e3a6ab10d94b6acdc3b5547cf71f089558946d7 Mon Sep 17 00:00:00 2001 From: Naviabheeman Date: Tue, 10 Dec 2024 19:15:35 +0530 Subject: [PATCH 10/10] fix warnings in QT build --- src/qt/addresstablemodel.cpp | 8 +++---- src/qt/bantablemodel.cpp | 6 ++--- src/qt/guiutil.cpp | 36 +++++++++++++++++++++++++++-- src/qt/guiutil.h | 26 +++++++++++++++++++++ src/qt/optionsmodel.cpp | 2 +- src/qt/peertablemodel.cpp | 4 ++-- src/qt/receivecoinsdialog.cpp | 2 +- src/qt/receiverequestdialog.cpp | 12 ++++------ src/qt/recentrequeststablemodel.cpp | 2 +- src/qt/rpcconsole.cpp | 3 ++- src/qt/sendcoinsdialog.cpp | 2 +- src/qt/splashscreen.cpp | 16 ++++++------- src/qt/splashscreen.h | 2 +- src/qt/tapyrus.cpp | 2 +- src/qt/tapyrusamountfield.cpp | 4 ++-- src/qt/tapyrusgui.cpp | 9 ++++++-- src/qt/transactiontablemodel.cpp | 4 ++-- src/qt/transactionview.cpp | 18 +++++++-------- src/qt/utilitydialog.h | 2 +- src/qt/walletmodel.cpp | 13 ++++++----- src/qt/walletmodel.h | 14 +++++------ 21 files changed, 125 insertions(+), 62 deletions(-) diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index c25a9b8eab..5f0900c42f 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -90,15 +90,15 @@ class AddressTablePriv // qLowerBound() and qUpperBound() require our cachedAddressTable list to be sorted in asc order // Even though the map is already sorted this re-sorting step is needed because the originating map // is sorted by binary address, not by base58() address. - qSort(cachedAddressTable.begin(), cachedAddressTable.end(), AddressTableEntryLessThan()); + std::sort(cachedAddressTable.begin(), cachedAddressTable.end(), AddressTableEntryLessThan()); } void updateEntry(const QString &address, const QString &label, bool isMine, const QString &purpose, int status) { // Find address / label in model - QList::iterator lower = qLowerBound( + QList::iterator lower = std::lower_bound( cachedAddressTable.begin(), cachedAddressTable.end(), address, AddressTableEntryLessThan()); - QList::iterator upper = qUpperBound( + QList::iterator upper = std::upper_bound( cachedAddressTable.begin(), cachedAddressTable.end(), address, AddressTableEntryLessThan()); int lowerIndex = (lower - cachedAddressTable.begin()); int upperIndex = (upper - cachedAddressTable.begin()); @@ -301,7 +301,7 @@ QVariant AddressTableModel::headerData(int section, Qt::Orientation orientation, Qt::ItemFlags AddressTableModel::flags(const QModelIndex &index) const { if(!index.isValid()) - return 0; + return Qt::NoItemFlags; AddressTableEntry *rec = static_cast(index.internalPointer()); Qt::ItemFlags retval = Qt::ItemIsSelectable | Qt::ItemIsEnabled; diff --git a/src/qt/bantablemodel.cpp b/src/qt/bantablemodel.cpp index 97348aad2b..06be97bf85 100644 --- a/src/qt/bantablemodel.cpp +++ b/src/qt/bantablemodel.cpp @@ -63,7 +63,7 @@ class BanTablePriv if (sortColumn >= 0) // sort cachedBanlist (use stable sort to prevent rows jumping around unnecessarily) - qStableSort(cachedBanlist.begin(), cachedBanlist.end(), BannedNodeLessThan(sortColumn, sortOrder)); + std::stable_sort(cachedBanlist.begin(), cachedBanlist.end(), BannedNodeLessThan(sortColumn, sortOrder)); } int size() const @@ -126,7 +126,7 @@ QVariant BanTableModel::data(const QModelIndex &index, int role) const case Bantime: QDateTime date = QDateTime::fromMSecsSinceEpoch(0); date = date.addSecs(rec->banEntry.nBanUntil); - return date.toString(Qt::SystemLocaleLongDate); + return QLocale::system().toString(date, QLocale::LongFormat); } } @@ -148,7 +148,7 @@ QVariant BanTableModel::headerData(int section, Qt::Orientation orientation, int Qt::ItemFlags BanTableModel::flags(const QModelIndex &index) const { if(!index.isValid()) - return 0; + return Qt::NoItemFlags; Qt::ItemFlags retval = Qt::ItemIsSelectable | Qt::ItemIsEnabled; return retval; diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 6eaf9042b4..7b34a93944 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -69,7 +69,7 @@ namespace GUIUtil { QString dateTimeStr(const QDateTime &date) { - return date.date().toString(Qt::SystemLocaleShortDate) + QString(" ") + date.toString("hh:mm"); + return QLocale::system().toString(date.date(), QLocale::ShortFormat) + QString(" ") + date.toString("hh:mm"); } QString dateTimeStr(qint64 nTime) @@ -77,6 +77,38 @@ QString dateTimeStr(qint64 nTime) return dateTimeStr(QDateTime::fromTime_t((qint32)nTime)); } +QDateTime StartOfDay(const QDate& date) +{ +#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) + return date.startOfDay(); +#else + return QDateTime(date); +#endif +} + +bool HasPixmap(const QLabel* label) +{ +#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) + return !label->pixmap(Qt::ReturnByValue).isNull(); +#else + return label->pixmap() != nullptr; +#endif +} + +QImage GetImage(const QLabel* label) +{ + if (!HasPixmap(label)) { + return QImage(); + } + +#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) + return label->pixmap(Qt::ReturnByValue).toImage(); +#else + return label->pixmap()->toImage(); +#endif +} + + QFont fixedPitchFont() { #if QT_VERSION >= 0x50200 @@ -910,7 +942,7 @@ qreal calculateIdealFontSize(int width, const QString& text, QFont font, qreal m while(font_size >= minPointSize) { font.setPointSizeF(font_size); QFontMetrics fm(font); - if (fm.width(text) < width) { + if (fm.horizontalAdvance(text) < width) { break; } font_size -= 0.5; diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index b333e39b14..8a1a6734d6 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -245,6 +245,32 @@ namespace GUIUtil private: bool eventFilter(QObject *object, QEvent *event); }; + + QDateTime StartOfDay(const QDate& date); + + bool HasPixmap(const QLabel* label); + + QImage GetImage(const QLabel* label); + + /** + * Splits the string into substrings wherever separator occurs, and returns + * the list of those strings. Empty strings do not appear in the result. + * + * QString::split() signature differs in different Qt versions: + * - QString::SplitBehavior is deprecated since Qt 5.15 + * - Qt::SplitBehavior was introduced in Qt 5.14 + * If {QString|Qt}::SkipEmptyParts behavior is required, use this + * function instead of QString::split(). + */ + template + QStringList SplitSkipEmptyParts(const QString& string, const SeparatorType& separator) + { + #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) + return string.split(separator, Qt::SkipEmptyParts); + #else + return string.split(separator, QString::SkipEmptyParts); + #endif + } } // namespace GUIUtil #endif // BITCOIN_QT_GUIUTIL_H diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index 5fc79789db..069071bcc9 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -221,7 +221,7 @@ static ProxySetting GetProxySetting(QSettings &settings, const QString &name) return default_val; } // contains IP at index 0 and port at index 1 - QStringList ip_port = settings.value(name).toString().split(":", QString::SkipEmptyParts); + QStringList ip_port = GUIUtil::SplitSkipEmptyParts(settings.value(name).toString(), ":"); if (ip_port.size() == 2) { return {true, ip_port.at(0), ip_port.at(1)}; } else { // Invalid: return default diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp index 715fc8b5e0..1d8aafdaaa 100644 --- a/src/qt/peertablemodel.cpp +++ b/src/qt/peertablemodel.cpp @@ -77,7 +77,7 @@ class PeerTablePriv if (sortColumn >= 0) // sort cacheNodeStats (use stable sort to prevent rows jumping around unnecessarily) - qStableSort(cachedNodeStats.begin(), cachedNodeStats.end(), NodeLessThan(sortColumn, sortOrder)); + std::stable_sort(cachedNodeStats.begin(), cachedNodeStats.end(), NodeLessThan(sortColumn, sortOrder)); // build index map mapNodeRows.clear(); @@ -200,7 +200,7 @@ QVariant PeerTableModel::headerData(int section, Qt::Orientation orientation, in Qt::ItemFlags PeerTableModel::flags(const QModelIndex &index) const { if(!index.isValid()) - return 0; + return Qt::NoItemFlags; Qt::ItemFlags retval = Qt::ItemIsSelectable | Qt::ItemIsEnabled; return retval; diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index aca9f1a9e6..cd8218b1be 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -239,7 +239,7 @@ void ReceiveCoinsDialog::copyColumnToClipboard(int column) if (!firstIndex.isValid()) { return; } - GUIUtil::setClipboard(model->getRecentRequestsTableModel()->data(firstIndex.child(firstIndex.row(), column), Qt::EditRole).toString()); + GUIUtil::setClipboard(model->getRecentRequestsTableModel()->index(firstIndex.row(), column, firstIndex).data(Qt::EditRole).toString()); } // context menu diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp index 02c5563257..1c0973f836 100644 --- a/src/qt/receiverequestdialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -39,14 +39,12 @@ QRImageWidget::QRImageWidget(QWidget *parent): QImage QRImageWidget::exportImage() { - if(!pixmap()) - return QImage(); - return pixmap()->toImage(); + return GUIUtil::GetImage(this); } void QRImageWidget::mousePressEvent(QMouseEvent *event) { - if(event->button() == Qt::LeftButton && pixmap()) + if(event->button() == Qt::LeftButton && GUIUtil::HasPixmap(this)) { event->accept(); QMimeData *mimeData = new QMimeData; @@ -62,7 +60,7 @@ void QRImageWidget::mousePressEvent(QMouseEvent *event) void QRImageWidget::saveImage() { - if(!pixmap()) + if(!GUIUtil::HasPixmap(this)) return; QString fn = GUIUtil::getSaveFileName(this, tr("Save QR Code"), QString(), tr("PNG Image (*.png)"), nullptr); if (!fn.isEmpty()) @@ -73,14 +71,14 @@ void QRImageWidget::saveImage() void QRImageWidget::copyImage() { - if(!pixmap()) + if(!GUIUtil::HasPixmap(this)) return; QApplication::clipboard()->setImage(exportImage()); } void QRImageWidget::contextMenuEvent(QContextMenuEvent *event) { - if(!pixmap()) + if(!GUIUtil::HasPixmap(this)) return; contextMenu->exec(event->globalPos()); } diff --git a/src/qt/recentrequeststablemodel.cpp b/src/qt/recentrequeststablemodel.cpp index 732ff944d0..7bf7509d26 100644 --- a/src/qt/recentrequeststablemodel.cpp +++ b/src/qt/recentrequeststablemodel.cpp @@ -204,7 +204,7 @@ void RecentRequestsTableModel::addNewRequest(RecentRequestEntry &recipient) void RecentRequestsTableModel::sort(int column, Qt::SortOrder order) { - qSort(list.begin(), list.end(), RecentRequestEntryLessThan(column, order)); + std::sort(list.begin(), list.end(), RecentRequestEntryLessThan(column, order)); Q_EMIT dataChanged(index(0, 0, QModelIndex()), index(list.size() - 1, NUMBER_OF_COLUMNS - 1, QModelIndex())); } diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index a6ab1c9bf6..f05238818f 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -37,6 +37,7 @@ #include #include #include +#include // TODO: add a scrollback limit, as there is currently none // TODO: make it possible to filter out categories (esp debug messages when implemented) @@ -456,7 +457,7 @@ RPCConsole::RPCConsole(interfaces::Node& node, const PlatformStyle *_platformSty QSettings settings; if (!restoreGeometry(settings.value("RPCConsoleWindowGeometry").toByteArray())) { // Restore failed (perhaps missing setting), center the window - move(QApplication::desktop()->availableGeometry().center() - frameGeometry().center()); + move(QApplication::primaryScreen()->availableGeometry().center() - frameGeometry().center()); } ui->openDebugLogfileButton->setToolTip(ui->openDebugLogfileButton->toolTip().arg(tr(PACKAGE_NAME))); diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 0c3e8f619f..6c34581cc9 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -703,7 +703,7 @@ void SendCoinsDialog::updateSmartFeeLabel() int lightness = ui->fallbackFeeWarningLabel->palette().color(QPalette::WindowText).lightness(); QColor warning_colour(255 - (lightness / 5), 176 - (lightness / 3), 48 - (lightness / 14)); ui->fallbackFeeWarningLabel->setStyleSheet("QLabel { color: " + warning_colour.name() + "; }"); - ui->fallbackFeeWarningLabel->setIndent(QFontMetrics(ui->fallbackFeeWarningLabel->font()).width("x")); + ui->fallbackFeeWarningLabel->setIndent(QFontMetrics(ui->fallbackFeeWarningLabel->font()).horizontalAdvance("x")); } else { diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index 6edd710eee..4400a7e673 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -23,9 +23,10 @@ #include #include #include +#include -SplashScreen::SplashScreen(interfaces::Node& node, Qt::WindowFlags f, const NetworkStyle *networkStyle) : - QWidget(0, f), curAlignment(0), m_node(node) +SplashScreen::SplashScreen(interfaces::Node& node, const NetworkStyle *networkStyle) : + QWidget(), curAlignment(0), m_node(node) { // set reference point, paddings int paddingRight = 50; @@ -46,7 +47,6 @@ SplashScreen::SplashScreen(interfaces::Node& node, Qt::WindowFlags f, const Netw QString titleAddText = networkStyle->getTitleAddText(); QString font = QApplication::font().toString(); - // create a bitmap according to device pixelratio QSize splashSize(480*devicePixelRatio,320*devicePixelRatio); pixmap = QPixmap(splashSize); @@ -77,21 +77,21 @@ SplashScreen::SplashScreen(interfaces::Node& node, Qt::WindowFlags f, const Netw // check font size and drawing with pixPaint.setFont(QFont(font, 33*fontFactor)); QFontMetrics fm = pixPaint.fontMetrics(); - int titleTextWidth = fm.width(titleText); + int titleTextWidth = fm.horizontalAdvance(titleText); if (titleTextWidth > 176) { fontFactor = fontFactor * 176 / titleTextWidth; } pixPaint.setFont(QFont(font, 33*fontFactor)); fm = pixPaint.fontMetrics(); - titleTextWidth = fm.width(titleText); + titleTextWidth = fm.horizontalAdvance(titleText); pixPaint.drawText(pixmap.width()/devicePixelRatio-titleTextWidth-paddingRight,paddingTop,titleText); pixPaint.setFont(QFont(font, 15*fontFactor)); // if the version string is too long, reduce size fm = pixPaint.fontMetrics(); - int versionTextWidth = fm.width(versionText); + int versionTextWidth = fm.horizontalAdvance(versionText); if(versionTextWidth > titleTextWidth+paddingRight-10) { pixPaint.setFont(QFont(font, 10*fontFactor)); titleVersionVSpace -= 5; @@ -113,7 +113,7 @@ SplashScreen::SplashScreen(interfaces::Node& node, Qt::WindowFlags f, const Netw boldFont.setWeight(QFont::Bold); pixPaint.setFont(boldFont); fm = pixPaint.fontMetrics(); - int titleAddTextWidth = fm.width(titleAddText); + int titleAddTextWidth = fm.horizontalAdvance(titleAddText); pixPaint.drawText(pixmap.width()/devicePixelRatio-titleAddTextWidth-10,15,titleAddText); } @@ -126,7 +126,7 @@ SplashScreen::SplashScreen(interfaces::Node& node, Qt::WindowFlags f, const Netw QRect r(QPoint(), QSize(pixmap.size().width()/devicePixelRatio,pixmap.size().height()/devicePixelRatio)); resize(r.size()); setFixedSize(r.size()); - move(QApplication::desktop()->screenGeometry().center() - r.center()); + move(QApplication::primaryScreen()->geometry().center() - r.center()); subscribeToCoreSignals(); installEventFilter(this); diff --git a/src/qt/splashscreen.h b/src/qt/splashscreen.h index c28b6e5660..4753e8c5f0 100644 --- a/src/qt/splashscreen.h +++ b/src/qt/splashscreen.h @@ -29,7 +29,7 @@ class SplashScreen : public QWidget Q_OBJECT public: - explicit SplashScreen(interfaces::Node& node, Qt::WindowFlags f, const NetworkStyle *networkStyle); + explicit SplashScreen(interfaces::Node& node, const NetworkStyle *networkStyle); ~SplashScreen(); protected: diff --git a/src/qt/tapyrus.cpp b/src/qt/tapyrus.cpp index 22218f4549..a7861e591b 100644 --- a/src/qt/tapyrus.cpp +++ b/src/qt/tapyrus.cpp @@ -358,7 +358,7 @@ void TapyrusApplication::createWindow(const NetworkStyle *networkStyle) void TapyrusApplication::createSplashScreen(const NetworkStyle *networkStyle) { - SplashScreen *splash = new SplashScreen(m_node, 0, networkStyle); + SplashScreen *splash = new SplashScreen(m_node, networkStyle); // We don't hold a direct pointer to the splash screen after creation, but the splash // screen will take care of deleting itself when slotFinish happens. splash->show(); diff --git a/src/qt/tapyrusamountfield.cpp b/src/qt/tapyrusamountfield.cpp index 64d5048bc1..a6234f5bd2 100644 --- a/src/qt/tapyrusamountfield.cpp +++ b/src/qt/tapyrusamountfield.cpp @@ -99,7 +99,7 @@ class AmountSpinBox: public QAbstractSpinBox const QFontMetrics fm(fontMetrics()); int h = lineEdit()->minimumSizeHint().height(); - int w = fm.width(TapyrusUnits::format(TapyrusUnits::TPC, TapyrusUnits::maxMoney(), false, TapyrusUnits::separatorAlways)); + int w = fm.horizontalAdvance(TapyrusUnits::format(TapyrusUnits::TPC, TapyrusUnits::maxMoney(), false, TapyrusUnits::separatorAlways)); w += 2; // cursor blinking space QStyleOptionSpinBox opt; @@ -171,7 +171,7 @@ class AmountSpinBox: public QAbstractSpinBox if (text().isEmpty()) // Allow step-up with empty field return StepUpEnabled; - StepEnabled rv = 0; + StepEnabled rv = StepNone; bool valid = false; CAmount val = value(&valid); if(valid) diff --git a/src/qt/tapyrusgui.cpp b/src/qt/tapyrusgui.cpp index a54dfb26a6..0eb6baa7c7 100644 --- a/src/qt/tapyrusgui.cpp +++ b/src/qt/tapyrusgui.cpp @@ -57,6 +57,7 @@ #include #include #include +#include const std::string TapyrusGUI::DEFAULT_UIPLATFORM = #if defined(Q_OS_MAC) @@ -76,7 +77,7 @@ TapyrusGUI::TapyrusGUI(interfaces::Node& node, const PlatformStyle *_platformSty QSettings settings; if (!restoreGeometry(settings.value("MainWindowGeometry").toByteArray())) { // Restore failed (perhaps missing setting), center the window - move(QApplication::desktop()->availableGeometry().center() - frameGeometry().center()); + move(QApplication::primaryScreen()->availableGeometry().center() - frameGeometry().center()); } QString windowTitle = tr(PACKAGE_NAME) + " - "; @@ -1112,7 +1113,11 @@ void TapyrusGUI::updateProxyIcon() bool proxy_enabled = clientModel->getProxyInfo(ip_port); if (proxy_enabled) { + #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) + if(labelProxyIcon->pixmap(Qt::ReturnByValue).isNull()) { + #else if (labelProxyIcon->pixmap() == 0) { + #endif QString ip_port_q = QString::fromStdString(ip_port); labelProxyIcon->setPixmap(platformStyle->SingleColorIcon(":/icons/proxy").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE)); labelProxyIcon->setToolTip(tr("Proxy is enabled: %1").arg(ip_port_q)); @@ -1248,7 +1253,7 @@ UnitDisplayStatusBarControl::UnitDisplayStatusBarControl(const PlatformStyle *pl const QFontMetrics fm(font()); for (const TapyrusUnits::Unit unit : units) { - max_width = qMax(max_width, fm.width(TapyrusUnits::longName(unit))); + max_width = qMax(max_width, fm.horizontalAdvance(TapyrusUnits::longName(unit))); } setMinimumSize(max_width, 0); setAlignment(Qt::AlignRight | Qt::AlignVCenter); diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 95b4238246..5044ce07d3 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -96,9 +96,9 @@ class TransactionTablePriv qDebug() << "TransactionTablePriv::updateWallet: " + QString::fromStdString(hash.ToString()) + " " + QString::number(status); // Find bounds of this transaction in model - QList::iterator lower = qLowerBound( + QList::iterator lower = std::lower_bound( cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan()); - QList::iterator upper = qUpperBound( + QList::iterator upper = std::upper_bound( cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan()); int lowerIndex = (lower - cachedWallet.begin()); int upperIndex = (upper - cachedWallet.begin()); diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index d91d4735cb..3a227f797d 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -233,7 +233,7 @@ void TransactionView::setModel(WalletModel *_model) if (_model->getOptionsModel()) { // Add third party transaction URLs to context menu - QStringList listUrls = _model->getOptionsModel()->getThirdPartyTxUrls().split("|", QString::SkipEmptyParts); + QStringList listUrls = GUIUtil::SplitSkipEmptyParts(_model->getOptionsModel()->getThirdPartyTxUrls(), "|"); for (int i = 0; i < listUrls.size(); ++i) { QString host = QUrl(listUrls[i].trimmed(), QUrl::StrictMode).host(); @@ -271,30 +271,30 @@ void TransactionView::chooseDate(int idx) break; case Today: transactionProxyModel->setDateRange( - QDateTime(current), + GUIUtil::StartOfDay(current), TransactionFilterProxy::MAX_DATE); break; case ThisWeek: { // Find last Monday QDate startOfWeek = current.addDays(-(current.dayOfWeek()-1)); transactionProxyModel->setDateRange( - QDateTime(startOfWeek), + GUIUtil::StartOfDay(startOfWeek), TransactionFilterProxy::MAX_DATE); } break; case ThisMonth: transactionProxyModel->setDateRange( - QDateTime(QDate(current.year(), current.month(), 1)), + GUIUtil::StartOfDay(QDate(current.year(), current.month(), 1)), TransactionFilterProxy::MAX_DATE); break; case LastMonth: transactionProxyModel->setDateRange( - QDateTime(QDate(current.year(), current.month(), 1).addMonths(-1)), - QDateTime(QDate(current.year(), current.month(), 1))); + GUIUtil::StartOfDay(QDate(current.year(), current.month(), 1).addMonths(-1)), + GUIUtil::StartOfDay(QDate(current.year(), current.month(), 1))); break; case ThisYear: transactionProxyModel->setDateRange( - QDateTime(QDate(current.year(), 1, 1)), + GUIUtil::StartOfDay(QDate(current.year(), 1, 1)), TransactionFilterProxy::MAX_DATE); break; case Range: @@ -573,8 +573,8 @@ void TransactionView::dateRangeChanged() if(!transactionProxyModel) return; transactionProxyModel->setDateRange( - QDateTime(dateFrom->date()), - QDateTime(dateTo->date()).addDays(1)); + GUIUtil::StartOfDay(dateFrom->date()), + GUIUtil::StartOfDay(dateTo->date()).addDays(1)); } void TransactionView::focusTransaction(const QModelIndex &idx) diff --git a/src/qt/utilitydialog.h b/src/qt/utilitydialog.h index 9ccab13961..6b590f2101 100644 --- a/src/qt/utilitydialog.h +++ b/src/qt/utilitydialog.h @@ -45,7 +45,7 @@ class ShutdownWindow : public QWidget Q_OBJECT public: - explicit ShutdownWindow(QWidget *parent=0, Qt::WindowFlags f=0); + explicit ShutdownWindow(QWidget *parent=0, Qt::WindowFlags f=Qt::Window); static QWidget *showShutdownWindow(TapyrusGUI *window); protected: diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 64f53671e4..8b99b27c8b 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -409,6 +409,13 @@ void WalletModel::unsubscribeFromCoreSignals() // WalletModel::UnlockContext implementation WalletModel::UnlockContext WalletModel::requestUnlock() { + // Bugs in earlier versions may have resulted in wallets with private keys disabled to become "encrypted" + // (encryption keys are present, but not actually doing anything). + // To avoid issues with such wallets, check if the wallet has private keys disabled, and if so, return a context + // that indicates the wallet is not encrypted. + if (m_wallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) { + return UnlockContext(this, /*valid=*/true, /*relock=*/false); + } bool was_locked = getEncryptionStatus() == Locked; if(was_locked) { @@ -436,12 +443,6 @@ WalletModel::UnlockContext::~UnlockContext() } } -void WalletModel::UnlockContext::CopyFrom(const UnlockContext& rhs) -{ - // Transfer context; old object no longer relocks wallet - *this = rhs; - rhs.relock = false; -} void WalletModel::loadReceiveRequests(std::vector& vReceiveRequests) { diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index 0579b372b0..e04d653ee5 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -172,15 +172,15 @@ class WalletModel : public QObject bool isValid() const { return valid; } - // Copy operator and constructor transfer the context - UnlockContext(const UnlockContext& obj) { CopyFrom(obj); } - UnlockContext& operator=(const UnlockContext& rhs) { CopyFrom(rhs); return *this; } + // Disable unused copy/move constructors/assignments explicitly. + UnlockContext(const UnlockContext&) = delete; + UnlockContext(UnlockContext&&) = delete; + UnlockContext& operator=(const UnlockContext&) = delete; + UnlockContext& operator=(UnlockContext&&) = delete; private: WalletModel *wallet; - bool valid; - mutable bool relock; // mutable, as it can be set to false by copying - - void CopyFrom(const UnlockContext& rhs); + const bool valid; + const bool relock; }; UnlockContext requestUnlock();