diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index 130cf29..b1cadf5 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -330,6 +330,7 @@ AC_DEFUN([_BITCOIN_QT_FIND_LIBS_WITHOUT_PKGCONFIG],[ ]) BITCOIN_QT_CHECK(AC_CHECK_LIB([z] ,[main],,BITCOIN_QT_FAIL(zlib not found))) + BITCOIN_QT_CHECK(AC_CHECK_LIB([zstd] ,[main],,BITCOIN_QT_FAIL(zstd not found))) BITCOIN_QT_CHECK(AC_CHECK_LIB([png] ,[main],,BITCOIN_QT_FAIL(png not found))) BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Core] ,[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXCore not found))) BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Gui] ,[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXGui not found))) diff --git a/configure.ac b/configure.ac index 50029df..a2b6ccd 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.69]) define(_CLIENT_VERSION_MAJOR, 0) define(_CLIENT_VERSION_MINOR, 1) -define(_CLIENT_VERSION_REVISION, 6) +define(_CLIENT_VERSION_REVISION, 7) define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_IS_RELEASE, true) define(_COPYRIGHT_YEAR, 2014) @@ -10,6 +10,13 @@ AC_INIT([Bitcoin Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERS AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([build-aux/m4]) LT_INIT([disable-shared]) + +dnl Unless the user specified ARFLAGS, force it to be cr +AC_ARG_VAR(ARFLAGS, [Flags for the archiver, defaults to if not set]) +if test "x${ARFLAGS+set}" != "xset"; then + ARFLAGS="cr" +fi + AC_CANONICAL_HOST AH_TOP([#ifndef BITCOIN_CONFIG_H]) AH_TOP([#define BITCOIN_CONFIG_H]) @@ -155,7 +162,7 @@ if test "x$enable_debug" = xyes; then if test "x$GXX" = xyes; then CXXFLAGS="-g3 -rdynamic -O0 -DDEBUG" fi -fi +fi ## TODO: Remove these hard-coded paths and flags. They are here for the sake of ## compatibility with the legacy buildsystem. @@ -199,6 +206,9 @@ case $host in AC_CHECK_LIB([userenv], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([dwmapi], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([pcre2-16], [main],, AC_MSG_ERROR(lib missing)) + AC_CHECK_LIB([wtsapi32], [main],, AC_MSG_ERROR(lib missing)) + AC_CHECK_LIB([zstd], [main],, AC_MSG_ERROR(lib missing)) + AC_CHECK_LIB([opengl32], [main],, AC_MSG_ERROR(lib missing)) AX_CHECK_LINK_FLAG([[-static]],[LDFLAGS="$LDFLAGS -static"]) AX_CHECK_LINK_FLAG([[-static-libgcc]],[LDFLAGS="$LDFLAGS -static-libgcc"]) @@ -599,7 +609,6 @@ AC_MSG_RESULT($build_bitcoin_cli) dnl sets $bitcoin_enable_qt, $bitcoin_enable_qt_test, $bitcoin_enable_qt_dbus BITCOIN_QT_CONFIGURE([$use_pkgconfig], [qt4]) - if test x$use_ipv6 = xyes; then dnl Check for ipv6 build requirements AC_MSG_CHECKING(for operating system IPv6 support) @@ -779,3 +788,78 @@ AC_CONFIG_FILES([Makefile src/Makefile src/test/Makefile src/qt/Makefile src/qt/ AC_CONFIG_FILES([qa/pull-tester/run-bitcoind-for-test.sh],[chmod +x qa/pull-tester/run-bitcoind-for-test.sh]) AC_CONFIG_FILES([qa/pull-tester/build-tests.sh],[chmod +x qa/pull-tester/build-tests.sh]) AC_OUTPUT + +detect_build_os() { + # Detect WSL + if grep -qEi "(Microsoft|WSL)" /proc/version &> /dev/null; then + # WSL specific commands + if test -f "/etc/os-release"; then + . /etc/os-release + linux_dist="${PRETTY_NAME:-$ID}" + else + # Fallback to lsb_release if /etc/os-release is not available + if type lsb_release >/dev/null 2>&1; then + linux_dist=$(lsb_release -d | cut -f2) + else + linux_dist="Unknown Linux" + fi + fi + + echo "WSL (${linux_dist})" + elif [ "$(uname)" = "Linux" ]; then + # Regular Linux + if test -f "/etc/os-release"; then + . /etc/os-release + linux_dist="${PRETTY_NAME:-$ID}" + elif type lsb_release >/dev/null 2>&1; then + linux_dist=$(lsb_release -d | cut -f2) + else + linux_dist="Unknown Linux" + fi + echo "$linux_dist" + elif [ "$(uname)" = "Darwin" ]; then + # macOS + echo "macOS $(sw_vers -productVersion)" + else + # Unknown OS + echo "Unknown OS" + fi +} + +# Store the result in a variable +BUILD_OS=$(detect_build_os) + +# Define color variables using tput +LIGHT_GREY=$(tput setaf 249) +MEDIUM_GREY=$(tput setaf 245) +DARK_GREY=$(tput setaf 235) +NC=$(tput sgr0) # No Color + +# Start of the script +echo "${DARK_GREY}═══════════════════════════════════════════════════════════════════════════${NC}" +echo "${MEDIUM_GREY}============================ System Information ===========================${NC}" +echo "${DARK_GREY}═══════════════════════════════════════════════════════════════════════════${NC}" +echo "${MEDIUM_GREY}Target OS: ${LIGHT_GREY}$TARGET_OS${NC}" +echo "${MEDIUM_GREY}Build OS: ${LIGHT_GREY}$BUILD_OS${NC}" +echo "${DARK_GREY}═══════════════════════════════════════════════════════════════════════════${NC}" +echo "${MEDIUM_GREY}=========================== Application Options ===========================${NC}" +echo "${DARK_GREY}═══════════════════════════════════════════════════════════════════════════${NC}" +echo "${MEDIUM_GREY}Wallet Support: ${LIGHT_GREY}$enable_wallet${NC}" +echo "${MEDIUM_GREY}GUI/Qt Support: ${LIGHT_GREY}$bitcoin_enable_qt${NC}" +if test x$bitcoin_enable_qt != xno; then + echo " ${MEDIUM_GREY}Qt Version: ${LIGHT_GREY}$bitcoin_qt_got_major_vers${NC}" + echo " ${MEDIUM_GREY}QR Support: ${LIGHT_GREY}$use_qr${NC}" +fi +echo "${MEDIUM_GREY}UPnP Support: ${LIGHT_GREY}$use_upnp${NC}" +echo "${MEDIUM_GREY}Debugging: ${LIGHT_GREY}$enable_debug${NC}" +echo "${DARK_GREY}═══════════════════════════════════════════════════════════════════════════${NC}" +echo "${MEDIUM_GREY}============================ Compiler Settings ============================${NC}" +echo "${DARK_GREY}═══════════════════════════════════════════════════════════════════════════${NC}" +echo "${MEDIUM_GREY}Compiler (C): ${LIGHT_GREY}$CC${NC}" +echo "${MEDIUM_GREY}C Flags: ${LIGHT_GREY}$CFLAGS${NC}" +echo "${MEDIUM_GREY}Preprocessor Flags: ${LIGHT_GREY}$CPPFLAGS${NC}" +echo "${MEDIUM_GREY}Compiler (C++): ${LIGHT_GREY}$CXX${NC}" +echo "${MEDIUM_GREY}C++ Flags: ${LIGHT_GREY}$CXXFLAGS${NC}" +echo "${MEDIUM_GREY}Linker Flags: ${LIGHT_GREY}$LDFLAGS${NC}" +echo "${MEDIUM_GREY}AR Flags: ${LIGHT_GREY}$ARFLAGS${NC}" +echo "${DARK_GREY}═══════════════════════════════════════════════════════════════════════════${NC}" diff --git a/src/Makefile.am b/src/Makefile.am index 70644be..9b5993a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,6 @@ include Makefile.include -AM_CPPFLAGS += -I$(builddir) -fpermissive -ffloat-store -std=c++11 -D__STDC_LIMIT_MACROS -D__USE_MINGW_ANSI_STDIO +AM_CPPFLAGS += -I$(builddir) -fpermissive -ffloat-store -std=c++17 -D__STDC_LIMIT_MACROS -D__USE_MINGW_ANSI_STDIO noinst_LIBRARIES = \ libcryptonite_server.a \ diff --git a/src/addrman.h b/src/addrman.h index ecfba3a..536e62b 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -331,7 +331,7 @@ class CAddrMan READWRITE(info); am->mapAddr[info] = n; info.nRandomPos = vRandom.size(); - am->vRandom.push_back(n); + am->vRandom.emplace_back(n); if (nUBuckets != ADDRMAN_NEW_BUCKET_COUNT) { am->vvNew[info.GetNewBucket(am->nKey)].insert(n); @@ -349,10 +349,10 @@ class CAddrMan { info.nRandomPos = vRandom.size(); info.fInTried = true; - am->vRandom.push_back(am->nIdCount); + am->vRandom.emplace_back(am->nIdCount); am->mapInfo[am->nIdCount] = info; am->mapAddr[info] = am->nIdCount; - vTried.push_back(am->nIdCount); + vTried.emplace_back(am->nIdCount); am->nIdCount++; } else { nLost++; diff --git a/src/base58.h b/src/base58.h index 97cb015..63fa926 100644 --- a/src/base58.h +++ b/src/base58.h @@ -262,7 +262,7 @@ class CBitcoinSecret : public CBase58Data assert(vchSecret.IsValid()); SetData(Params().Base58Prefix(CChainParams::SECRET_KEY), vchSecret.begin(), vchSecret.size()); if (vchSecret.IsCompressed()) - vchData.push_back(1); + vchData.emplace_back(1); } CKey GetKey() diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 733ac58..81499ab 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -64,7 +64,7 @@ class CMainParams : public CChainParams { bnProofOfWorkLimit = ~uint256(0) >> 20; nSubsidyHalvingInterval = 210000; -//printf("Target: %s\n", GetTargetWork(4096.0).GetHex().c_str()); exit(0); + //printf("Target: %s\n", GetTargetWork(4096.0).GetHex().c_str()); exit(0); // Build the genesis block. Note that the output of the genesis coinbase cannot // be spent as it did not originally exist in the database. @@ -80,21 +80,21 @@ class CMainParams : public CChainParams { txNew.vout[0].nValue = MAX_MONEY; //All coins created in genesis txNew.vout[0].pubKey = 0; //Genesis target is coinbase txNew.nLockHeight=0; - string msg = "2014/07/27 - Epoch Times - How Bitcoin Compares..."; - txNew.msg = vector(msg.begin(),msg.end()); - genesis.vtx.push_back(txNew); + string msg = "2014/07/27 - Epoch Times - How Bitcoin Compares..."; + txNew.msg = vector(msg.begin(),msg.end()); + genesis.vtx.push_back(txNew); genesis.hashPrevBlock = 0; genesis.hashMerkleRoot = genesis.BuildMerkleTree(); - //Build a single trienode to find the hash of the coinbase only trie - TrieNode *coinbase = new TrieNode(NODE_LEAF); - coinbase->SetKey(0); - coinbase->SetBalance(txNew.vout[0].nValue); + //Build a single trienode to find the hash of the coinbase only trie + TrieNode *coinbase = new TrieNode(NODE_LEAF); + coinbase->SetKey(0); + coinbase->SetBalance(txNew.vout[0].nValue); - genesis.hashAccountRoot = coinbase->Hash(); //TODO: get the trie hash - delete coinbase; + genesis.hashAccountRoot = coinbase->Hash(); //TODO: get the trie hash + delete coinbase; genesis.nVersion = 1; - genesis.nHeight = 0; + genesis.nHeight = 0; genesis.nTime = 1406509200; genesis.nNonce = 1041215929; @@ -105,10 +105,12 @@ class CMainParams : public CChainParams { if(hashGenesisBlock != uint256("0x000009a460ccc429ac6e53c91c6ed2d96697884b8b656a903042faff8971c5aa")) MineGenesis(genesis); - vSeeds.push_back(CDNSSeedData("explorer.cryptonite.info", "explorer.cryptonite.info")); - vSeeds.push_back(CDNSSeedData("xcn.suprnova.cc", "xcn.suprnova.cc")); - vSeeds.push_back(CDNSSeedData("explorer.digicent.org", "explorer.digicent.org")); + vSeeds.emplace_back("dnsseed.cryptonite.info", "dnsseed.cryptonite.info"); + // vSeeds.emplace_back("xcn.suprnova.cc", "xcn.suprnova.cc"); + // vSeeds.emplace_back("explorer.digicent.org", "explorer.digicent.org"); + + //sa ToDO: Review. The convert_to_container stuff was added as a quick fix to get it building in c++11. it should work // but not 100% certain and haven't tested base58Prefixes[PUBKEY_ADDRESS] = (list_of(28)).convert_to_container >(); diff --git a/src/checkqueue.h b/src/checkqueue.h index 2f04f37..d0afc8c 100644 --- a/src/checkqueue.h +++ b/src/checkqueue.h @@ -137,7 +137,7 @@ template class CCheckQueue { void Add(std::vector &vChecks) { boost::unique_lock lock(mutex); for (T &check : vChecks) { - queue.push_back(T()); + queue.emplace_back(T()); check.swap(queue.back()); } nTodo += vChecks.size(); diff --git a/src/clientversion.h b/src/clientversion.h index b68dff9..9bf2e3b 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -11,7 +11,7 @@ // These need to be macros, as version.cpp's and bitcoin-qt.rc's voodoo requires it #define CLIENT_VERSION_MAJOR 0 #define CLIENT_VERSION_MINOR 9 -#define CLIENT_VERSION_REVISION 5 +#define CLIENT_VERSION_REVISION 6 #define CLIENT_VERSION_BUILD 99 // Set to true for release, false for prerelease or test build diff --git a/src/db.cpp b/src/db.cpp index 8ff6a53..3e211c6 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -20,14 +20,12 @@ #include #include +namespace fs = boost::filesystem; using namespace std; using namespace boost; - unsigned int nWalletDBUpdated; - - // // CDB // @@ -44,7 +42,7 @@ void CDBEnv::EnvShutdown() if (ret != 0) LogPrintf("CDBEnv::EnvShutdown : Error %d shutting down database environment: %s\n", ret, DbEnv::strerror(ret)); if (!fMockDb) - DbEnv(0).remove(path.string().c_str(), 0); + DbEnv(static_cast(0)).remove(path.string().c_str(), 0); } CDBEnv::CDBEnv() : dbenv(DB_CXX_NO_EXCEPTIONS) @@ -63,7 +61,7 @@ void CDBEnv::Close() EnvShutdown(); } -bool CDBEnv::Open(const boost::filesystem::path& pathIn) +bool CDBEnv::Open(const fs::path& pathIn) { if (fDbEnvInit) return true; @@ -71,9 +69,9 @@ bool CDBEnv::Open(const boost::filesystem::path& pathIn) boost::this_thread::interruption_point(); path = pathIn; - filesystem::path pathLogDir = path / "database"; + fs::path pathLogDir = path / "database"; TryCreateDirectory(pathLogDir); - filesystem::path pathErrorFile = path / "db.log"; + fs::path pathErrorFile = path / "db.log"; LogPrintf("CDBEnv::Open : LogDir=%s ErrorFile=%s\n", pathLogDir.string(), pathErrorFile.string()); unsigned int nEnvFlags = 0; @@ -471,7 +469,7 @@ void CDBEnv::Flush(bool fShutdown) dbenv.log_archive(&listp, DB_ARCH_REMOVE); Close(); if (!fMockDb) - boost::filesystem::remove_all(path / "database"); + fs::remove_all(path / "database"); } } } diff --git a/src/hashblock.h b/src/hashblock.h index 859b71d..d437125 100644 --- a/src/hashblock.h +++ b/src/hashblock.h @@ -30,8 +30,6 @@ GLOBAL sph_haval256_5_context z_haval; GLOBAL sph_tiger_context z_tiger; GLOBAL sph_ripemd160_context z_ripemd; - - #define fillz() do { \ sph_sha512_init(&z_sha512); \ sph_sha256_init(&z_sha256); \ @@ -145,15 +143,8 @@ inline uint256 Hash7(const T1 pbegin, const T1 pend) sph_sha256 (&ctx_sha256, data,bytes); sph_sha256_close(&ctx_sha256, static_cast(&finalhash)); - free(data); return finalhash; } - - - - - #endif // HASHBLOCK_H - diff --git a/src/init.cpp b/src/init.cpp index 9071389..76f180c 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -38,6 +38,7 @@ #include #include +namespace fs = boost::filesystem; using namespace std; using namespace boost; @@ -139,7 +140,7 @@ void Shutdown() if (pwalletMain) bitdb.Flush(true); #endif - boost::filesystem::remove(GetPidFile()); + fs::remove(GetPidFile()); UnregisterAllWallets(); #ifdef ENABLE_WALLET if (pwalletMain) @@ -366,7 +367,7 @@ struct CImportingNow } }; -void ThreadImport(std::vector vImportFiles) +void ThreadImport(std::vector vImportFiles) { RenameThread("cryptonite-loadblk"); ScheduleBatchPriority(); @@ -392,12 +393,12 @@ void ThreadImport(std::vector vImportFiles) } // hardcoded $DATADIR/bootstrap.dat - filesystem::path pathBootstrap = GetDataDir() / "bootstrap.dat"; - if (filesystem::exists(pathBootstrap)) { + fs::path pathBootstrap = GetDataDir() / "bootstrap.dat"; + if (fs::exists(pathBootstrap)) { FILE *file = fopen(pathBootstrap.string().c_str(), "rb"); if (file) { CImportingNow imp; - filesystem::path pathBootstrapOld = GetDataDir() / "bootstrap.dat.old"; + fs::path pathBootstrapOld = GetDataDir() / "bootstrap.dat.old"; LogPrintf("Importing bootstrap.dat...\n"); LoadExternalBlockFile(file); RenameOver(pathBootstrap, pathBootstrapOld); @@ -407,7 +408,7 @@ void ThreadImport(std::vector vImportFiles) } // -loadblock= - for (boost::filesystem::path &path : vImportFiles) { + for (fs::path &path : vImportFiles) { FILE *file = fopen(path.string().c_str(), "rb"); if (file) { CImportingNow imp; @@ -640,11 +641,11 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) std::string strDataDir = GetDataDir().string(); #ifdef ENABLE_WALLET // Wallet file must be a plain filename without a directory - if (strWalletFile != boost::filesystem::basename(strWalletFile) + boost::filesystem::extension(strWalletFile)) + if (strWalletFile != fs::basename(strWalletFile) + fs::extension(strWalletFile)) return InitError(strprintf(_("Wallet %s resides outside data directory %s"), strWalletFile, strDataDir)); #endif // Make sure only a single Bitcoin process is using the data directory. - boost::filesystem::path pathLockFile = GetDataDir() / ".lock"; + fs::path pathLockFile = GetDataDir() / ".lock"; FILE* file = fopen(pathLockFile.string().c_str(), "a"); // empty lock file; created if it doesn't exist. if (file) fclose(file); static boost::interprocess::file_lock lock(pathLockFile.string().c_str()); @@ -684,12 +685,12 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (!bitdb.Open(GetDataDir())) { // try moving the database env out of the way - boost::filesystem::path pathDatabase = GetDataDir() / "database"; - boost::filesystem::path pathDatabaseBak = GetDataDir() / strprintf("database.%d.bak", GetTime()); + fs::path pathDatabase = GetDataDir() / "database"; + fs::path pathDatabaseBak = GetDataDir() / strprintf("database.%d.bak", GetTime()); try { - boost::filesystem::rename(pathDatabase, pathDatabaseBak); + fs::rename(pathDatabase, pathDatabaseBak); LogPrintf("Moved old %s to %s. Retrying.\n", pathDatabase.string(), pathDatabaseBak.string()); - } catch(boost::filesystem::filesystem_error &error) { + } catch(fs::filesystem_error &error) { // failure is ok (well, not really, but it's not worse than what we started with) } @@ -708,7 +709,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) return false; } - if (filesystem::exists(GetDataDir() / strWalletFile)) + if (fs::exists(GetDataDir() / strWalletFile)) { CDBEnv::VerifyResult r = bitdb.Verify(strWalletFile, CWalletDB::Recover); if (r == CDBEnv::RECOVER_OK) @@ -834,10 +835,10 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) fReindex = GetBoolArg("-reindex", false); // Create blocks dir - filesystem::path blocksDir = GetDataDir() / "blocks"; - if (!filesystem::exists(blocksDir)) + fs::path blocksDir = GetDataDir() / "blocks"; + if (!fs::exists(blocksDir)) { - filesystem::create_directories(blocksDir); + fs::create_directories(blocksDir); } // cache size calculations @@ -1092,7 +1093,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) fLoading=false; - std::vector vImportFiles; + std::vector vImportFiles; if (mapArgs.count("-loadblock")) { for (string strFile : mapMultiArgs["-loadblock"]) diff --git a/src/json/json_spirit_reader_template.h b/src/json/json_spirit_reader_template.h index 42fd0fb..0b404b5 100644 --- a/src/json/json_spirit_reader_template.h +++ b/src/json/json_spirit_reader_template.h @@ -11,7 +11,7 @@ //#define BOOST_SPIRIT_THREADSAFE // uncomment for multithreaded use, requires linking to boost.thread -#include +#include #include #if BOOST_VERSION >= 103800 @@ -30,6 +30,8 @@ #define spirit_namespace boost::spirit #endif +using namespace boost::placeholders; + namespace json_spirit { const spirit_namespace::int_parser < boost::int64_t > int64_p = spirit_namespace::int_parser < boost::int64_t >(); @@ -307,7 +309,7 @@ namespace json_spirit } else { - stack_.push_back( current_p_ ); + stack_.emplace_back( current_p_ ); Array_or_obj new_array_or_obj; // avoid copy by building new array or object in place @@ -333,7 +335,7 @@ namespace json_spirit } else if( current_p_->type() == array_type ) { - current_p_->get_array().push_back( value ); + current_p_->get_array().emplace_back( value ); return ¤t_p_->get_array().back(); } diff --git a/src/json/json_spirit_utils.h b/src/json/json_spirit_utils.h index 553e3b9..724bf7a 100644 --- a/src/json/json_spirit_utils.h +++ b/src/json/json_spirit_utils.h @@ -33,7 +33,7 @@ namespace json_spirit for( typename Map_t::const_iterator i = mp_obj.begin(); i != mp_obj.end(); ++i ) { - obj.push_back( typename Obj_t::value_type( i->first, i->second ) ); + obj.emplace_back( typename Obj_t::value_type( i->first, i->second ) ); } } diff --git a/src/json/json_spirit_value.h b/src/json/json_spirit_value.h index 7e83a2a..fa2592b 100644 --- a/src/json/json_spirit_value.h +++ b/src/json/json_spirit_value.h @@ -117,7 +117,7 @@ namespace json_spirit static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value ) { - obj.push_back( Pair_type( name , value ) ); + obj.emplace_back( Pair_type( name , value ) ); return obj.back().value_; } diff --git a/src/key.cpp b/src/key.cpp index 55b5837..cebfd7a 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -115,7 +115,7 @@ int ECDSA_SIG_recover_key_GFp(EC_KEY *eckey, ECDSA_SIG *ecsig, const unsigned ch if (!BN_bin2bn(msg, msglen, e)) { ret=-1; goto err; } if (8*msglen > n) BN_rshift(e, e, 8-(n & 7)); zero = BN_CTX_get(ctx); - if (!BN_zero(zero)) { ret=-1; goto err; } + BN_zero(zero); if (!BN_mod_sub(e, zero, e, order, ctx)) { ret=-1; goto err; } rr = BN_CTX_get(ctx); if (!BN_mod_inverse(rr, sig_r, order, ctx)) { ret=-1; goto err; } diff --git a/src/leveldb/db/version_edit.h b/src/leveldb/db/version_edit.h index eaef77b..859996d 100644 --- a/src/leveldb/db/version_edit.h +++ b/src/leveldb/db/version_edit.h @@ -53,7 +53,7 @@ class VersionEdit { last_sequence_ = seq; } void SetCompactPointer(int level, const InternalKey& key) { - compact_pointers_.push_back(std::make_pair(level, key)); + compact_pointers_.emplace_back(std::make_pair(level, key)); } // Add the specified file at the specified number. @@ -68,7 +68,7 @@ class VersionEdit { f.file_size = file_size; f.smallest = smallest; f.largest = largest; - new_files_.push_back(std::make_pair(level, f)); + new_files_.emplace_back(std::make_pair(level, f)); } // Delete the specified "file" from the specified "level". diff --git a/src/leveldbwrapper.cpp b/src/leveldbwrapper.cpp index 01b80fc..185cc7f 100644 --- a/src/leveldbwrapper.cpp +++ b/src/leveldbwrapper.cpp @@ -3,16 +3,14 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "leveldbwrapper.h" - #include "util.h" - #include #include #include #include #include -void HandleError(const leveldb::Status &status) throw(leveldb_error) { +void HandleError(const leveldb::Status &status) { if (status.ok()) return; LogPrintf("%s\n", status.ToString()); @@ -70,7 +68,7 @@ CLevelDBWrapper::~CLevelDBWrapper() { options.env = nullptr; } -bool CLevelDBWrapper::WriteBatch(CLevelDBBatch &batch, bool fSync) throw(leveldb_error) { +bool CLevelDBWrapper::WriteBatch(CLevelDBBatch &batch, bool fSync) { leveldb::Status status = pdb->Write(fSync ? syncoptions : writeoptions, &batch.batch); HandleError(status); return true; diff --git a/src/leveldbwrapper.h b/src/leveldbwrapper.h index 10a778e..4cf54b2 100644 --- a/src/leveldbwrapper.h +++ b/src/leveldbwrapper.h @@ -19,9 +19,8 @@ class leveldb_error : public std::runtime_error leveldb_error(const std::string &msg) : std::runtime_error(msg) {} }; -void HandleError(const leveldb::Status &status) throw(leveldb_error); +void HandleError(const leveldb::Status &status); -// Batch of changes queued to be written to a CLevelDBWrapper class CLevelDBBatch { friend class CLevelDBWrapper; @@ -82,7 +81,7 @@ class CLevelDBWrapper CLevelDBWrapper(const boost::filesystem::path &path, size_t nCacheSize, bool fMemory = false, bool fWipe = false); ~CLevelDBWrapper(); - template bool Read(const K& key, V& value) throw(leveldb_error) { + template bool Read(const K& key, V& value) { CDataStream ssKey(SER_DISK, CLIENT_VERSION); ssKey.reserve(ssKey.GetSerializeSize(key)); ssKey << key; @@ -92,7 +91,6 @@ class CLevelDBWrapper leveldb::Status status = pdb->Get(readoptions, slKey, &strValue); if (!status.ok()) { if (status.IsNotFound()){ - //printf("Not found\n"); return false; } LogPrintf("LevelDB read failure: %s\n", status.ToString().c_str()); @@ -101,20 +99,19 @@ class CLevelDBWrapper try { CDataStream ssValue(strValue.data(), strValue.data() + strValue.size(), SER_DISK, CLIENT_VERSION); ssValue >> value; - } catch(std::exception &e) { - //printf("Exception\n"); + } catch(const std::exception &e) { return false; } return true; } - template bool Write(const K& key, const V& value, bool fSync = false) throw(leveldb_error) { + template bool Write(const K& key, const V& value, bool fSync = false) { CLevelDBBatch batch; batch.Write(key, value); return WriteBatch(batch, fSync); } - template bool Exists(const K& key) throw(leveldb_error) { + template bool Exists(const K& key) { CDataStream ssKey(SER_DISK, CLIENT_VERSION); ssKey.reserve(ssKey.GetSerializeSize(key)); ssKey << key; @@ -131,20 +128,20 @@ class CLevelDBWrapper return true; } - template bool Erase(const K& key, bool fSync = false) throw(leveldb_error) { + template bool Erase(const K& key, bool fSync = false) { CLevelDBBatch batch; batch.Erase(key); return WriteBatch(batch, fSync); } - bool WriteBatch(CLevelDBBatch &batch, bool fSync = false) throw(leveldb_error); + bool WriteBatch(CLevelDBBatch &batch, bool fSync = false); // not available for LevelDB; provide for compatibility with BDB bool Flush() { return true; } - bool Sync() throw(leveldb_error) { + bool Sync() { CLevelDBBatch batch; return WriteBatch(batch, true); } diff --git a/src/limitedmap.h b/src/limitedmap.h index 1623a37..3d0a4ec 100644 --- a/src/limitedmap.h +++ b/src/limitedmap.h @@ -5,11 +5,12 @@ #ifndef BITCOIN_LIMITEDMAP_H #define BITCOIN_LIMITEDMAP_H -#include // TODO: remove +#include #include /** STL-like map container that only keeps the N elements with the highest value. */ -template class limitedmap +template +class limitedmap { public: typedef K key_type; @@ -26,76 +27,75 @@ template class limitedmap size_type nMaxSize; public: - limitedmap(size_type nMaxSizeIn = 0) { nMaxSize = nMaxSizeIn; } + limitedmap(size_type nMaxSizeIn) + { + assert(nMaxSizeIn > 0); + nMaxSize = nMaxSizeIn; + } + const_iterator begin() const { return map.begin(); } const_iterator end() const { return map.end(); } size_type size() const { return map.size(); } bool empty() const { return map.empty(); } const_iterator find(const key_type& k) const { return map.find(k); } size_type count(const key_type& k) const { return map.count(k); } + void insert(const value_type& x) { - std::pair ret = map.insert(x); - if (ret.second) - { - if (nMaxSize && map.size() == nMaxSize) - { + auto ret = map.emplace(x); + if (ret.second) { + if (map.size() > nMaxSize) { map.erase(rmap.begin()->second); rmap.erase(rmap.begin()); } - rmap.insert(make_pair(x.second, ret.first)); + rmap.emplace(x.second, ret.first); } - return; } + void erase(const key_type& k) { iterator itTarget = map.find(k); if (itTarget == map.end()) return; - std::pair itPair = rmap.equal_range(itTarget->second); + + auto itPair = rmap.equal_range(itTarget->second); for (rmap_iterator it = itPair.first; it != itPair.second; ++it) - if (it->second == itTarget) - { + if (it->second == itTarget) { rmap.erase(it); map.erase(itTarget); return; } - // Shouldn't ever get here - assert(0); //TODO remove me - map.erase(itTarget); + assert(0); } + void update(const_iterator itIn, const mapped_type& v) { - //TODO: When we switch to C++11, use map.erase(itIn, itIn) to get the non-const iterator - iterator itTarget = map.find(itIn->first); + iterator itTarget = map.erase(itIn, itIn); if (itTarget == map.end()) return; - std::pair itPair = rmap.equal_range(itTarget->second); + + auto itPair = rmap.equal_range(itTarget->second); for (rmap_iterator it = itPair.first; it != itPair.second; ++it) - if (it->second == itTarget) - { + if (it->second == itTarget) { rmap.erase(it); itTarget->second = v; - rmap.insert(make_pair(v, itTarget)); + rmap.emplace(v, itTarget); return; } - // Shouldn't ever get here - assert(0); //TODO remove me - itTarget->second = v; - rmap.insert(make_pair(v, itTarget)); + assert(0); } + size_type max_size() const { return nMaxSize; } size_type max_size(size_type s) { - if (s) - while (map.size() > s) - { - map.erase(rmap.begin()->second); - rmap.erase(rmap.begin()); - } + assert(s > 0); + while (map.size() > s) { + map.erase(rmap.begin()->second); + rmap.erase(rmap.begin()); + } nMaxSize = s; return nMaxSize; } }; -#endif +#endif // BITCOIN_LIMITEDMAP_H diff --git a/src/main.cpp b/src/main.cpp index 13f94c5..3501bcc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -28,6 +28,11 @@ #include +#include +#include +#include + +namespace fs = boost::filesystem; using namespace std; using namespace boost; @@ -97,10 +102,9 @@ static std::map mapUnindexed; const string strMessageMagic = "Cryptonite Signed Message:\n"; // Internal stuff -namespace { struct CBlockIndexWorkComparator { - bool operator()(CBlockIndex *pa, CBlockIndex *pb) { + bool operator()(CBlockIndex *pa, CBlockIndex *pb) const { // First sort by most total work, ... if (pa->nChainWork > pb->nChainWork) return false; if (pa->nChainWork < pb->nChainWork) return true; @@ -132,7 +136,6 @@ void printAffairs(){ printf("validSize: %ld\n", setBlockIndexValid.size()); } - CCriticalSection cs_LastBlockFile; CBlockFileInfo infoLastBlockFile; int nLastBlockFile = 0; @@ -147,12 +150,9 @@ uint32_t nBlockSequenceId = 1; // them, if processing happens afterwards. Protected by cs_main. map mapBlockSource; -} - /** Show progress e.g. for load */ boost::signals2::signal ShowProgress; - ////////////////////////////////////////////////////////////////////////////// // // dispatching functions @@ -160,39 +160,44 @@ boost::signals2::signal ShowProg // These functions dispatch to one or all registered wallets +std::map connectionMap; + namespace { struct CMainSignals { - // Notifies listeners of updated transaction data (passing hash, transaction, and optionally the block it is found in. boost::signals2::signal SyncTransaction; - // Notifies listeners of an erased transaction (currently disabled, requires transaction replacement). boost::signals2::signal EraseTransaction; - // Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible). boost::signals2::signal UpdatedTransaction; - // Notifies listeners of a new active block chain. boost::signals2::signal SetBestChain; - // Notifies listeners about an inventory item being seen on the network. boost::signals2::signal Inventory; - // Tells listeners to broadcast their data. boost::signals2::signal Broadcast; } g_signals; } void RegisterWallet(CWalletInterface* pwalletIn) { - g_signals.SyncTransaction.connect(boost::bind(&CWalletInterface::SyncTransaction, pwalletIn, _1, _2, _3)); - g_signals.EraseTransaction.connect(boost::bind(&CWalletInterface::EraseFromWallet, pwalletIn, _1)); - g_signals.UpdatedTransaction.connect(boost::bind(&CWalletInterface::UpdatedTransaction, pwalletIn, _1)); - g_signals.SetBestChain.connect(boost::bind(&CWalletInterface::SetBestChain, pwalletIn, _1)); - g_signals.Inventory.connect(boost::bind(&CWalletInterface::Inventory, pwalletIn, _1)); - g_signals.Broadcast.connect(boost::bind(&CWalletInterface::ResendWalletTransactions, pwalletIn)); + connectionMap[pwalletIn] = g_signals.SyncTransaction.connect([=](const uint256 &hash, const CTransaction &tx, const CBlock *pblock) { + pwalletIn->SyncTransaction(hash, tx, pblock); + }); + g_signals.EraseTransaction.connect([=](const uint256 &hash) { + pwalletIn->EraseFromWallet(hash); + }); + g_signals.UpdatedTransaction.connect([=](const uint256 &hash) { + pwalletIn->UpdatedTransaction(hash); + }); + g_signals.SetBestChain.connect([=](const CBlockLocator &locator) { + pwalletIn->SetBestChain(locator); + }); + g_signals.Inventory.connect([=](const uint256 &hash) { + pwalletIn->Inventory(hash); + }); + g_signals.Broadcast.connect([=]() { + pwalletIn->ResendWalletTransactions(); + }); } void UnregisterWallet(CWalletInterface* pwalletIn) { - g_signals.Broadcast.disconnect(boost::bind(&CWalletInterface::ResendWalletTransactions, pwalletIn)); - g_signals.Inventory.disconnect(boost::bind(&CWalletInterface::Inventory, pwalletIn, _1)); - g_signals.SetBestChain.disconnect(boost::bind(&CWalletInterface::SetBestChain, pwalletIn, _1)); - g_signals.UpdatedTransaction.disconnect(boost::bind(&CWalletInterface::UpdatedTransaction, pwalletIn, _1)); - g_signals.EraseTransaction.disconnect(boost::bind(&CWalletInterface::EraseFromWallet, pwalletIn, _1)); - g_signals.SyncTransaction.disconnect(boost::bind(&CWalletInterface::SyncTransaction, pwalletIn, _1, _2, _3)); + connectionMap[pwalletIn].disconnect(); + // No lambdas should be passed to disconnect(). + // Just call disconnect on the connection } void UnregisterAllWallets() { @@ -208,6 +213,7 @@ void SyncWithWallets(const uint256 &hash, const CTransaction &tx, const CBlock * g_signals.SyncTransaction(hash, tx, pblock); } + ////////////////////////////////////////////////////////////////////////////// // // Registration of network node signals. @@ -432,7 +438,6 @@ unsigned int GetLegacySigOpCount(const CTransaction& tx) return nSigOps; } - bool CheckTransaction(const CTransaction& tx, CValidationState &state) { // Basic checks that don't depend on any context @@ -1013,7 +1018,7 @@ void SystemResync(bool restart){ int64_t oldPid = GetArg("-pid",0LL); //Impossible to check for exit via pid, so use lock - boost::filesystem::path pathLockFile = GetDataDir() / ".lock"; + fs::path pathLockFile = GetDataDir() / ".lock"; static boost::interprocess::file_lock lock(pathLockFile.string().c_str()); while(!lock.try_lock()){ MilliSleep(1000); @@ -1952,47 +1957,50 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo // Size limits if (block.vtx.empty()) return state.DoS(100, error("CheckBlock() : size limits failed"), - REJECT_INVALID, "bad-blk-length"); + REJECT_INVALID, "bad-blk-length"); // First transaction must be coinbase, the rest must not be, genesis TX is non-standard if ((block.vtx.empty() || !block.vtx[0].IsCoinBase()) && block.nHeight != 0) return state.DoS(100, error("CheckBlock() : first tx is not coinbase"), - REJECT_INVALID, "bad-cb-missing"); + REJECT_INVALID, "bad-cb-missing"); // Coinbase lockheight must be = height - if (block.vtx[0].nLockHeight != block.nHeight){ - return state.DoS(100, error("CheckBlock() : coinbase lockheight != block height"), - REJECT_INVALID, "bad-cb-height"); + if (block.vtx[0].nLockHeight != block.nHeight) + { + return state.DoS(100, error("CheckBlock() : coinbase lockheight != block height"), + REJECT_INVALID, "bad-cb-height"); } - for (unsigned int i = 1; i < block.vtx.size(); i++) - if (block.vtx[i].IsCoinBase()) - return state.DoS(100, error("CheckBlock() : more than one coinbase"), - REJECT_INVALID, "bad-cb-multiple"); - // Check transactions if(block.nHeight!=0){ - for (const CTransaction& tx : block.vtx) - if (!CheckTransaction(tx, state)) + for (auto it = block.vtx.begin(); it != block.vtx.end(); ++it) + if (!CheckTransaction(*it, state)) return error("CheckBlock() : CheckTransaction failed"); } //Check for multiple limit updates or withdrawal + limit update combo set setLimit, setWD; - for (const CTransaction& tx : block.vtx){ - if(tx.fSetLimit){ - if(setLimit.count(tx.vin[0].pubKey) || setWD.count(tx.vin[0].pubKey)){ - return error("CheckBlock() : Limit and withdrawal overlap"); - } - setLimit.insert(tx.vin[0].pubKey); - }else{ - for (const CTxIn txin : tx.vin){ - if(setLimit.count(txin.pubKey)){ - return error("CheckBlock() : Limit and withdrawal overlap"); - } - setWD.insert(txin.pubKey); + for (auto it = block.vtx.begin(); it != block.vtx.end(); ++it) + { + if(it->fSetLimit) + { + if(setLimit.count(it->vin[0].pubKey) || setWD.count(it->vin[0].pubKey)) + { + return error("CheckBlock() : Limit and withdrawal overlap"); + } + setLimit.insert(it->vin[0].pubKey); + } + else + { + for (auto txin = it->vin.begin(); txin != it->vin.end(); ++txin) + { + if(setLimit.count(txin->pubKey)) + { + return error("CheckBlock() : Limit and withdrawal overlap"); + } + setWD.insert(txin->pubKey); + } } - } } // Build the merkle tree already. We need it anyway later, and it makes the @@ -2003,24 +2011,25 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo // Check for duplicate txids. This is caught by ConnectInputs(), // but catching it earlier avoids a potential DoS attack: set uniqueTx; - for (unsigned int i = 0; i < block.vtx.size(); i++) { - uniqueTx.insert(block.vtx[i].GetTxID()); + for (const auto& tx : block.vtx) + { + uniqueTx.insert(tx.GetTxID()); } + if (uniqueTx.size() != block.vtx.size()) return state.DoS(100, error("CheckBlock() : duplicate transaction"), - REJECT_INVALID, "bad-txns-duplicate", true); - - unsigned int nSigOps = 0; - for (const CTransaction& tx : block.vtx) - { - nSigOps += GetLegacySigOpCount(tx); - } + REJECT_INVALID, "bad-txns-duplicate", true); + unsigned int nSigOps = 0; + for (const auto& tx : block.vtx) + { + nSigOps += GetLegacySigOpCount(tx); + } + // Check merkle root if (fCheckMerkleRoot && block.hashMerkleRoot != block.vMerkleTree.back()) return state.DoS(100, error("CheckBlock() : hashMerkleRoot mismatch"), - REJECT_INVALID, "bad-txnmrklroot", true); - + REJECT_INVALID, "bad-txnmrklroot", true); return true; } @@ -2036,8 +2045,7 @@ bool static WriteBlockPosition(CBlockIndex *pindexNew, const CBlock &block, cons pindexNew->nStatus = (pindexNew->nStatus & ~BLOCK_VALID_MASK) | BLOCK_VALID_TRANSACTIONS; return pblocktree->WriteBlockIndex(CDiskBlockIndex(pindexNew)); - } - +} bool static AcceptBlockHeader(const CBlockHeader &block, CValidationState& state, CBlockIndex* &pindexNew) { @@ -2536,7 +2544,7 @@ bool AbortNode(const std::string &strMessage) { bool CheckDiskSpace(uint64_t nAdditionalBytes) { - uint64_t nFreeBytesAvailable = filesystem::space(GetDataDir()).available; + uint64_t nFreeBytesAvailable = fs::space(GetDataDir()).available; // Check for nMinDiskSpace bytes (currently 50MB) if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes) @@ -2549,8 +2557,8 @@ FILE* OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, bool fReadOnly) { if (pos.IsNull()) return nullptr; - boost::filesystem::path path = GetDataDir() / "blocks" / strprintf("%s%05u.dat", prefix, pos.nFile); - boost::filesystem::create_directories(path.parent_path()); + fs::path path = GetDataDir() / "blocks" / strprintf("%s%05u.dat", prefix, pos.nFile); + fs::create_directories(path.parent_path()); FILE* file = fopen(path.string().c_str(), "rb+"); if (!file && !fReadOnly) file = fopen(path.string().c_str(), "wb+"); @@ -2578,48 +2586,42 @@ FILE* OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly) { bool static LinkOrphans(const uint256 *phashParent) { bool fWorkDone = false; - const uint256 &hashGenesisBlock = Params().HashGenesisBlock(); + const auto &hashGenesisBlock = Params().HashGenesisBlock(); - deque::iterator> vTodo; + deque::iterator> vTodo; if (phashParent) { - map::iterator itpar = mapBlockIndex.find(*phashParent); + auto itpar = mapBlockIndex.find(*phashParent); if (*phashParent == uint256(0) || (itpar != mapBlockIndex.end() && itpar->second->nHeight != -1)) { - multimap::iterator it = mapOrphanBlocksByPrev.find(*phashParent); - while (it != mapOrphanBlocksByPrev.end() && it->first == *phashParent) { //How would it->first ever not be phashParent? - vTodo.push_back(it); - it++; + auto it = mapOrphanBlocksByPrev.find(*phashParent); + while (it != mapOrphanBlocksByPrev.end() && it->first == *phashParent) { + vTodo.emplace_back(it); + ++it; } } } else { - // First find unconnected blocks whose parent is connected. - for (multimap::iterator it = mapOrphanBlocksByPrev.begin(); it != mapOrphanBlocksByPrev.end(); ) { - multimap::iterator itnow = it++; + for (auto it = mapOrphanBlocksByPrev.begin(); it != mapOrphanBlocksByPrev.end(); ) { + auto itnow = it++; if (itnow->second->fConnected) { mapOrphanBlocksByPrev.erase(itnow); continue; } - map::iterator itprev = mapBlockIndex.find(itnow->first); + auto itprev = mapBlockIndex.find(itnow->first); if (itnow->first == uint256(0) || (itprev != mapBlockIndex.end() && itprev->second->fConnected)) { - vTodo.push_back(itnow); + vTodo.emplace_back(itnow); } } } - // Iterate as long as such parent-connected unconnecteds exist, adding children to the - // queue after adding a node. while (!vTodo.empty()) { - multimap::iterator it = vTodo.front(); - uint256 hashPrev = it->first; - CBlockIndex *pindex = it->second; - mapOrphanBlocksByPrev.erase(it); + auto [hashPrev, pindex] = *vTodo.front(); + mapOrphanBlocksByPrev.erase(vTodo.front()); vTodo.pop_front(); - //printf("vtodo\n"); + if (hashPrev == uint256(0)) { if (pindex->GetBlockHash() != hashGenesisBlock) { continue; } - // Deal with the genesis block specially. pindexGenesisBlock = pindex; pindex->fConnected=true; pindex->nChainWork = pindex->GetBlockWork(); @@ -2637,21 +2639,16 @@ bool static LinkOrphans(const uint256 *phashParent) { } } fWorkDone = true; - //printf("going to insert %d\n", pindex->nStatus); + if (!(pindex->nStatus & BLOCK_FAILED_MASK) && ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TREE)){ - //printf("insert\n"); - pindex->nSequenceId = ++nBlockSequenceId; + pindex->nSequenceId = ++nBlockSequenceId; setBlockIndexValid.insert(pindex); - }else{ - //printf("Couldn't insert %d\n", pindex->nStatus); - } - const uint256 &hashBlock = pindex->GetBlockHash(); - multimap::iterator itadd = mapOrphanBlocksByPrev.lower_bound(hashBlock); + } + const auto &hashBlock = pindex->GetBlockHash(); + auto itadd = mapOrphanBlocksByPrev.lower_bound(hashBlock); while (itadd != mapOrphanBlocksByPrev.end() && itadd->first == hashBlock) - vTodo.push_back(itadd++); + vTodo.emplace_back(itadd++); } - //printf("linkorphans dones\n"); - //printAffairs(); return fWorkDone; } @@ -2695,9 +2692,20 @@ bool static LoadBlockIndexDB() if (!pblocktree->LoadBlockIndexGuts()) return false; -printAffairs(); + printAffairs(); + + // Start timer + auto start = std::chrono::high_resolution_clock::now(); + LinkOrphans(); -printAffairs(); + + // Stop timer and calculate duration + auto stop = std::chrono::high_resolution_clock::now(); + auto duration = std::chrono::duration_cast(stop - start); + + LogPrintf("Time taken by LinkOrphans: %lld microseconds\n", duration.count()); + + printAffairs(); boost::this_thread::interruption_point(); diff --git a/src/mruset.h b/src/mruset.h index c36a0c8..7927499 100644 --- a/src/mruset.h +++ b/src/mruset.h @@ -45,7 +45,7 @@ template class mruset set.erase(queue.front()); queue.pop_front(); } - queue.push_back(x); + queue.emplace_back(x); } return ret; } diff --git a/src/net.h b/src/net.h index fd9d4fc..9a0a52a 100644 --- a/src/net.h +++ b/src/net.h @@ -403,7 +403,7 @@ class CNode // SendMessages will filter it again for knowns that were added // after addresses were pushed. if (addr.IsValid() && !setAddrKnown.count(addr)) - vAddrToSend.push_back(addr); + vAddrToSend.emplace_back(addr); } @@ -420,7 +420,7 @@ class CNode { LOCK(cs_inventory); if (!setInventoryKnown.count(inv)) - vInventoryToSend.push_back(inv); + vInventoryToSend.emplace_back(inv); } } diff --git a/src/qt/Makefile.am b/src/qt/Makefile.am index 434b4d7..1e711a0 100644 --- a/src/qt/Makefile.am +++ b/src/qt/Makefile.am @@ -5,7 +5,7 @@ AM_CPPFLAGS += -I$(top_srcdir)/src \ -I$(top_builddir)/src/qt/forms \ $(PROTOBUF_CFLAGS) \ $(QR_CFLAGS) \ - -fpermissive -ffloat-store -std=c++11 -DQT_NO_KEYWORDS -D__STDC_LIMIT_MACROS -D__USE_MINGW_ANSI_STDIO + -fpermissive -ffloat-store -std=c++17 -DQT_NO_KEYWORDS -D__STDC_LIMIT_MACROS -D__USE_MINGW_ANSI_STDIO bin_PROGRAMS = cryptonite-qt noinst_LIBRARIES = libcryptoniteqt.a SUBDIRS = . diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index 942aec0..380c668 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -129,13 +129,8 @@ void AddressBookPage::setModel(AddressTableModel *model) ui->tableView->sortByColumn(0, Qt::AscendingOrder); // Set column widths -#if QT_VERSION < 0x050000 - ui->tableView->horizontalHeader()->setResizeMode(AddressTableModel::Label, QHeaderView::Stretch); - ui->tableView->horizontalHeader()->setResizeMode(AddressTableModel::Address, QHeaderView::ResizeToContents); -#else ui->tableView->horizontalHeader()->setSectionResizeMode(AddressTableModel::Label, QHeaderView::Stretch); ui->tableView->horizontalHeader()->setSectionResizeMode(AddressTableModel::Address, QHeaderView::ResizeToContents); -#endif connect(ui->tableView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(selectionChanged())); diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index fac4fd9..cc0a389 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -87,8 +87,8 @@ class AddressTablePriv QString::fromStdString(item.second.purpose), fMine); const std::string& strName = item.second.name; cachedAddressTable.append(AddressTableEntry(addressType, - QString::fromStdString(strName), - QString::fromStdString(address.ToString()))); + QString::fromStdString(strName), + QString::fromStdString(address.ToString()))); } } // qLowerBound() and qUpperBound() require our cachedAddressTable list to be sorted in asc order diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 2c0bbbf..c9a94f5 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -7,14 +7,15 @@ #endif #include "bitcoingui.h" - #include "clientmodel.h" #include "guiconstants.h" #include "guiutil.h" #include "intro.h" #include "optionsmodel.h" +#include "scheduler.h" #include "splashscreen.h" #include "utilitydialog.h" + #ifdef ENABLE_WALLET #include "paymentserver.h" #include "walletmodel.h" @@ -26,13 +27,13 @@ #include "scheduler.h" #include "ui_interface.h" #include "util.h" + #ifdef ENABLE_WALLET #include "wallet.h" #endif #include #include - #include #include #include @@ -40,26 +41,13 @@ #include #include #include +#include #include #include -#include #if defined(QT_STATICPLUGIN) #include -#if QT_VERSION < 0x050000 -Q_IMPORT_PLUGIN(qcncodecs) -Q_IMPORT_PLUGIN(qjpcodecs) -Q_IMPORT_PLUGIN(qtwcodecs) -Q_IMPORT_PLUGIN(qkrcodecs) -Q_IMPORT_PLUGIN(qtaccessiblewidgets) -#else -#if QT_VERSION < 0x050400 -Q_IMPORT_PLUGIN(AccessibleFactory) Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin) -#else -Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin) -#endif -#endif #endif #if defined(QT_QPA_PLATFORM_XCB) @@ -67,10 +55,6 @@ Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin) Q_IMPORT_PLUGIN(QXcbIntegrationPlugin); #endif -#if QT_VERSION < 0x050000 -#include -#endif - // Declare meta types used for QMetaObject::invokeMethod Q_DECLARE_METATYPE(bool*) @@ -134,20 +118,12 @@ static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTrans } /* qDebug() message handler --> debug.log */ -#if QT_VERSION < 0x050000 -void DebugMessageHandler(QtMsgType type, const char *msg) -{ - Q_UNUSED(type); - LogPrint("qt", "GUI: %s\n", msg); -} -#else void DebugMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString &msg) { Q_UNUSED(type); Q_UNUSED(context); LogPrint("qt", "GUI: %s\n", qPrintable(msg)); } -#endif /** Class encapsulating Bitcoin Core startup and shutdown. * Allows running startup and shutdown in a different thread from the UI thread. @@ -476,25 +452,17 @@ int main(int argc, char *argv[]) // Do not refer to data directory yet, this can be overridden by Intro::pickDataDirectory - /// 2. Basic Qt initialization (not dependent on parameters or configuration) -#if QT_VERSION < 0x050000 - // Internal string conversion is all UTF-8 - QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8")); - QTextCodec::setCodecForCStrings(QTextCodec::codecForTr()); -#endif + // Enable high-dpi features + QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); + QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + + #ifdef Q_OS_MAC + QApplication::setAttribute(Qt::AA_DontShowIconsInMenus); + #endif + /// 2. Basic Qt initialization (not dependent on parameters or configuration) Q_INIT_RESOURCE(bitcoin); BitcoinApplication app(argc, argv); -#if QT_VERSION > 0x050100 - // Generate high-dpi pixmaps - QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); -#endif -#if QT_VERSION >= 0x050600 - QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); -#endif -#ifdef Q_OS_MAC - QApplication::setAttribute(Qt::AA_DontShowIconsInMenus); -#endif // Register meta types used for QMetaObject::invokeMethod qRegisterMetaType< bool* >(); @@ -582,14 +550,13 @@ int main(int argc, char *argv[]) #endif /// 9. Main GUI initialization + // Install global event filter that makes sure that long tooltips can be word-wrapped app.installEventFilter(new GUIUtil::ToolTipToRichTextFilter(TOOLTIP_WRAP_THRESHOLD, &app)); + // Install qDebug() message handler to route to debug.log -#if QT_VERSION < 0x050000 - qInstallMsgHandler(DebugMessageHandler); -#else qInstallMessageHandler(DebugMessageHandler); -#endif + // Load GUI settings from QSettings app.createOptionsModel(); diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc index 263ff5f..703e8a3 100644 --- a/src/qt/bitcoin.qrc +++ b/src/qt/bitcoin.qrc @@ -53,36 +53,6 @@ res/movies/spinner-002.png res/movies/spinner-003.png res/movies/spinner-004.png - res/movies/spinner-005.png - res/movies/spinner-006.png - res/movies/spinner-007.png - res/movies/spinner-008.png - res/movies/spinner-009.png - res/movies/spinner-010.png - res/movies/spinner-011.png - res/movies/spinner-012.png - res/movies/spinner-013.png - res/movies/spinner-014.png - res/movies/spinner-015.png - res/movies/spinner-016.png - res/movies/spinner-017.png - res/movies/spinner-018.png - res/movies/spinner-019.png - res/movies/spinner-020.png - res/movies/spinner-021.png - res/movies/spinner-022.png - res/movies/spinner-023.png - res/movies/spinner-024.png - res/movies/spinner-025.png - res/movies/spinner-026.png - res/movies/spinner-027.png - res/movies/spinner-028.png - res/movies/spinner-029.png - res/movies/spinner-030.png - res/movies/spinner-031.png - res/movies/spinner-032.png - res/movies/spinner-033.png - res/movies/spinner-034.png locale/bitcoin_ach.qm diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index e230097..f56abdf 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -3,17 +3,20 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "bitcoingui.h" - #include "bitcoinunits.h" #include "clientmodel.h" +#include "core.h" #include "guiconstants.h" #include "guiutil.h" +#include "init.h" #include "notificator.h" #include "openuridialog.h" #include "optionsdialog.h" #include "optionsmodel.h" #include "rpcconsole.h" #include "utilitydialog.h" +#include "ui_interface.h" + #ifdef ENABLE_WALLET #include "walletframe.h" #include "walletmodel.h" @@ -23,12 +26,9 @@ #include "macdockiconhandler.h" #endif -#include "init.h" -#include "ui_interface.h" -#include "core.h" - #include +#include #include #include #include @@ -49,13 +49,9 @@ #include #include #include - -#if QT_VERSION < 0x050000 -#include -#include -#else #include -#endif + +using namespace boost::placeholders; const QString BitcoinGUI::DEFAULT_WALLET = "~Default"; @@ -89,7 +85,6 @@ BitcoinGUI::BitcoinGUI(bool fIsTestnet, QWidget *parent) : darkPalette.setColor(QPalette::ButtonText, Qt::white); darkPalette.setColor(QPalette::BrightText, Qt::red); darkPalette.setColor(QPalette::Link, QColor(42, 130, 218)); - darkPalette.setColor(QPalette::Highlight, QColor(42, 130, 218)); darkPalette.setColor(QPalette::HighlightedText, Qt::black); @@ -132,12 +127,6 @@ BitcoinGUI::BitcoinGUI(bool fIsTestnet, QWidget *parent) : } setWindowTitle(windowTitle); -#if defined(Q_OS_MAC) && QT_VERSION < 0x050000 - // This property is not implemented in Qt 5. Setting it has no effect. - // A replacement API (QtMacUnifiedToolBar) is available in QtMacExtras. - setUnifiedTitleAndToolBarOnMac(true); -#endif - rpcConsole = new RPCConsole(0); #ifdef ENABLE_WALLET if(enableWallet) @@ -198,13 +187,24 @@ BitcoinGUI::BitcoinGUI(bool fIsTestnet, QWidget *parent) : progressBar->setAlignment(Qt::AlignCenter); progressBar->setVisible(false); - // Override style sheet for progress bar for styles that have a segmented progress bar, - // as they make the text unreadable (workaround for issue #1071) - // See https://qt-project.org/doc/qt-4.8/gallery.html QString curStyle = QApplication::style()->metaObject()->className(); - if(curStyle == "QWindowsStyle" || curStyle == "QWindowsXPStyle") + + if (curStyle == "QWindowsStyle" || curStyle == "QWindowsXPStyle") { - progressBar->setStyleSheet("QProgressBar { background-color: #e8e8e8; border: 1px solid grey; border-radius: 7px; padding: 1px; text-align: center; } QProgressBar::chunk { background: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #FF8000, stop: 1 orange); border-radius: 7px; margin: 0px; }"); + QString progressBarStyleSheet = "QProgressBar {" + " background-color: #e8e8e8;" + " border: 1px solid grey;" + " border-radius: 7px;" + " padding: 1px;" + " text-align: center;" + "}" + "QProgressBar::chunk {" + " background: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #FF8000, stop: 1 orange);" + " border-radius: 7px;" + " margin: 0px;" + "}"; + + progressBar->setStyleSheet(progressBarStyleSheet); } statusBar()->addWidget(progressBarLabel); @@ -295,11 +295,7 @@ void BitcoinGUI::createActions(bool fIsTestnet) aboutAction = new QAction(QIcon(":/icons/bitcoin_testnet"), tr("&About Cryptonite"), this); aboutAction->setStatusTip(tr("Show information about Cryptonite")); aboutAction->setMenuRole(QAction::AboutRole); -#if QT_VERSION < 0x050000 - aboutQtAction = new QAction(QIcon(":/trolltech/qmessagebox/images/qtlogo-64.png"), tr("About &Qt"), this); -#else aboutQtAction = new QAction(QIcon(":/qt-project.org/qmessagebox/images/qtlogo-64.png"), tr("About &Qt"), this); -#endif aboutQtAction->setStatusTip(tr("Show information about Qt")); aboutQtAction->setMenuRole(QAction::AboutQtRole); optionsAction = new QAction(QIcon(":/icons/options"), tr("&Options..."), this); diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index d160807..33aacde 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -3,7 +3,6 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "clientmodel.h" - #include "guiconstants.h" #include "peertablemodel.h" @@ -14,22 +13,22 @@ #include "net.h" #include "ui_interface.h" +#include + #include #include #include #include +using namespace boost::placeholders; + static const int64_t nClientStartupTime = GetTime(); ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) : QObject(parent), optionsModel(optionsModel), peerTableModel(0), - cachedNumBlocks(0), cachedNumHeaders(0), - cachedReindexing(0), cachedImporting(0), - cachedTrieOnline(0), cachedTotalMissing(0), - cachedTrieComplete(0), cachedValidating(0), - cachedProgress(0), nProgress(0), - numBlocksAtStartup(-1), pollTimer(0) + cachedState({0, 0, 0, 0, false, false, false, false, 0.0}), + nProgress(0), numBlocksAtStartup(-1), pollTimer(0) { peerTableModel = new PeerTableModel(this); pollTimer = new QTimer(this); @@ -135,35 +134,25 @@ double ClientModel::getVerificationProgress() const return Checkpoints::GuessVerificationProgress(chainActive.Tip()); } -void ClientModel::updateTimer() -{ - // Some quantities (such as number of blocks) change so fast that we don't want to be notified for each change. - // Periodically check and update with a timer. - int newNumBlocks = getNumBlocks(); - int newNumHeaders = getNumHeaders(); - int totalMissing = getTotalMissing(); - int trieComplete = getTrieComplete(); - - //printf("Tick\n"); - - // check for changed number of blocks we have, number of blocks peers claim to have, reindexing state and importing state - if (cachedNumBlocks != newNumBlocks || cachedNumHeaders != newNumHeaders || - cachedReindexing != fReindex || cachedImporting != fImporting || cachedTrieOnline != fTrieOnline || - cachedTotalMissing != totalMissing || cachedTrieComplete != trieComplete || cachedValidating != fValidating || - cachedProgress != nProgress) - { - cachedNumBlocks = newNumBlocks; - cachedNumHeaders = newNumHeaders; - cachedTotalMissing = totalMissing; - cachedReindexing = fReindex; - cachedImporting = fImporting; - cachedTrieOnline = fTrieOnline; - cachedTrieComplete = trieComplete; - cachedValidating = fValidating; - cachedProgress = nProgress; - - // ensure we return the maximum of newNumBlocksTotal and newNumBlocks to not create weird displays in the GUI - Q_EMIT numBlocksChanged(newNumBlocks, newNumHeaders); +void ClientModel::updateTimer() { + // Create a new state + ClientModelState newState = { + getNumBlocks(), + getNumHeaders(), + getTotalMissing(), + getTrieComplete(), + fReindex, + fImporting, + fTrieOnline, + fValidating, + nProgress + }; + + // Compare the new state with the old one + if (memcmp(&cachedState, &newState, sizeof(ClientModelState)) != 0) { + // If they're different, update the old state and emit signals + memcpy(&cachedState, &newState, sizeof(ClientModelState)); + Q_EMIT numBlocksChanged(cachedState.numBlocks, cachedState.numHeaders); } Q_EMIT bytesChanged(getTotalBytesRecv(), getTotalBytesSent()); @@ -259,8 +248,8 @@ QString ClientModel::dataDir() const // Handlers for core signals static void NotifyBlocksChanged(ClientModel *clientmodel) { - // This notification is too frequent. Don't trigger a signal. - // Don't remove it, though, as it might be useful later. + // This notification is too frequent. Don't trigger a signal. + // Don't remove it, though, as it might be useful later. } static void NotifyNumConnectionsChanged(ClientModel *clientmodel, int newNumConnections) diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index a1508eb..27bc16f 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -6,6 +6,7 @@ #define CLIENTMODEL_H #include +#include class AddressTableModel; class OptionsModel; @@ -38,6 +39,18 @@ class ClientModel : public QObject { Q_OBJECT +struct ClientModelState { + int numBlocks; + int numHeaders; + int totalMissing; + int trieComplete; + bool reindex; + bool importing; + bool trieOnline; + bool validating; + double progress; +}; + public: explicit ClientModel(OptionsModel *optionsModel, QObject *parent = 0); ~ClientModel(); @@ -85,16 +98,9 @@ class ClientModel : public QObject OptionsModel *optionsModel; PeerTableModel *peerTableModel; - int cachedNumBlocks; - int cachedNumHeaders; - int cachedTotalMissing; - int cachedTrieComplete; - bool cachedReindexing; - bool cachedImporting; - bool cachedTrieOnline; - bool cachedValidating; + ClientModelState cachedState; + int numBlocksAtStartup; - int cachedProgress; QTimer *pollTimer; @@ -116,4 +122,4 @@ public Q_SLOTS: void updateAlert(const QString &hash, int status); }; -#endif // CLIENTMODEL_H +#endif // CLIENTMODEL_H \ No newline at end of file diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 67c4081..6bfbc5a 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -26,6 +26,7 @@ #include using namespace std; + QList CoinControlDialog::payAmounts; CoinControlDialog::CoinControlDialog(QWidget *parent) : @@ -98,11 +99,7 @@ CoinControlDialog::CoinControlDialog(QWidget *parent) : connect(ui->treeWidget, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(viewItemChanged(QTreeWidgetItem*, int))); // click on header -#if QT_VERSION < 0x050000 - ui->treeWidget->header()->setClickable(true); -#else ui->treeWidget->header()->setSectionsClickable(true); -#endif connect(ui->treeWidget->header(), SIGNAL(sectionClicked(int)), this, SLOT(headerSectionClicked(int))); // ok button @@ -383,13 +380,11 @@ void CoinControlDialog::viewItemChanged(QTreeWidgetItem* item, int column) // including all childs are partially selected. But the parent node should be fully selected // as well as the childs. Childs should never be partially selected in the first place. // Please remove this ugly fix, once the bug is solved upstream. -#if QT_VERSION >= 0x050000 - else if (column == COLUMN_CHECKBOX && item->childCount() > 0) + if (column == COLUMN_CHECKBOX && item->childCount() > 0) { if (item->checkState(COLUMN_CHECKBOX) == Qt::PartiallyChecked && item->child(0)->checkState(COLUMN_CHECKBOX) == Qt::PartiallyChecked) item->setCheckState(COLUMN_CHECKBOX, Qt::Checked); } -#endif #else assert(0); #endif @@ -649,7 +644,7 @@ void CoinControlDialog::updateView() map > mapCoins; model->listCoins(mapCoins); - for (std::pair> coins : mapCoins) + for (std::pair> coins : mapCoins) { QTreeWidgetItem *itemWalletAddress = new QTreeWidgetItem(); itemWalletAddress->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked); diff --git a/src/qt/forms/debugwindow.ui b/src/qt/forms/debugwindow.ui index f2712b1..3390b3c 100644 --- a/src/qt/forms/debugwindow.ui +++ b/src/qt/forms/debugwindow.ui @@ -1,7 +1,7 @@ RPCConsole - + 0 @@ -22,7 +22,7 @@ - 0 + 3 @@ -960,7 +960,7 @@ - + Services diff --git a/src/qt/guiconstants.h b/src/qt/guiconstants.h index a7fcd9a..da1e3b3 100644 --- a/src/qt/guiconstants.h +++ b/src/qt/guiconstants.h @@ -39,7 +39,7 @@ static const int MAX_PAYMENT_REQUEST_SIZE = 50000; // bytes #define EXPORT_IMAGE_SIZE 256 /* Number of frames in spinner animation */ -#define SPINNER_FRAMES 35 +#define SPINNER_FRAMES 5 #define QAPP_ORG_NAME "Mini-Blockchain" #define QAPP_ORG_DOMAIN "cryptonite.info" diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 9911f89..cfeb83d 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -16,21 +16,10 @@ #include "util.h" #ifdef WIN32 -#ifdef _WIN32_WINNT -#undef _WIN32_WINNT -#endif -#define _WIN32_WINNT 0x0501 -#ifdef _WIN32_IE -#undef _WIN32_IE -#endif -#define _WIN32_IE 0x0501 -#define WIN32_LEAN_AND_MEAN 1 -#ifndef NOMINMAX #define NOMINMAX -#endif +#define WIN32_LEAN_AND_MEAN + #include "shellapi.h" -#include "shlobj.h" -#include "shlwapi.h" #endif #include @@ -43,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -52,12 +42,7 @@ #include #include // for Qt::mightBeRichText #include - -#if QT_VERSION < 0x050000 -#include -#else #include -#endif #if BOOST_FILESYSTEM_VERSION >= 3 static boost::filesystem::detail::utf8_codecvt_facet utf8; @@ -78,11 +63,7 @@ QString dateTimeStr(qint64 nTime) QFont bitcoinAddressFont() { QFont font("Monospace"); -#if QT_VERSION >= 0x040800 font.setStyleHint(QFont::Monospace); -#else - font.setStyleHint(QFont::TypeWriter); -#endif return font; } @@ -91,9 +72,7 @@ void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent) parent->setFocusProxy(widget); widget->setFont(bitcoinAddressFont()); -#if QT_VERSION >= 0x040700 widget->setPlaceholderText(QObject::tr("Enter a Cryptonite address (e.g. CNS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)")); -#endif widget->setValidator(new BitcoinAddressEntryValidator(parent)); widget->setCheckValidator(new BitcoinAddressCheckValidator(parent)); } @@ -117,12 +96,9 @@ bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out) rv.address = uri.path(); rv.amount = 0; -#if QT_VERSION < 0x050000 - QList > items = uri.queryItems(); -#else QUrlQuery uriQuery(uri); QList > items = uriQuery.queryItems(); -#endif + for (QList >::iterator i = items.begin(); i != items.end(); i++) { bool fShouldReturnFalse = false; @@ -202,11 +178,8 @@ bool isDust(const QString& address, qint64 amount) QString HtmlEscape(const QString& str, bool fMultiLine) { -#if QT_VERSION < 0x050000 - QString escaped = Qt::escape(str); -#else QString escaped = str.toHtmlEscaped(); -#endif + if(fMultiLine) { escaped = escaped.replace("\n", "
\n"); @@ -240,11 +213,7 @@ QString getSaveFileName(QWidget *parent, const QString &caption, const QString & QString myDir; if(dir.isEmpty()) // Default to user documents location { -#if QT_VERSION < 0x050000 - myDir = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation); -#else myDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); -#endif } else { @@ -290,11 +259,7 @@ QString getOpenFileName(QWidget *parent, const QString &caption, const QString & QString myDir; if(dir.isEmpty()) // Default to user documents location { -#if QT_VERSION < 0x050000 - myDir = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation); -#else myDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); -#endif } else { @@ -395,11 +360,7 @@ void TableViewLastColumnResizingFixer::disconnectViewHeadersSignals() // Refactored here for readability. void TableViewLastColumnResizingFixer::setViewHeaderResizeMode(int logicalIndex, QHeaderView::ResizeMode resizeMode) { -#if QT_VERSION < 0x050000 - tableView->horizontalHeader()->setResizeMode(logicalIndex, resizeMode); -#else tableView->horizontalHeader()->setSectionResizeMode(logicalIndex, resizeMode); -#endif } void TableViewLastColumnResizingFixer::resizeColumn(int nColumnIndex, int width) @@ -496,70 +457,43 @@ TableViewLastColumnResizingFixer::TableViewLastColumnResizingFixer(QTableView* t } #ifdef WIN32 +QString static StartupRegistryPath() +{ + return "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"; +} + +QString static StartupRegistryKey() +{ + return "Cryptonite"; +} + boost::filesystem::path static StartupShortcutPath() { - return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin.lnk"; + return StartupRegistryPath().toStdString() + "\\" + StartupRegistryKey().toStdString(); } bool GetStartOnSystemStartup() { - // check for Bitcoin.lnk - return boost::filesystem::exists(StartupShortcutPath()); + QSettings registry(StartupRegistryPath(), QSettings::NativeFormat); + return registry.contains(StartupRegistryKey()); } bool SetStartOnSystemStartup(bool fAutoStart) { - // If the shortcut exists already, remove it for updating - boost::filesystem::remove(StartupShortcutPath()); + QSettings registry(StartupRegistryPath(), QSettings::NativeFormat); if (fAutoStart) { - CoInitialize(nullptr); - - // Get a pointer to the IShellLink interface. - IShellLink* psl = nullptr; - HRESULT hres = CoCreateInstance(CLSID_ShellLink, nullptr, - CLSCTX_INPROC_SERVER, IID_IShellLink, - reinterpret_cast(&psl)); - - if (SUCCEEDED(hres)) - { - // Get the current executable path - TCHAR pszExePath[MAX_PATH]; - GetModuleFileName(nullptr, pszExePath, sizeof(pszExePath)); - - TCHAR pszArgs[5] = TEXT("-min"); - - // Set the path to the shortcut target - psl->SetPath(pszExePath); - PathRemoveFileSpec(pszExePath); - psl->SetWorkingDirectory(pszExePath); - psl->SetShowCmd(SW_SHOWMINNOACTIVE); - psl->SetArguments(pszArgs); - - // Query IShellLink for the IPersistFile interface for - // saving the shortcut in persistent storage. - IPersistFile* ppf = nullptr; - hres = psl->QueryInterface(IID_IPersistFile, - reinterpret_cast(&ppf)); - if (SUCCEEDED(hres)) - { - WCHAR pwsz[MAX_PATH]; - // Ensure that the string is ANSI. - MultiByteToWideChar(CP_ACP, 0, StartupShortcutPath().string().c_str(), -1, pwsz, MAX_PATH); - // Save the link by calling IPersistFile::Save. - hres = ppf->Save(pwsz, TRUE); - ppf->Release(); - psl->Release(); - CoUninitialize(); - return true; - } - psl->Release(); - } - CoUninitialize(); - return false; + QString appPath = QCoreApplication::applicationFilePath(); + appPath = QDir::toNativeSeparators(appPath); + registry.setValue(StartupRegistryKey(), appPath + " -min"); } - return true; + else + { + registry.remove(StartupRegistryKey()); + } + + return fAutoStart == GetStartOnSystemStartup(); } #elif defined(Q_OS_LINUX) diff --git a/src/qt/macdockiconhandler.mm b/src/qt/macdockiconhandler.mm index 64291c9..83796bb 100644 --- a/src/qt/macdockiconhandler.mm +++ b/src/qt/macdockiconhandler.mm @@ -12,10 +12,6 @@ #undef slots #include -#if QT_VERSION < 0x050000 -extern void qt_mac_set_dock_menu(QMenu *); -#endif - @interface DockIconClickEventHandler : NSObject { MacDockIconHandler* dockIconHandler; @@ -60,9 +56,6 @@ - (void)handleDockClickEvent:(NSAppleEventDescriptor*)event withReplyEvent:(NSAp this->m_dummyWidget = new QWidget(); this->m_dockMenu = new QMenu(this->m_dummyWidget); this->setMainWindow(NULL); -#if QT_VERSION < 0x050000 - qt_mac_set_dock_menu(this->m_dockMenu); -#endif [pool release]; } diff --git a/src/qt/openuridialog.cpp b/src/qt/openuridialog.cpp index ebd234c..5892caf 100644 --- a/src/qt/openuridialog.cpp +++ b/src/qt/openuridialog.cpp @@ -15,9 +15,7 @@ OpenURIDialog::OpenURIDialog(QWidget *parent) : ui(new Ui::OpenURIDialog) { ui->setupUi(this); -#if QT_VERSION >= 0x040700 ui->uriEdit->setPlaceholderText("cryptonite:"); -#endif } OpenURIDialog::~OpenURIDialog() diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index a938525..5b360bb 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -76,23 +76,13 @@ OptionsDialog::OptionsDialog(QWidget *parent) : /** check if the locale name consists of 2 parts (language_country) */ if(langStr.contains("_")) { -#if QT_VERSION >= 0x040800 /** display language strings as "native language - native country (locale name)", e.g. "Deutsch - Deutschland (de)" */ ui->lang->addItem(locale.nativeLanguageName() + QString(" - ") + locale.nativeCountryName() + QString(" (") + langStr + QString(")"), QVariant(langStr)); -#else - /** display language strings as "language - country (locale name)", e.g. "German - Germany (de)" */ - ui->lang->addItem(QLocale::languageToString(locale.language()) + QString(" - ") + QLocale::countryToString(locale.country()) + QString(" (") + langStr + QString(")"), QVariant(langStr)); -#endif } else { -#if QT_VERSION >= 0x040800 /** display language strings as "native language (locale name)", e.g. "Deutsch (de)" */ ui->lang->addItem(locale.nativeLanguageName() + QString(" (") + langStr + QString(")"), QVariant(langStr)); -#else - /** display language strings as "language (locale name)", e.g. "German (de)" */ - ui->lang->addItem(QLocale::languageToString(locale.language()) + QString(" (") + langStr + QString(")"), QVariant(langStr)); -#endif } } diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp index 5fe9695..14b56dd 100644 --- a/src/qt/paymentrequestplus.cpp +++ b/src/qt/paymentrequestplus.cpp @@ -106,12 +106,10 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c qDebug() << "PaymentRequestPlus::getMerchant : Payment request: certificate expired or not yet active: " << qCert; return false; } -#if QT_VERSION >= 0x050000 if (qCert.isBlacklisted()) { qDebug() << "PaymentRequestPlus::getMerchant : Payment request: certificate blacklisted: " << qCert; return false; } -#endif const unsigned char *data = (const unsigned char *)certChain.certificate(i).data(); X509 *cert = d2i_X509(nullptr, &data, certChain.certificate(i).size()); if (cert) diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 3774adb..67924d7 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -37,12 +37,8 @@ #include #include #include - -#if QT_VERSION < 0x050000 -#include -#else #include -#endif + using namespace boost; @@ -138,12 +134,11 @@ void PaymentServer::LoadRootCAs(X509_STORE* _store) ReportInvalidCertificate(cert); continue; } -#if QT_VERSION >= 0x050000 if (cert.isBlacklisted()) { ReportInvalidCertificate(cert); continue; } -#endif + QByteArray certData = cert.toDer(); const unsigned char *data = (const unsigned char *)certData.data(); @@ -380,11 +375,8 @@ void PaymentServer::handleURIOrFile(const QString& s) if (s.startsWith(BITCOIN_IPC_PREFIX, Qt::CaseInsensitive)) // bitcoin: URI { -#if QT_VERSION < 0x050000 - QUrl uri(s); -#else QUrlQuery uri((QUrl(s))); -#endif + if (uri.hasQueryItem("r")) // payment request URI { QByteArray temp; diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp index 2cd96bf..724a585 100644 --- a/src/qt/peertablemodel.cpp +++ b/src/qt/peertablemodel.cpp @@ -62,9 +62,8 @@ class PeerTablePriv return; } cachedNodeStats.clear(); -#if QT_VERSION >= 0x040700 cachedNodeStats.reserve(vNodes.size()); -#endif + for (CNode* pnode : vNodes) { CNodeCombinedStats stats; @@ -75,9 +74,15 @@ class PeerTablePriv } } - // Try to retrieve the CNodeStateStats for each node. - for (CNodeCombinedStats &stats : cachedNodeStats) - stats.fNodeStateStatsAvailable = GetNodeStateStats(stats.nodeStats.nodeid, stats.nodeStateStats); + { + TRY_LOCK(cs_main, lockMain); + if (lockMain) + { + // Try to retrieve the CNodeStateStats for each node. + for (CNodeCombinedStats &stats : cachedNodeStats) + stats.fNodeStateStatsAvailable = GetNodeStateStats(stats.nodeStats.nodeid, stats.nodeStateStats); + } + } if (sortColumn >= 0) // sort cacheNodeStats (use stable sort to prevent rows jumping around unneceesarily) diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index d4cc862..f3bfc1c 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -180,7 +180,8 @@ void ReceiveCoinsDialog::on_showRequestButton_clicked() return; QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows(); - for (const QModelIndex& index : selection) { + for (const QModelIndex& index : selection) + { on_recentRequestsView_doubleClicked(index); } } diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp index 83525c8..bcddc78 100644 --- a/src/qt/receiverequestdialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -15,10 +15,8 @@ #include #include #include +#include #include -#if QT_VERSION < 0x050000 -#include -#endif #if defined(HAVE_CONFIG_H) #include "bitcoin-config.h" /* for USE_QRCODE */ @@ -34,10 +32,11 @@ QRImageWidget::QRImageWidget(QWidget *parent): setContextMenuPolicy(Qt::ActionsContextMenu); QAction *saveImageAction = new QAction(tr("&Save Image..."), this); - connect(saveImageAction, SIGNAL(triggered()), this, SLOT(saveImage())); + connect(saveImageAction, &QAction::triggered, this, &QRImageWidget::saveImage); addAction(saveImageAction); + QAction *copyImageAction = new QAction(tr("&Copy Image"), this); - connect(copyImageAction, SIGNAL(triggered()), this, SLOT(copyImage())); + connect(copyImageAction, &QAction::triggered, this, &QRImageWidget::copyImage); addAction(copyImageAction); } diff --git a/src/qt/res/movies/spinner-005.png b/src/qt/res/movies/spinner-005.png deleted file mode 100644 index 153330f..0000000 Binary files a/src/qt/res/movies/spinner-005.png and /dev/null differ diff --git a/src/qt/res/movies/spinner-006.png b/src/qt/res/movies/spinner-006.png deleted file mode 100644 index 16996ce..0000000 Binary files a/src/qt/res/movies/spinner-006.png and /dev/null differ diff --git a/src/qt/res/movies/spinner-007.png b/src/qt/res/movies/spinner-007.png deleted file mode 100644 index 8bff4d7..0000000 Binary files a/src/qt/res/movies/spinner-007.png and /dev/null differ diff --git a/src/qt/res/movies/spinner-008.png b/src/qt/res/movies/spinner-008.png deleted file mode 100644 index c48d9e4..0000000 Binary files a/src/qt/res/movies/spinner-008.png and /dev/null differ diff --git a/src/qt/res/movies/spinner-009.png b/src/qt/res/movies/spinner-009.png deleted file mode 100644 index 6d4f2c5..0000000 Binary files a/src/qt/res/movies/spinner-009.png and /dev/null differ diff --git a/src/qt/res/movies/spinner-010.png b/src/qt/res/movies/spinner-010.png deleted file mode 100644 index 153330f..0000000 Binary files a/src/qt/res/movies/spinner-010.png and /dev/null differ diff --git a/src/qt/res/movies/spinner-011.png b/src/qt/res/movies/spinner-011.png deleted file mode 100644 index 16996ce..0000000 Binary files a/src/qt/res/movies/spinner-011.png and /dev/null differ diff --git a/src/qt/res/movies/spinner-012.png b/src/qt/res/movies/spinner-012.png deleted file mode 100644 index 8bff4d7..0000000 Binary files a/src/qt/res/movies/spinner-012.png and /dev/null differ diff --git a/src/qt/res/movies/spinner-013.png b/src/qt/res/movies/spinner-013.png deleted file mode 100644 index c48d9e4..0000000 Binary files a/src/qt/res/movies/spinner-013.png and /dev/null differ diff --git a/src/qt/res/movies/spinner-014.png b/src/qt/res/movies/spinner-014.png deleted file mode 100644 index 6d4f2c5..0000000 Binary files a/src/qt/res/movies/spinner-014.png and /dev/null differ diff --git a/src/qt/res/movies/spinner-015.png b/src/qt/res/movies/spinner-015.png deleted file mode 100644 index 153330f..0000000 Binary files a/src/qt/res/movies/spinner-015.png and /dev/null differ diff --git a/src/qt/res/movies/spinner-016.png b/src/qt/res/movies/spinner-016.png deleted file mode 100644 index 16996ce..0000000 Binary files a/src/qt/res/movies/spinner-016.png and /dev/null differ diff --git a/src/qt/res/movies/spinner-017.png b/src/qt/res/movies/spinner-017.png deleted file mode 100644 index 8bff4d7..0000000 Binary files a/src/qt/res/movies/spinner-017.png and /dev/null differ diff --git a/src/qt/res/movies/spinner-018.png b/src/qt/res/movies/spinner-018.png deleted file mode 100644 index c48d9e4..0000000 Binary files a/src/qt/res/movies/spinner-018.png and /dev/null differ diff --git a/src/qt/res/movies/spinner-019.png b/src/qt/res/movies/spinner-019.png deleted file mode 100644 index 6d4f2c5..0000000 Binary files a/src/qt/res/movies/spinner-019.png and /dev/null differ diff --git a/src/qt/res/movies/spinner-020.png b/src/qt/res/movies/spinner-020.png deleted file mode 100644 index 153330f..0000000 Binary files a/src/qt/res/movies/spinner-020.png and /dev/null differ diff --git a/src/qt/res/movies/spinner-021.png b/src/qt/res/movies/spinner-021.png deleted file mode 100644 index 16996ce..0000000 Binary files a/src/qt/res/movies/spinner-021.png and /dev/null differ diff --git a/src/qt/res/movies/spinner-022.png b/src/qt/res/movies/spinner-022.png deleted file mode 100644 index 8bff4d7..0000000 Binary files a/src/qt/res/movies/spinner-022.png and /dev/null differ diff --git a/src/qt/res/movies/spinner-023.png b/src/qt/res/movies/spinner-023.png deleted file mode 100644 index c48d9e4..0000000 Binary files a/src/qt/res/movies/spinner-023.png and /dev/null differ diff --git a/src/qt/res/movies/spinner-024.png b/src/qt/res/movies/spinner-024.png deleted file mode 100644 index 6d4f2c5..0000000 Binary files a/src/qt/res/movies/spinner-024.png and /dev/null differ diff --git a/src/qt/res/movies/spinner-025.png b/src/qt/res/movies/spinner-025.png deleted file mode 100644 index 153330f..0000000 Binary files a/src/qt/res/movies/spinner-025.png and /dev/null differ diff --git a/src/qt/res/movies/spinner-026.png b/src/qt/res/movies/spinner-026.png deleted file mode 100644 index 16996ce..0000000 Binary files a/src/qt/res/movies/spinner-026.png and /dev/null differ diff --git a/src/qt/res/movies/spinner-027.png b/src/qt/res/movies/spinner-027.png deleted file mode 100644 index 8bff4d7..0000000 Binary files a/src/qt/res/movies/spinner-027.png and /dev/null differ diff --git a/src/qt/res/movies/spinner-028.png b/src/qt/res/movies/spinner-028.png deleted file mode 100644 index c48d9e4..0000000 Binary files a/src/qt/res/movies/spinner-028.png and /dev/null differ diff --git a/src/qt/res/movies/spinner-029.png b/src/qt/res/movies/spinner-029.png deleted file mode 100644 index 6d4f2c5..0000000 Binary files a/src/qt/res/movies/spinner-029.png and /dev/null differ diff --git a/src/qt/res/movies/spinner-030.png b/src/qt/res/movies/spinner-030.png deleted file mode 100644 index 153330f..0000000 Binary files a/src/qt/res/movies/spinner-030.png and /dev/null differ diff --git a/src/qt/res/movies/spinner-031.png b/src/qt/res/movies/spinner-031.png deleted file mode 100644 index 16996ce..0000000 Binary files a/src/qt/res/movies/spinner-031.png and /dev/null differ diff --git a/src/qt/res/movies/spinner-032.png b/src/qt/res/movies/spinner-032.png deleted file mode 100644 index 8bff4d7..0000000 Binary files a/src/qt/res/movies/spinner-032.png and /dev/null differ diff --git a/src/qt/res/movies/spinner-033.png b/src/qt/res/movies/spinner-033.png deleted file mode 100644 index c48d9e4..0000000 Binary files a/src/qt/res/movies/spinner-033.png and /dev/null differ diff --git a/src/qt/res/movies/spinner-034.png b/src/qt/res/movies/spinner-034.png deleted file mode 100644 index 6d4f2c5..0000000 Binary files a/src/qt/res/movies/spinner-034.png and /dev/null differ diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index a2a516a..4585d67 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -26,10 +26,6 @@ #include #include -#if QT_VERSION < 0x050000 -#include -#endif - // TODO: add a scrollback limit, as there is currently none // TODO: make it possible to filter out categories (esp debug messages when implemented) // TODO: receive errors and debug messages through ClientModel @@ -198,7 +194,7 @@ void RPCExecutor::request(const QString &command) } RPCConsole::RPCConsole(QWidget *parent) : - QDialog(parent), + QWidget(parent), ui(new Ui::RPCConsole), clientModel(0), historyPtr(0), @@ -276,7 +272,7 @@ bool RPCConsole::eventFilter(QObject* obj, QEvent *event) } } } - return QDialog::eventFilter(obj, event); + return QWidget::eventFilter(obj, event); } void RPCConsole::setClientModel(ClientModel *model) @@ -354,7 +350,7 @@ void RPCConsole::clear() ui->messagesWidget->document()->setDefaultStyleSheet( "table { }" "td.time { color: #808080; padding-top: 3px; } " - "td.message { font-family: monospace; font-size: 12px; } " // Todo: Remove fixed font-size + "td.message { font-family: monospace; } " "td.cmd-request { color: #006060; } " "td.cmd-error { color: red; } " "b { color: #006060; } " @@ -365,11 +361,12 @@ void RPCConsole::clear() tr("Type help for an overview of available commands.")), true); } -void RPCConsole::reject() +void RPCConsole::keyPressEvent(QKeyEvent *event) { - // Ignore escape keypress if this is not a seperate window - if(windowType() != Qt::Widget) - QDialog::reject(); + if(windowType() != Qt::Widget && event->key() == Qt::Key_Escape) + { + close(); + } } void RPCConsole::message(int category, const QString &message, bool html) diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index a79049e..f93a168 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -10,7 +10,7 @@ #include "net.h" -#include +#include class ClientModel; @@ -23,7 +23,7 @@ namespace Ui { } /** Local Bitcoin RPC console. */ -class RPCConsole: public QDialog +class RPCConsole: public QWidget { Q_OBJECT @@ -43,6 +43,7 @@ class RPCConsole: public QDialog protected: virtual bool eventFilter(QObject* obj, QEvent *event); + void keyPressEvent(QKeyEvent *); private Q_SLOTS: void on_lineEdit_returnPressed(); @@ -59,7 +60,6 @@ private Q_SLOTS: public Q_SLOTS: void clear(); - void reject(); void message(int category, const QString &message, bool html = false); /** Set number of connections shown in the UI */ void setNumConnections(int count); diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index b36318d..d488dba 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -33,9 +33,7 @@ SendCoinsDialog::SendCoinsDialog(QWidget *parent) : ui->sendButton->setIcon(QIcon()); #endif -#if QT_VERSION >= 0x040700 ui->msgLabel->setPlaceholderText(tr("Enter a message to include with this transaction")); -#endif GUIUtil::setupAddressWidget(ui->lineEditCoinControlChange, this); diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp index 5fd704d..82f179c 100644 --- a/src/qt/sendcoinsentry.cpp +++ b/src/qt/sendcoinsentry.cpp @@ -26,9 +26,9 @@ SendCoinsEntry::SendCoinsEntry(QWidget *parent) : #ifdef Q_OS_MAC ui->payToLayout->setSpacing(4); #endif -#if QT_VERSION >= 0x040700 + ui->addAsLabel->setPlaceholderText(tr("Enter a label for this address to add it to your address book")); -#endif + // normal bitcoin address field GUIUtil::setupAddressWidget(ui->payTo, this); diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp index f5d1c7c..0a6e8ae 100644 --- a/src/qt/signverifymessagedialog.cpp +++ b/src/qt/signverifymessagedialog.cpp @@ -24,11 +24,8 @@ SignVerifyMessageDialog::SignVerifyMessageDialog(QWidget *parent) : model(0) { ui->setupUi(this); - -#if QT_VERSION >= 0x040700 ui->signatureOut_SM->setPlaceholderText(tr("Click \"Sign Message\" to generate signature")); ui->addressIn_VM->setPlaceholderText(tr("Enter a Cryptonite address (e.g. CNS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)")); -#endif GUIUtil::setupAddressWidget(ui->addressIn_SM, this); GUIUtil::setupAddressWidget(ui->addressIn_VM, this); diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index 3e2364e..64aaf74 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -12,6 +12,9 @@ #include "wallet.h" #endif +#include +using namespace boost::placeholders; + #include #include #include diff --git a/src/qt/test/Makefile.am b/src/qt/test/Makefile.am index a7005fa..10ac125 100644 --- a/src/qt/test/Makefile.am +++ b/src/qt/test/Makefile.am @@ -1,6 +1,6 @@ include $(top_srcdir)/src/Makefile.include -AM_CPPFLAGS += -I$(top_srcdir)/src -std=c++11 -D__STDC_LIMIT_MACROS \ +AM_CPPFLAGS += -I$(top_srcdir)/src -std=c++17 -D__STDC_LIMIT_MACROS \ -I$(top_srcdir)/src/qt \ -I$(top_builddir)/src/qt \ $(PROTOBUF_CFLAGS) \ diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp index a2adb00..6894ba2 100644 --- a/src/qt/test/test_main.cpp +++ b/src/qt/test/test_main.cpp @@ -12,14 +12,6 @@ #include #include -#if defined(QT_STATICPLUGIN) && QT_VERSION < 0x050000 -#include -Q_IMPORT_PLUGIN(qcncodecs) -Q_IMPORT_PLUGIN(qjpcodecs) -Q_IMPORT_PLUGIN(qtwcodecs) -Q_IMPORT_PLUGIN(qkrcodecs) -#endif - // This is all you need to run all the tests int main(int argc, char *argv[]) { diff --git a/src/qt/trafficgraphwidget.cpp b/src/qt/trafficgraphwidget.cpp index 836d296..8bd5fb5 100644 --- a/src/qt/trafficgraphwidget.cpp +++ b/src/qt/trafficgraphwidget.cpp @@ -6,6 +6,7 @@ #include "clientmodel.h" #include +#include #include #include diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 04a73bc..543eb02 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -88,91 +88,78 @@ class TransactionTablePriv } /* Update our model of the wallet incrementally, to synchronize our model of the wallet - with that of the core. + with that of the core. - Call with transaction that was added, removed or changed. - */ + Call with transaction that was added, removed or changed. + */ void updateWallet(const uint256 &hash, int status) { - qDebug() << "TransactionTablePriv::updateWallet : " + QString::fromStdString(hash.ToString()) + " " + QString::number(status); - { - LOCK2(cs_main,wallet->cs_wallet); + LOCK2(cs_main,wallet->cs_wallet); + + auto mi = wallet->mapWallet.find(hash); + bool inWallet = mi != wallet->mapWallet.end(); + bool showTransaction = (inWallet && TransactionRecord::showTransaction(mi->second)); - // Find transaction in wallet - std::map::iterator mi = wallet->mapWallet.find(hash); - bool inWallet = mi != wallet->mapWallet.end(); + auto lower = qLowerBound(cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan()); + auto upper = qUpperBound(cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan()); + bool inModel = (lower != upper); - // Find bounds of this transaction in model - QList::iterator lower = qLowerBound( - cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan()); - QList::iterator upper = qUpperBound( - cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan()); - int lowerIndex = (lower - cachedWallet.begin()); - int upperIndex = (upper - cachedWallet.begin()); - bool inModel = (lower != upper); + if(status == CT_UPDATED && showTransaction == inModel) + return; - // Determine whether to show transaction or not - bool showTransaction = (inWallet && TransactionRecord::showTransaction(mi->second)); + #ifdef DEBUG + qDebug() << "TransactionTablePriv::updateWallet : " + QString::fromStdString(hash.ToString()) + " " + QString::number(status); + qDebug() << " inWallet=" + QString::number(inWallet) + " inModel=" + QString::number(inModel) + + " Index=" + QString::number(lower - cachedWallet.begin()) + "-" + QString::number(upper - cachedWallet.begin()) + + " showTransaction=" + QString::number(showTransaction) + " derivedStatus=" + QString::number(status); + #endif - if(status == CT_UPDATED) + switch(status) + { + case CT_NEW: + if(inModel) { - if(showTransaction && !inModel) - status = CT_NEW; /* Not in model, but want to show, treat as new */ - if(!showTransaction && inModel) - status = CT_DELETED; /* In model, but want to hide, treat as deleted */ + #ifdef DEBUG + qDebug() << "TransactionTablePriv::updateWallet : Warning: Got CT_NEW, but transaction is already in model"; + #endif + break; } - - qDebug() << " inWallet=" + QString::number(inWallet) + " inModel=" + QString::number(inModel) + - " Index=" + QString::number(lowerIndex) + "-" + QString::number(upperIndex) + - " showTransaction=" + QString::number(showTransaction) + " derivedStatus=" + QString::number(status); - - switch(status) + if(!inWallet) { - case CT_NEW: - if(inModel) - { - qDebug() << "TransactionTablePriv::updateWallet : Warning: Got CT_NEW, but transaction is already in model"; - break; - } - if(!inWallet) - { - qDebug() << "TransactionTablePriv::updateWallet : Warning: Got CT_NEW, but transaction is not in wallet"; - break; - } - if(showTransaction) + #ifdef DEBUG + qDebug() << "TransactionTablePriv::updateWallet : Warning: Got CT_NEW, but transaction is not in wallet"; + #endif + break; + } + if(showTransaction) + { + QList toInsert = TransactionRecord::decomposeTransaction(wallet, mi->second); + if(!toInsert.isEmpty()) { - // Added -- insert at the right position - QList toInsert = - TransactionRecord::decomposeTransaction(wallet, mi->second); - if(!toInsert.isEmpty()) /* only if something to insert */ + int lowerIndex = lower - cachedWallet.begin(); + parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex+toInsert.size()-1); + for (const TransactionRecord &rec : toInsert) { - parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex+toInsert.size()-1); - int insert_idx = lowerIndex; - for (const TransactionRecord &rec : toInsert) - { - cachedWallet.insert(insert_idx, rec); - insert_idx += 1; - } - parent->endInsertRows(); + cachedWallet.append(rec); } + parent->endInsertRows(); } - break; - case CT_DELETED: - if(!inModel) - { - qDebug() << "TransactionTablePriv::updateWallet : Warning: Got CT_DELETED, but transaction is not in model"; - break; - } - // Removed -- remove entire transaction from table - parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1); - cachedWallet.erase(lower, upper); - parent->endRemoveRows(); - break; - case CT_UPDATED: - // Miscellaneous updates -- nothing to do, status update will take care of this, and is only computed for - // visible transactions. + } + break; + case CT_DELETED: + if(!inModel) + { + #ifdef DEBUG + qDebug() << "TransactionTablePriv::updateWallet : Warning: Got CT_DELETED, but transaction is not in model"; + #endif break; } + parent->beginRemoveRows(QModelIndex(), lower - cachedWallet.begin(), upper - cachedWallet.begin() - 1); + cachedWallet.erase(lower, upper); + parent->endRemoveRows(); + break; + case CT_UPDATED: + break; } } diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index 9c4c4c3..4631863 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -83,15 +83,13 @@ TransactionView::TransactionView(QWidget *parent) : hlayout->addWidget(typeWidget); addressWidget = new QLineEdit(this); -#if QT_VERSION >= 0x040700 addressWidget->setPlaceholderText(tr("Enter address or label to search")); -#endif + hlayout->addWidget(addressWidget); amountWidget = new QLineEdit(this); -#if QT_VERSION >= 0x040700 amountWidget->setPlaceholderText(tr("Min amount")); -#endif + #ifdef Q_OS_MAC amountWidget->setFixedWidth(97); #else diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 259ebb0..e131a51 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -20,10 +20,16 @@ #include +#include +#include +#include + #include #include #include +using namespace boost::placeholders; + WalletModel::WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent) : QObject(parent), wallet(wallet), optionsModel(optionsModel), addressTableModel(0), transactionTableModel(0), @@ -579,11 +585,18 @@ void WalletModel::loadReceiveRequests(std::vector& vReceiveRequests { LOCK(wallet->cs_wallet); for (const std::pair& item : wallet->mapAddressBook) + { for (const std::pair& item2 : item.second.destdata) - if (item2.first.size() > 2 && item2.first.substr(0,2) == "rr") // receive request + { + if (item2.first.size() > 2 && item2.first.substr(0,2) == "rr") // receive request + { vReceiveRequests.push_back(item2.second); + } + } + } } + bool WalletModel::saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest) { CTxDestination dest = CBitcoinAddress(sAddress).Get(); diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index 9846c88..fffdc6e 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include @@ -26,6 +26,7 @@ using namespace std; using namespace boost; using namespace boost::asio; +using namespace boost::placeholders; using namespace json_spirit; Object CallRPC(const string& strMethod, const Array& params) diff --git a/src/rpcprotocol.cpp b/src/rpcprotocol.cpp index 82f5270..0cbf9e2 100644 --- a/src/rpcprotocol.cpp +++ b/src/rpcprotocol.cpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include @@ -23,6 +23,7 @@ using namespace std; using namespace boost; using namespace boost::asio; +using namespace boost::placeholders; using namespace json_spirit; // diff --git a/src/rpcprotocol.h b/src/rpcprotocol.h index 8b3df19..07cbd3c 100644 --- a/src/rpcprotocol.h +++ b/src/rpcprotocol.h @@ -103,7 +103,7 @@ class SSLIOStreamDevice : public boost::iostreams::device #include #include -#include +#include #include #include #include #include #include "json/json_spirit_writer_template.h" +namespace fs = boost::filesystem; using namespace std; using namespace boost; using namespace boost::asio; +using namespace boost::placeholders; using namespace json_spirit; static std::string strRPCUserColonPass; @@ -489,10 +491,10 @@ class AcceptedConnectionImpl : public AcceptedConnection { public: AcceptedConnectionImpl( - asio::io_service& io_service, + asio::any_io_executor executor, ssl::context &context, bool fUseSSL) : - sslStream(io_service, context), + sslStream(executor, context), _d(sslStream, fUseSSL), _stream(_d) { @@ -539,8 +541,8 @@ static void RPCListen(boost::shared_ptr< basic_socket_acceptor* conn = new AcceptedConnectionImpl(acceptor->get_io_service(), context, fUseSSL); + // Pass the executor instead of the io_service + AcceptedConnectionImpl* conn = new AcceptedConnectionImpl(acceptor->get_executor(), context, fUseSSL); acceptor->async_accept( conn->sslStream.lowest_layer(), @@ -639,14 +641,14 @@ void StartRPCThreads() { rpc_ssl_context->set_options(ssl::context::no_sslv2); - filesystem::path pathCertFile(GetArg("-rpcsslcertificatechainfile", "server.cert")); - if (!pathCertFile.is_complete()) pathCertFile = filesystem::path(GetDataDir()) / pathCertFile; - if (filesystem::exists(pathCertFile)) rpc_ssl_context->use_certificate_chain_file(pathCertFile.string()); + fs::path pathCertFile(GetArg("-rpcsslcertificatechainfile", "server.cert")); + if (!pathCertFile.is_complete()) pathCertFile = fs::path(GetDataDir()) / pathCertFile; + if (fs::exists(pathCertFile)) rpc_ssl_context->use_certificate_chain_file(pathCertFile.string()); else LogPrintf("ThreadRPCServer ERROR: missing server certificate file %s\n", pathCertFile.string()); - filesystem::path pathPKFile(GetArg("-rpcsslprivatekeyfile", "server.pem")); - if (!pathPKFile.is_complete()) pathPKFile = filesystem::path(GetDataDir()) / pathPKFile; - if (filesystem::exists(pathPKFile)) rpc_ssl_context->use_private_key_file(pathPKFile.string(), ssl::context::pem); + fs::path pathPKFile(GetArg("-rpcsslprivatekeyfile", "server.pem")); + if (!pathPKFile.is_complete()) pathPKFile = fs::path(GetDataDir()) / pathPKFile; + if (fs::exists(pathPKFile)) rpc_ssl_context->use_private_key_file(pathPKFile.string(), ssl::context::pem); else LogPrintf("ThreadRPCServer ERROR: missing server private key file %s\n", pathPKFile.string()); string strCiphers = GetArg("-rpcsslciphers", "TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH"); diff --git a/src/scheduler.cpp b/src/scheduler.cpp index c559c0c..d3b9c2f 100644 --- a/src/scheduler.cpp +++ b/src/scheduler.cpp @@ -5,9 +5,11 @@ #include "scheduler.h" #include -#include +#include #include +using namespace boost::placeholders; + CScheduler::CScheduler() : nThreadsServicingQueue(0), stopRequested(false), stopWhenEmpty(false) { } diff --git a/src/test/Makefile.am b/src/test/Makefile.am index e2f60a8..96c97b5 100644 --- a/src/test/Makefile.am +++ b/src/test/Makefile.am @@ -1,6 +1,6 @@ include $(top_srcdir)/src/Makefile.include -AM_CPPFLAGS += -I$(top_srcdir)/src -std=c++11 -fpermissive -ffloat-store -D__STDC_LIMIT_MACROS +AM_CPPFLAGS += -I$(top_srcdir)/src -std=c++17 -fpermissive -ffloat-store -D__STDC_LIMIT_MACROS bin_PROGRAMS = test_bitcoin diff --git a/src/trieengine.cpp b/src/trieengine.cpp index 49d1139..0328617 100644 --- a/src/trieengine.cpp +++ b/src/trieengine.cpp @@ -28,141 +28,105 @@ static uint32_t high_bit(uint160_t key, uint32_t shift){ } //Function to insert into trie -void TrieEngine::Insert(TrieNode **root, TrieNode *node, uint32_t bits){ - if(*root==0){ - *root = node; - node->SetParent(0); - return; - } - - if((*root)->Type() == NODE_BRANCH){ - //First check if we need to split the branch - uint32_t new_bits = (*root)->Bits(); - uint160_t subkey=sub_key(node->Key(), bits, new_bits);//(key>>(256-(new_bits-1)))<<(256-(new_bits-1)); - //cout << "Subkey: " << subkey.GetBin() << "\n"; - if(subkey == (*root)->Key()){ - //printf("Got match\n"); - //Can move down tree - uint32_t bit=high_bit(node->Key(), bits + new_bits);//Find bottom bit of subkey - if(bit & 1){ //Right side - Insert(&(*root)->m_right,node,bits+new_bits+1); - }else{ - Insert(&(*root)->m_left,node,bits+new_bits+1); - } - return; - } - //return; - //If we get here, then the branch at root needs to be split and another branch inserted - - } - - if(1){ //(*root)->Type() == NODE_LEAF - TrieNode *parent = (*root)->Parent(); - - //Uh ohs!!!!! - TrieNode *node2 = *root; - //Add the nodes with lower node on left. - uint160_t k1 = node->Key() << bits; - uint160_t k2 = node2->Key() << bits; - - assert(k1!=k2); //Duplicate insert attempt; - - if(parent){ - //we must deparent the leaf first to get counts under control - parent->Subtract((*root)->Children()); - //assert(0); - } - - //Create a new node to hold the branch - *root = new TrieNode(NODE_BRANCH); - (*root)->SetParent(parent); - - if(k1 < k2){ - (*root)->Add(node); - (*root)->Add(node2); - }else{ - (*root)->Add(node2); - (*root)->Add(node); - } - - //cout << "k1: " << k1.GetBin() << "\n"; - //cout << "k2: " << k2.GetBin() << "\n"; - - //Determine how many bits are common - uint8_t c1,c2; - uint32_t new_bits=0; - do{ - c1 = *(k1.end()-1); - c2 = *(k2.end()-1); - - //printf("%X %X %X %X\n", c1, c2, c1 ^ c2, (c1 ^ c2) & 0x80); - - k1 = k1 << 1; - k2 = k2 << 1; - new_bits++; - }while(((c1 ^ c2) & 0x80) == 0); - new_bits--; - (*root)->SetBits(new_bits); - - //printf("new bits %d\n", new_bits); - - //Common is new_bits - (*root)->SetKey(sub_key(node->Key(), bits, new_bits)); - - //Should be good to go - - //If we just broke a branch, we need to update the childs hash crap -#if 1 - if(node->Type() == NODE_BRANCH || node2->Type() == NODE_BRANCH){ - //printf("Foo1111\n"); - TrieNode *branch = node; - if(node2->Type() == NODE_BRANCH) - branch = node2; - - branch->SetBits(branch->Bits()-new_bits-1); - branch->SetKey(sub_key(branch->Key(), bits + new_bits+1, branch->Bits())); - } -#endif - } +void TrieEngine::Insert(TrieNode **root, TrieNode *node, uint32_t bits) { + if (*root == nullptr) { + *root = node; + node->SetParent(nullptr); + return; + } + + if ((*root)->Type() == NODE_BRANCH) { + uint32_t new_bits = (*root)->Bits(); + uint160_t subkey = sub_key(node->Key(), bits, new_bits); + if (subkey == (*root)->Key()) { + uint32_t bit = high_bit(node->Key(), bits + new_bits); + if (bit & 1) { + Insert(&(*root)->m_right, node, bits + new_bits + 1); + } else { + Insert(&(*root)->m_left, node, bits + new_bits + 1); + } + return; + } + } + + if (true) { // Simplified conditional + TrieNode *parent = (*root)->Parent(); + TrieNode *node2 = *root; + uint160_t k1 = node->Key() << bits; + uint160_t k2 = node2->Key() << bits; + + assert(k1 != k2); + + if (parent) { + parent->Subtract((*root)->Children()); + } + + *root = new TrieNode(NODE_BRANCH); + (*root)->SetParent(parent); + + if (k1 < k2) { + (*root)->Add(node); + (*root)->Add(node2); + } else { + (*root)->Add(node2); + (*root)->Add(node); + } + + uint8_t c1, c2; + uint32_t new_bits = 0; + do { + c1 = *(k1.end() - 1); + c2 = *(k2.end() - 1); + + k1 <<= 1; + k2 <<= 1; + new_bits++; + } while (((c1 ^ c2) & 0x80) == 0); + new_bits--; + + (*root)->SetBits(new_bits); + (*root)->SetKey(sub_key(node->Key(), bits, new_bits)); + + if ((node->Type() == NODE_BRANCH) || (node2->Type() == NODE_BRANCH)) { + TrieNode *branch = (node2->Type() == NODE_BRANCH) ? node2 : node; + branch->SetBits(branch->Bits() - new_bits - 1); + branch->SetKey(sub_key(branch->Key(), bits + new_bits + 1, branch->Bits())); + } + } } -void TrieEngine::Remove(TrieNode **root, TrieNode *node){ - TrieNode *parent = node->Parent(); - if(!parent){ - *root = 0; - delete node; - return; - } - - //Remove node from parent. If other child of parent is leaf, then reparent leaf to parents parent - //If other child is branch, then combine the branched and reparent to parents parent - TrieNode *peer = parent->Remove(node); - delete node; - - if(!parent->Parent()){ - *root = peer; - peer->SetParent(0); - }else{ - parent->Parent()->Replace(parent,peer); - } - - { - if(peer->Type() == NODE_BRANCH){ - peer->SetBits(peer->Bits() + parent->Bits() + 1); - uint32_t total = parent->GetTotalBits(); - peer->SetKey(peer->Key() | parent->Key()); - if(parent->m_right==peer){ - uint160_t foo = 1; - foo = foo << (160 - total); - peer->SetKey(peer->Key() | foo); - } - } - //Must set parent to null because this node is orphaned and we don't want it propagating count updates - parent->SetParent(0); - //Must remove the peer from parent before delete or it will try to delete good nodes - parent->Remove(peer); - delete parent; - } +void TrieEngine::Remove(TrieNode **root, TrieNode *node) { + TrieNode *parent = node->Parent(); + if (!parent) { + *root = nullptr; + delete node; + return; + } + + TrieNode *peer = parent->Remove(node); + delete node; + + if (!parent->Parent()) { + *root = peer; + peer->SetParent(nullptr); + } else { + parent->Parent()->Replace(parent, peer); + } + + if (peer->Type() == NODE_BRANCH) { + peer->SetBits(peer->Bits() + parent->Bits() + 1); + uint32_t total = parent->GetTotalBits(); + peer->SetKey(peer->Key() | parent->Key()); + if (parent->m_right == peer) { + uint160_t foo = 1; + foo <<= (160 - total); + peer->SetKey(peer->Key() | foo); + } + } + + parent->SetParent(nullptr); + parent->Remove(peer); + delete parent; } uint64_t TrieEngine::Size(TrieNode* root){ @@ -246,163 +210,111 @@ void TrieEngine::RebuildStructure(TrieNode *root){ } void TrieEngine::TraverseLeft(TrieNode *leftnode, uint160_t left, uint160_t right, list *lefts, int bits) { - uint160_t ones; - memset(&ones,0xFF,20); - if(leftnode){ - if(leftnode->Type()==NODE_BRANCH){ - bits+=leftnode->Bits(); - uint160 tkey = leftnode->GetTotalKey(leftnode->m_left,0); - uint160_t mask = ~(ones >> (bits+1)); - uint160 rtkey = leftnode->GetTotalKey(leftnode->m_right,0); - - if(tkey < (left&mask)){ - leftnode->FindAll(NODE_HASH,lefts); - return; - }else{ - TraverseLeft(leftnode->m_left, left, right, lefts, bits); - } - if(rtkey < (left&mask)){ - leftnode->m_right->FindAll(NODE_HASH,lefts); - return; - }else{ - TraverseLeft(leftnode->m_right, left, right, lefts, bits); - } - } - } + uint160_t ones; + memset(&ones, 0xFF, 20); + if (leftnode && leftnode->Type() == NODE_BRANCH) { + bits += leftnode->Bits(); + uint160_t mask = ~(ones >> (bits + 1)); + uint160_t tkey = leftnode->GetTotalKey(leftnode->m_left, 0); + uint160_t rtkey = leftnode->GetTotalKey(leftnode->m_right, 0); + + if (tkey < (left & mask)) { + leftnode->FindAll(NODE_HASH, lefts); + } else { + TraverseLeft(leftnode->m_left, left, right, lefts, bits); + } + if (rtkey < (left & mask)) { + leftnode->m_right->FindAll(NODE_HASH, lefts); + } else { + TraverseLeft(leftnode->m_right, left, right, lefts, bits); + } + } } void TrieEngine::TraverseRight(TrieNode *rightnode, uint160_t left, uint160_t right, list *rights, int bits) { - uint160_t ones; - memset(&ones,0xFF,20); - if(rightnode){ - if(rightnode->Type()==NODE_BRANCH){ - bits+=rightnode->Bits(); - uint160 rtkey = rightnode->GetTotalKey(rightnode->m_right,0); - - if(rtkey > right){ - rightnode->FindAll(NODE_HASH,rights); - return; - }else{ - TraverseRight(rightnode->m_right, left, right, rights, bits); - } - if(rtkey > left){ - rightnode->m_left->FindAll(NODE_HASH,rights); - return; - }else{ - TraverseRight(rightnode->m_left, left, right, rights, bits); - } - } - } + uint160_t ones; + memset(&ones, 0xFF, 20); + if (rightnode && rightnode->Type() == NODE_BRANCH) { + bits += rightnode->Bits(); + uint160_t rtkey = rightnode->GetTotalKey(rightnode->m_right, 0); + + if (rtkey > right) { + rightnode->FindAll(NODE_HASH, rights); + } else { + TraverseRight(rightnode->m_right, left, right, rights, bits); + } + if (rtkey > left) { + rightnode->m_left->FindAll(NODE_HASH, rights); + } else { + TraverseRight(rightnode->m_left, left, right, rights, bits); + } + } } -bool TrieEngine::Prove(TrieNode *root, uint160_t left, uint160_t right){ - uint160_t ones; - memset(&ones,0xFF,20); - - //Principle here is that we will traverse the trie. locating all hash only nodes to the left of the left bound - //and to the right of the right bound. If the union of these sets contains all hash nodes in the subtrie, then - //the subtrie *must* contain all real nodes between left and right. - - //Locate all hash nodes to the left of left - list lefts; - TraverseLeft(root, left, right, &lefts, 0); - - //Do right traversal - list rights; - TraverseRight(root, left, right, &rights, 0); - - //For sanity check we must find all hash nodes - list hashnodes; - root->FindAll(NODE_HASH,&hashnodes); - - //lefts+rights can be larger than hashnodes in degenerate cases, so we ignore failure to remove - //as it is impossible that union of lefts+rights contains elements not in hashnodes - list::iterator it; - for(it = lefts.begin(); it!= lefts.end(); it++){ - hashnodes.remove(*it); - } - for(it = rights.begin(); it != rights.end(); it++){ - hashnodes.remove(*it); - } - - if(!hashnodes.empty()){ - //Bastard tried to sneak a fast one on us - printf("Bad trie!\n"); - return false; - } -#if 0 - //Very last elements in list are the bounding elements of the recieved data - //Warning, lists may be empty if trie is unbounded on either side! - TrieNode* leftBound = lefts.empty()?0:lefts.back(); - TrieNode* rightBound = rights.empty()?0:rights.back(); - - printf("%p %p %ld %ld\n", leftBound, rightBound, lefts.size(), rights.size()); - - //////////////////////At this point we know the trie is well formed. Just a matter of locating the bounds - uint160_t leftcalc,rightcalc; - if(leftBound){ - uint32_t bits = leftBound->Parent()->GetTotalBits(); - uint160_t key = ones >> bits; - uint160_t key2 = leftBound->Parent()->GetTotalKey(leftBound,0); - leftcalc = key|key2; - }else{ - leftcalc = 0; - } +bool TrieEngine::Prove(TrieNode *root, uint160_t left, uint160_t right) { + uint160_t ones; + memset(&ones, 0xFF, 20); + + if (!root) { + printf("Empty trie provided.\n"); + return false; + } + + // Locate all hash nodes to the left of left + list lefts; + TraverseLeft(root, left, right, &lefts, 0); + + // Do right traversal + list rights; + TraverseRight(root, left, right, &rights, 0); + + // For sanity check, find all hash nodes + list hashnodes; + root->FindAll(NODE_HASH, &hashnodes); + + // Remove duplicates from lefts and rights + lefts.sort(); + lefts.unique(); + rights.sort(); + rights.unique(); + + // Remove nodes in lefts and rights from hashnodes + for (TrieNode* node : lefts) { + hashnodes.remove(node); + } + for (TrieNode* node : rights) { + hashnodes.remove(node); + } + + // Check for remaining hash nodes + if (!hashnodes.empty()) { + printf("Bad trie! Unaccounted hash nodes found.\n"); + return false; + } + + return true; +} - //TODO: Pretty sure right bound is wrong - if(rightBound){ - //uint32_t bits = rightBound->Parent()->GetTotalBits(); - uint160_t key = 0;//ones >> bits; - uint160_t key2 = rightBound->Parent()->GetTotalKey(rightBound,0); - rightcalc=key|key2; - }else{ - //If there are no empty nodes on right then the bound is maximal - rightcalc=ones; - } +TrieNode* TrieEngine::Find(uint160_t key, TrieNode *root, uint32_t keybits) { + if (!root) { + return nullptr; + } - //Really weird degenerate cases - if(leftcalc != 0 && rightcalc < leftcalc) - rightcalc = ones; + if (root->Type() == NODE_LEAF) { + return (root->Key() == key) ? root : nullptr; + } - if(rightcalc != ones && rightcalc < leftcalc) - leftcalc = 0; - cout << left.GetHex() << endl; - cout << leftcalc.GetHex() << endl; - cout << right.GetHex() << endl; - cout << rightcalc.GetHex() << endl; + if (root->Type() == NODE_BRANCH) { + uint160_t skey = sub_key(key, keybits, root->Bits()); + uint160_t key2 = sub_key(root->Key(), keybits, root->Bits()); - return leftcalc <= left && rightcalc >= right; -#else - return true; -#endif -} + if (skey != key2) { + return nullptr; + } -TrieNode* TrieEngine::Find(uint160_t key, TrieNode *root, uint32_t keybits){ - if(!root) - return 0; - if(root->Type() == NODE_LEAF){ - //printf("Key: %s %s\n", key.GetHex().c_str(), root->Key().GetHex().c_str()); - if(root->Key() == key) - return root; - else - return 0; - } - if(root->Type() != NODE_BRANCH) - return 0; + bool isRight = ((key >> (159 - (keybits + root->Bits()))) & 1) != 0; + return Find(key, isRight ? root->m_right : root->m_left, keybits + root->Bits() + 1); + } - if(root->Type() == NODE_BRANCH){ - uint160_t skey = sub_key(key,keybits,root->Bits()); - uint160_t key2 = sub_key(root->Key(),keybits,root->Bits()); - //printf("Keys: %s, %s\n", skey.GetHex().c_str(), key2.GetHex().c_str()); - if(skey!=key2) - return 0; - - if(((key >> (159 - (keybits + root->Bits()))) & 1) != 0){ - //printf("Right\n"); - return Find(key,root->m_right,keybits + root->Bits() + 1); - } - //printf("Left\n"); - return Find(key,root->m_left,keybits + root->Bits() + 1); - } - return 0; + return nullptr; } diff --git a/src/triesync.cpp b/src/triesync.cpp index aedb35f..edf8975 100644 --- a/src/triesync.cpp +++ b/src/triesync.cpp @@ -212,9 +212,6 @@ bool overlap(list::iterator it, list::iterator it2){ return (overlap_left(it,it2) || overlap_left(it2,it)); } - - - void TrieSync::GetIntervals(multimap &slices, list &intervals){ //We want to produce a vector of all intervals that either have requests outstanding //or have already been fetched @@ -347,46 +344,46 @@ bool TrieSync::ReadyToBuild(){ return true; } -//TODO: all wrong void TrieSync::ApplyTransactions(map &data, CBlock &block){ - //Txout first + // Process outputs first for (CTransaction tx : block.vtx){ - for (CTxOut txout : tx.vout){ - AccountData ad; - if(data.find(txout.pubKey)!=data.end()) - ad = data[txout.pubKey]; - ad.SetKey(txout.pubKey); - //No set age on output -// ad.SetAge(block.nHeight); - ad.SetBalance(ad.Balance()+txout.nValue); - data[txout.pubKey] = ad; - } + for (CTxOut txout : tx.vout){ + AccountData ad; + if(data.find(txout.pubKey) != data.end()) + ad = data[txout.pubKey]; + ad.SetKey(txout.pubKey); + // No set age on output + // ad.SetAge(block.nHeight); + ad.SetBalance(ad.Balance() + txout.nValue); + data[txout.pubKey] = ad; + } } + // Then process inputs for (CTransaction tx : block.vtx){ - for (CTxIn txin : tx.vin){ - if(data.find(txin.pubKey)==data.end()) - continue; //Account not in slices yet, no worries - AccountData ad = data[txin.pubKey]; - - if(txin.nValue >= ad.Balance()){ - data.erase(txin.pubKey); - continue; - } - if(tx.fSetLimit) - ad.SetFutureLimit(tx.nLimitValue); - - if(ad.FutureLimit() < ad.Limit()) - ad.SetLimit(ad.FutureLimit()); - - if(block.nHeight - ad.Age() > MIN_LIMIT_TIME){ - ad.SetLimit(ad.FutureLimit()); - } - ad.SetAge(block.nHeight); - - ad.SetBalance(ad.Balance()-txin.nValue); - data[txin.pubKey] = ad; - } + for (CTxIn txin : tx.vin){ + if(data.find(txin.pubKey) == data.end()) + continue; // Account not in slices yet, no worries + AccountData ad = data[txin.pubKey]; + + if(txin.nValue >= ad.Balance()){ + data.erase(txin.pubKey); + continue; + } + if(tx.fSetLimit) + ad.SetFutureLimit(tx.nLimitValue); + + if(ad.FutureLimit() < ad.Limit()) + ad.SetLimit(ad.FutureLimit()); + + if(block.nHeight - ad.Age() > MIN_LIMIT_TIME){ + ad.SetLimit(ad.FutureLimit()); + } + ad.SetAge(block.nHeight); + + ad.SetBalance(ad.Balance() - txin.nValue); + data[txin.pubKey] = ad; + } } } diff --git a/src/txdb.cpp b/src/txdb.cpp index 37e3467..d4cced1 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -91,60 +91,49 @@ bool CBlockTreeDB::ReadFlag(const std::string &name, bool &fValue) { return true; } -bool CBlockTreeDB::LoadBlockIndexGuts() -{ - //printf("Load guts\n"); - leveldb::Iterator *pcursor = NewIterator(); +bool CBlockTreeDB::LoadBlockIndexGuts() { + std::unique_ptr pcursor(NewIterator()); CDataStream ssKeySet(SER_DISK, CLIENT_VERSION); - ssKeySet << make_pair('b', uint256(0)); + ssKeySet << std::make_pair('b', uint256(0)); pcursor->Seek(ssKeySet.str()); - // Load mapBlockIndex while (pcursor->Valid()) { boost::this_thread::interruption_point(); - try { - leveldb::Slice slKey = pcursor->key(); - CDataStream ssKey(slKey.data(), slKey.data()+slKey.size(), SER_DISK, CLIENT_VERSION); - char chType; - ssKey >> chType; - if (chType == 'b') { - leveldb::Slice slValue = pcursor->value(); - CDataStream ssValue(slValue.data(), slValue.data()+slValue.size(), SER_DISK, CLIENT_VERSION); - CDiskBlockIndex diskindex; + + leveldb::Slice slKey = pcursor->key(); + leveldb::Slice slValue = pcursor->value(); + + CDataStream ssKey(slKey.data(), slKey.data() + slKey.size(), SER_DISK, CLIENT_VERSION); + CDataStream ssValue(slValue.data(), slValue.data() + slValue.size(), SER_DISK, CLIENT_VERSION); + + char chType; + ssKey >> chType; + + if (chType == 'b') { + CDiskBlockIndex diskindex; + try { ssValue >> diskindex; + } catch (std::exception &e) { + return error("%s : Deserialize or I/O error - %s", __PRETTY_FUNCTION__, e.what()); + } - if (!diskindex.CheckIndex()) { - error("LoadBlockIndex() : CheckIndex failed: %s", diskindex.GetBlockHash().ToString().c_str()); - printf("fail\n"); - pcursor->Next(); - continue; - } - - // Construct block index object - CBlockIndex* pindexNew = InsertBlockIndex(diskindex.GetBlockHash(), diskindex.GetBlockHeader()); - pindexNew->nFile = diskindex.nFile; - pindexNew->nDataPos = diskindex.nDataPos; - pindexNew->nUndoPos = diskindex.nUndoPos; - pindexNew->nStatus = diskindex.nStatus; - pindexNew->nTx = diskindex.nTx; - - //printf("%d %ld %ld %ld\n", diskindex.nVersion, diskindex.nHeight, diskindex.nNonce, diskindex.nTime); - //printf("%s %s\n", diskindex.hashMerkleRoot.GetHex().c_str(), diskindex.hashAccountRoot.GetHex().c_str()); - - //pindexNew->nHeight = 0; - //printf("Foo: %s\n", pindexNew->GetBlockHeader().GetHash().GetHex().c_str()); - pcursor->Next(); - } else { - break; // if shutdown requested or finished loading block index + if (!diskindex.CheckIndex()) { + error("LoadBlockIndex() : CheckIndex failed: %s", diskindex.GetBlockHash().ToString().c_str()); + continue; } - } catch (std::exception &e) { - return error("%s : Deserialize or I/O error - %s", __PRETTY_FUNCTION__, e.what()); + + CBlockIndex* pindexNew = InsertBlockIndex(diskindex.GetBlockHash(), diskindex.GetBlockHeader()); + if (pindexNew) { + pindexNew->nFile = diskindex.nFile; + pindexNew->nDataPos = diskindex.nDataPos; + pindexNew->nUndoPos = diskindex.nUndoPos; + pindexNew->nStatus = diskindex.nStatus; + pindexNew->nTx = diskindex.nTx; + } + } else { + break; } + pcursor->Next(); } - delete pcursor; - - //now that all blocks are loaded it is possible to actually verify proof of work. - //which is done by caller - return true; } diff --git a/src/util.cpp b/src/util.cpp index 1a94609..9919e0f 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -14,6 +14,8 @@ #include +#include + #ifndef WIN32 // for posix_fallocate #ifdef __linux_ @@ -58,7 +60,9 @@ #endif #include /* for _commit */ -#include +// #include "shlobj.h" +#define CSIDL_APPDATA 0x001a + #endif #include // for to_lower() @@ -82,7 +86,6 @@ namespace boost { } } - using namespace std; map mapArgs; @@ -974,7 +977,7 @@ boost::filesystem::path GetDefaultDataDir() // Unix: ~/.bitcoin #ifdef WIN32 // Windows - return GetSpecialFolderPath(CSIDL_APPDATA) / "Cryptonite"; + return boost::filesystem::path(getenv("APPDATA")) / "Cryptonite"; #else fs::path pathRet; char* pszHome = getenv("HOME"); @@ -1367,19 +1370,30 @@ std::string FormatSubVersion(const std::string& name, int nClientVersion, const } #ifdef WIN32 -boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate) +boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate = true) { namespace fs = boost::filesystem; - char pszPath[MAX_PATH] = ""; - if(SHGetSpecialFolderPathA(nullptr, pszPath, nFolder, fCreate)) - { - return fs::path(pszPath); + const char* pPath = nullptr; + if (nFolder == CSIDL_APPDATA) { + pPath = getenv("APPDATA"); } + // Add other special folders here as needed... + + if (pPath != nullptr) { + strncpy(pszPath, pPath, sizeof(pszPath)); + pszPath[sizeof(pszPath) - 1] = '\0'; + } else { + LogPrintf("getenv() failed, could not obtain requested path.\n"); + return fs::path(""); + } + + fs::path pathRet = fs::path(pszPath); + if(fCreate && !fs::exists(pathRet)) + fs::create_directory(pathRet); - LogPrintf("SHGetSpecialFolderPathA() failed, could not obtain requested path.\n"); - return fs::path(""); + return pathRet; } #endif diff --git a/src/util.h b/src/util.h index 74fac6a..9464644 100644 --- a/src/util.h +++ b/src/util.h @@ -275,19 +275,19 @@ inline int64_t abs64(int64_t n) } template -std::string HexStr(const T itbegin, const T itend, bool fSpaces=false) +std::string HexStr(const T itbegin, const T itend, bool fSpaces = false) { std::string rv; - static const char hexmap[16] = { '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; - rv.reserve((itend-itbegin)*3); - for(T it = itbegin; it < itend; ++it) + static const char hexmap[16] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + rv.reserve((itend - itbegin) * 3); + for (T it = itbegin; it < itend; ++it) { unsigned char val = (unsigned char)(*it); - if(fSpaces && it != itbegin) + if (fSpaces && it != itbegin) rv.push_back(' '); - rv.push_back(hexmap[val>>4]); - rv.push_back(hexmap[val&15]); + rv.push_back(hexmap[val >> 4]); + rv.push_back(hexmap[val & 15]); } return rv; @@ -456,7 +456,7 @@ template class CMedianFilter nSize(size) { vValues.reserve(size); - vValues.push_back(initial_value); + vValues.emplace_back(initial_value); vSorted = vValues; } @@ -466,7 +466,7 @@ template class CMedianFilter { vValues.erase(vValues.begin()); } - vValues.push_back(value); + vValues.emplace_back(value); vSorted.resize(vValues.size()); std::copy(vValues.begin(), vValues.end(), vSorted.begin()); diff --git a/src/walletdb.cpp b/src/walletdb.cpp index 30b69cb..001e403 100644 --- a/src/walletdb.cpp +++ b/src/walletdb.cpp @@ -13,6 +13,7 @@ #include +namespace fs = boost::filesystem; using namespace std; using namespace boost; @@ -817,20 +818,20 @@ bool BackupWallet(const CWallet& wallet, const string& strDest) bitdb.mapFileUseCount.erase(wallet.strWalletFile); // Copy wallet.dat - filesystem::path pathSrc = GetDataDir() / wallet.strWalletFile; - filesystem::path pathDest(strDest); - if (filesystem::is_directory(pathDest)) + fs::path pathSrc = GetDataDir() / wallet.strWalletFile; + fs::path pathDest(strDest); + if (fs::is_directory(pathDest)) pathDest /= wallet.strWalletFile; try { #if BOOST_VERSION >= 104000 - filesystem::copy_file(pathSrc, pathDest, filesystem::copy_option::overwrite_if_exists); + fs::copy_file(pathSrc, pathDest, fs::copy_option::overwrite_if_exists); #else - filesystem::copy_file(pathSrc, pathDest); + fs::copy_file(pathSrc, pathDest); #endif LogPrintf("copied wallet.dat to %s\n", pathDest.string()); return true; - } catch(const filesystem::filesystem_error &e) { + } catch(const fs::filesystem_error &e) { LogPrintf("error copying wallet.dat to %s - %s\n", pathDest.string(), e.what()); return false; }