From ec871c1933ff732fd33586237320e0bd242342d8 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Thu, 3 Jan 2019 16:41:46 +0100 Subject: [PATCH 01/23] Merge #15020: Build: add names to Travis jobs 1db71d4a29 Add names to Travis jobs (Graham Krizek) Pull request description: This adds the `name` field to all the TravisCI jobs. This will make it more obvious in the Travis UI what job is failing or passing. Tree-SHA512: d65841bab0a80d098a46a4bb54af2f9a93db7abca93b848aa00d25dcf4cd74323371c7c0b78b4dbf390b197e7ba32262a91631e201fc505f834021753f700b28 --- .travis.yml | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index e096da1459b7..87ede99f6c04 100644 --- a/.travis.yml +++ b/.travis.yml @@ -200,8 +200,8 @@ after_script: - echo $TRAVIS_COMMIT_LOG after_success: - if [ "$DOCKER_BUILD" = "true" ]; then docker login -u $DOCKER_HUB_USER -p $DOCKER_HUB_PASSWORD && ./docker/push-docker.sh; fi -# lint stage - stage: lint + name: 'lint' env: cache: false language: python @@ -212,8 +212,9 @@ after_success: - set -o errexit; source .travis/lint_05_before_script.sh script: - set -o errexit; source .travis/lint_06_script.sh -# ARM + - stage: test + name: 'ARM [GOAL: install] [no unit or functional tests]' env: >- HOST=arm-linux-gnueabihf PACKAGES="python3 g++-arm-linux-gnueabihf" @@ -221,39 +222,42 @@ after_success: RUN_FUNCTIONAL_TESTS=false GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" -# Win32 - stage: test + name: 'Win32 [GOAL: deploy] [no gui tests]' env: >- HOST=i686-w64-mingw32 DPKG_ADD_ARCH="i386" PACKAGES="python3 nsis g++-mingw-w64-i686 wine-binfmt wine32" GOAL="deploy" BITCOIN_CONFIG="--enable-reduce-exports --disable-gui-tests" -# Win64 + - stage: test + name: 'Win64 [GOAL: deploy] [no gui tests]' env: >- HOST=x86_64-w64-mingw32 PACKAGES="python3 nsis g++-mingw-w64-x86-64 wine-binfmt wine64" GOAL="deploy" BITCOIN_CONFIG="--enable-reduce-exports --disable-gui-tests" -# 32-bit + dash + - stage: test + name: '32-bit + dash [GOAL: install]' env: >- HOST=i686-pc-linux-gnu PACKAGES="g++-multilib python3-zmq" GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" CONFIG_SHELL="/bin/dash" -# x86_64 Linux (uses qt5 dev package instead of depends Qt to speed up build and avoid timeout) + - stage: test + name: 'x86_64 Linux [GOAL: install] [bionic] [uses qt5 dev package instead of depends Qt to speed up build and avoid timeout]' env: >- HOST=x86_64-unknown-linux-gnu PACKAGES="python3-zmq qtbase5-dev qttools5-dev-tools protobuf-compiler libdbus-1-dev libharfbuzz-dev libprotobuf-dev" DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1 ALLOW_HOST_PACKAGES=1" GOAL="install" BITCOIN_CONFIG="--enable-zmq --with-gui=qt5 --enable-glibc-back-compat --enable-reduce-exports --enable-debug CXXFLAGS=\"-g0 -O2\"" -# x86_64 Linux (xenial, no depends, only system libs, sanitizers: thread (TSAN)) - stage: test + name: 'x86_64 Linux [GOAL: install] [xenial] [no depends, only system libs, sanitizers: thread (TSan), no wallet]' env: >- HOST=x86_64-unknown-linux-gnu DOCKER_NAME_TAG=ubuntu:16.04 @@ -262,8 +266,8 @@ after_success: RUN_FUNCTIONAL_TESTS=false # Disabled for now. TODO identify suppressions or exclude specific tests GOAL="install" BITCOIN_CONFIG="--enable-zmq --with-incompatible-bdb --with-gui=qt5 CPPFLAGS=-DDEBUG_LOCKORDER --with-sanitizers=thread --disable-hardening --disable-asm CC=clang CXX=clang++" -# x86_64 Linux (no depends, only system libs, sanitizers: undefined (UBSAN) + integer) - stage: test + name: 'x86_64 Linux [GOAL: install] [bionic] [no depends, only system libs, sanitizers: address/leak (ASan + LSan) + undefined (UBSan) + integer]' env: >- HOST=x86_64-unknown-linux-gnu PACKAGES="clang llvm python3-zmq qtbase5-dev qttools5-dev-tools libssl1.0-dev libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-test-dev libboost-thread-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev libprotobuf-dev protobuf-compiler libqrencode-dev" @@ -271,8 +275,8 @@ after_success: RUN_BENCH=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --with-incompatible-bdb --with-gui=qt5 CPPFLAGS=-DDEBUG_LOCKORDER --with-sanitizers=integer,undefined CC=clang CXX=clang++" -# x86_64 Linux, No wallet - stage: test + name: 'x86_64 Linux [GOAL: install] [bionic] [no wallet]' env: >- HOST=x86_64-unknown-linux-gnu PACKAGES="clang llvm python3 libssl1.0-dev libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-test-dev libboost-thread-dev" @@ -290,8 +294,9 @@ after_success: DEP_OPTS="NO_WALLET=1" GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" -# Cross-Mac + - stage: test + name: 'macOS 10.10 [GOAL: deploy]' env: >- HOST=x86_64-apple-darwin14 PACKAGES="cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python-dev python3-setuptools-git" From 2fe566ded9f38567c1d007df1b1e6d212812af23 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 3 Jan 2019 17:00:30 +0100 Subject: [PATCH 02/23] Merge #15038: docs: Get more info about GUI-related issue on Linux 79f0a3f1f42e0421e60cf9a57f6c70c6be9221a1 Get more info about GUI-related issue on Linux (Hennadii Stepanov) Pull request description: There is bunch of combinations Linux Distro (Debian, Fedora, Ubuntu etc) + Desktop Environment (GNOME, KDE, Xfce etc) + Graphical Shell (Unity, GNOME Shell etc). This PR adds related requests to the issue template. Providing such data will make GUI-related issue reviewing and reproducing easier. Tree-SHA512: 9728d7826108b62a916c43523572d1da1b52b43a21b3d550a84225ff67951224e0b8a9394627f274d7c65383b3f526bcd12cc40eef9d7fec174c19d1abf333d8 --- .github/ISSUE_TEMPLATE.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 0642e0b96fc2..cff4f548b79d 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -33,5 +33,7 @@ List the version number/commit ID, and if it is an official binary, self compile - Disk size: - Disk Type (HD/SDD): +### For the GUI-related issue on Linux provide names and versions of a distro, a desktop environment and a graphical shell (if relevant). + ### Any extra information that might be useful in the debugging process. This is normally the contents of a `debug.log` or `config.log` file. Raw text or a link to a pastebin type site are preferred. From 60d7fd708c07bcd764fb72491ec28936e3cb7a81 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 8 Jan 2019 13:53:20 +0100 Subject: [PATCH 03/23] Merge #12153: Avoid permanent cs_main lock in getblockheader MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit f12e1d0b5117e3688f52a25ed0170d76ecdbf233 rpc: Avoid permanent cs_main lock in getblockheader (João Barbosa) Pull request description: This PR reduces the `cs_main` lock scope in `getblockheader` RPC. Tree-SHA512: bc51f80e15d1b32d3c7886836457f9929706b6aad9841dafce31ffca444281471b21b56192bb50de774184b9377412f815ad8d3d2439049a7e64d2e59c415767 --- src/rpc/blockchain.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index e0c266881434..8b188d329ed7 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -809,8 +809,6 @@ static UniValue getblockheader(const JSONRPCRequest& request) + HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") ); - LOCK(cs_main); - std::string strHash = request.params[0].get_str(); uint256 hash(uint256S(strHash)); @@ -818,7 +816,14 @@ static UniValue getblockheader(const JSONRPCRequest& request) if (!request.params[1].isNull()) fVerbose = request.params[1].get_bool(); - const CBlockIndex* pblockindex = LookupBlockIndex(hash); + const CBlockIndex* pblockindex; + const CBlockIndex* tip; + { + LOCK(cs_main); + pblockindex = LookupBlockIndex(hash); + tip = chainActive.Tip(); + } + if (!pblockindex) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); } From b39ec37988a794538d7b7d2195a7846f6dd048c6 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Thu, 10 Jan 2019 12:09:20 -0500 Subject: [PATCH 04/23] Merge #15139: util: Remove [U](BEGIN|END) macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 332b3dd7c1 util: Make ToLower and ToUpper take a char (Wladimir J. van der Laan) edb5bb3500 util: remove unused [U](BEGIN|END) macros (Wladimir J. van der Laan) 7fa238c701 Replace use of BEGIN and END macros on uint256 (Wladimir J. van der Laan) Pull request description: Two cleanups in `util/strencodings.h`: - Remove `[U](BEGIN|END)` macros — The only use of these was in the Merkle tree code with `uint256` which has its own `begin` and `end` methods which are better. - Make ToLower and ToUpper take a char — Unfortunately, `std::string` elements are (bare) chars. As these are the most likely type to be passed to these functions, make them use char instead of unsigned char. This avoids some casts. Tree-SHA512: 96c8292e1b588d3d7fde95c2e98ad4e7eb75e7baab40a8e8e8209d4e8e7a1bd3b6846601d20976be34a9daabefc50cbc23f3b04200af17d0dfc857c4ec42aca7 --- src/merkleblock.cpp | 4 ++-- src/test/merkle_tests.cpp | 4 ++-- src/test/util_tests.cpp | 4 ++-- src/util/strencodings.cpp | 2 +- src/util/strencodings.h | 8 ++------ 5 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/merkleblock.cpp b/src/merkleblock.cpp index 5d592e096adb..41c1fcfc079c 100644 --- a/src/merkleblock.cpp +++ b/src/merkleblock.cpp @@ -83,7 +83,7 @@ uint256 CPartialMerkleTree::CalcHash(int height, unsigned int pos, const std::ve else right = left; // combine subhashes - return Hash(BEGIN(left), END(left), BEGIN(right), END(right)); + return Hash(left.begin(), left.end(), right.begin(), right.end()); } } @@ -139,7 +139,7 @@ uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, uns right = left; } // and combine them before returning - return Hash(BEGIN(left), END(left), BEGIN(right), END(right)); + return Hash(left.begin(), left.end(), right.begin(), right.end()); } } diff --git a/src/test/merkle_tests.cpp b/src/test/merkle_tests.cpp index 11a8517e95ea..b288865d8df1 100644 --- a/src/test/merkle_tests.cpp +++ b/src/test/merkle_tests.cpp @@ -13,9 +13,9 @@ static uint256 ComputeMerkleRootFromBranch(const uint256& leaf, const std::vecto uint256 hash = leaf; for (std::vector::const_iterator it = vMerkleBranch.begin(); it != vMerkleBranch.end(); ++it) { if (nIndex & 1) { - hash = Hash(BEGIN(*it), END(*it), BEGIN(hash), END(hash)); + hash = Hash(it->begin(), it->end(), hash.begin(), hash.end()); } else { - hash = Hash(BEGIN(hash), END(hash), BEGIN(*it), END(*it)); + hash = Hash(hash.begin(), hash.end(), it->begin(), it->end()); } nIndex >>= 1; } diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 33d3838344e1..d1b5e24c5eaf 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -1297,7 +1297,7 @@ BOOST_AUTO_TEST_CASE(test_ToLower) BOOST_CHECK_EQUAL(ToLower('Z'), 'z'); BOOST_CHECK_EQUAL(ToLower('['), '['); BOOST_CHECK_EQUAL(ToLower(0), 0); - BOOST_CHECK_EQUAL(ToLower(255), 255); + BOOST_CHECK_EQUAL(ToLower('\xff'), '\xff'); std::string testVector; Downcase(testVector); @@ -1319,7 +1319,7 @@ BOOST_AUTO_TEST_CASE(test_ToUpper) BOOST_CHECK_EQUAL(ToUpper('z'), 'Z'); BOOST_CHECK_EQUAL(ToUpper('{'), '{'); BOOST_CHECK_EQUAL(ToUpper(0), 0); - BOOST_CHECK_EQUAL(ToUpper(255), 255); + BOOST_CHECK_EQUAL(ToUpper('\xff'), '\xff'); } BOOST_AUTO_TEST_CASE(test_Capitalize) diff --git a/src/util/strencodings.cpp b/src/util/strencodings.cpp index c9c373c592b0..27d757ef46a9 100644 --- a/src/util/strencodings.cpp +++ b/src/util/strencodings.cpp @@ -620,7 +620,7 @@ std::string HexStr(const Span s) void Downcase(std::string& str) { - std::transform(str.begin(), str.end(), str.begin(), [](unsigned char c){return ToLower(c);}); + std::transform(str.begin(), str.end(), str.begin(), [](char c){return ToLower(c);}); } std::string Capitalize(std::string str) diff --git a/src/util/strencodings.h b/src/util/strencodings.h index 711cf5bcf105..f4a359854fb9 100644 --- a/src/util/strencodings.h +++ b/src/util/strencodings.h @@ -16,10 +16,6 @@ #include #include -#define BEGIN(a) ((char*)&(a)) -#define END(a) ((char*)&((&(a))[1])) -#define UBEGIN(a) ((unsigned char*)&(a)) -#define UEND(a) ((unsigned char*)&((&(a))[1])) #define ARRAYLEN(array) (sizeof(array)/sizeof((array)[0])) /** Used by SanitizeString() */ @@ -196,7 +192,7 @@ bool ConvertBits(const O& outfn, I it, I end) { * @return the lowercase equivalent of c; or the argument * if no conversion is possible. */ -constexpr unsigned char ToLower(unsigned char c) +constexpr char ToLower(char c) { return (c >= 'A' && c <= 'Z' ? (c - 'A') + 'a' : c); } @@ -217,7 +213,7 @@ void Downcase(std::string& str); * @return the uppercase equivalent of c; or the argument * if no conversion is possible. */ -constexpr unsigned char ToUpper(unsigned char c) +constexpr char ToUpper(char c) { return (c >= 'a' && c <= 'z' ? (c - 'a') + 'A' : c); } From 583c2ee123b914aa7f8590ff3d2af9203948c95d Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 11 Jan 2019 14:33:11 -1000 Subject: [PATCH 05/23] Merge #13216: [Qt] implements concept for different disk sizes on intro 9d0e52834 implements different disk sizes for different networks on intro (marcoagner) Pull request description: Fixes https://github.com/bitcoin/bitcoin/issues/13213. Mostly, I layed out the concept to open the PR for refinement and getting feedback if the approach is okay. Changes are expected. Two points: - The values for both new consts `TESTNET_BLOCK_CHAIN_SIZE` and `TESTNET_CHAIN_STATE_SIZE` is certainly not optimal; I just checked the size of my testnet3 related dirs and set them to little bit higher values. Which values should be used? - Should we do something like this to regtest? Or these "niceties" do not matter when on regtest? Thanks! Tree-SHA512: 8ae87a29fa8356b899e7a823c76cde793d9126b4ee59554d7a2a8edb088fe42a19976b34c06c2fd4a98a727e1e4971dd983f42b6093ea6caa255b45004e22bb4 --- doc/release-process.md | 2 +- src/chainparams.cpp | 8 ++++++++ src/chainparams.h | 6 ++++++ src/interfaces/node.cpp | 2 ++ src/interfaces/node.h | 6 ++++++ src/qt/intro.cpp | 25 +++++++++++++++---------- src/qt/intro.h | 5 ++++- 7 files changed, 42 insertions(+), 12 deletions(-) diff --git a/doc/release-process.md b/doc/release-process.md index aaae8a0818e0..f1e3e480faea 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -21,7 +21,7 @@ Before every minor and major release: Before every major release: * Update hardcoded [seeds](/contrib/seeds/README.md). TODO: Give example PR for Dash -* Update [`BLOCK_CHAIN_SIZE`](/src/qt/intro.cpp) to the current size plus some overhead. +* Update [`src/chainparams.cpp`](/src/chainparams.cpp) m_assumed_blockchain_size and m_assumed_chain_state_size with the current size plus some overhead. * Update `src/chainparams.cpp` chainTxData with statistics about the transaction count and rate. Use the output of the RPC `getchaintxstats`, see [this pull request](https://github.com/bitcoin/bitcoin/pull/12270) for an example. Reviewers can verify the results by running `getchaintxstats ` with the `window_block_count` and `window_last_block_hash` from your output. * Update version of `contrib/gitian-descriptors/*.yml`: usually one'd want to do this on master after branching off the release - but be sure to at least do it before a new major release diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 95a0bf284823..8e5e43c00d89 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -423,6 +423,8 @@ class CMainParams : public CChainParams { pchMessageStart[3] = 0xbd; nDefaultPort = 9999; nPruneAfterHeight = 100000; + m_assumed_blockchain_size = 35; + m_assumed_chain_state_size = 1; genesis = CreateGenesisBlock(1390095618, 28917698, 0x1e0ffff0, 1, 50 * COIN); consensus.hashGenesisBlock = genesis.GetHash(); @@ -626,6 +628,8 @@ class CTestNetParams : public CChainParams { pchMessageStart[3] = 0xff; nDefaultPort = 19999; nPruneAfterHeight = 1000; + m_assumed_blockchain_size = 3; + m_assumed_chain_state_size = 1; genesis = CreateGenesisBlock(1390666206UL, 3861367235UL, 0x1e0ffff0, 1, 50 * COIN); consensus.hashGenesisBlock = genesis.GetHash(); @@ -806,6 +810,8 @@ class CDevNetParams : public CChainParams { pchMessageStart[3] = 0xce; nDefaultPort = 19799; nPruneAfterHeight = 1000; + m_assumed_blockchain_size = 0; + m_assumed_chain_state_size = 0; genesis = CreateGenesisBlock(1417713337, 1096447, 0x207fffff, 1, 50 * COIN); consensus.hashGenesisBlock = genesis.GetHash(); @@ -962,6 +968,8 @@ class CRegTestParams : public CChainParams { pchMessageStart[3] = 0xdc; nDefaultPort = 19899; nPruneAfterHeight = 1000; + m_assumed_blockchain_size = 0; + m_assumed_chain_state_size = 0; genesis = CreateGenesisBlock(1417713337, 1096447, 0x207fffff, 1, 50 * COIN); consensus.hashGenesisBlock = genesis.GetHash(); diff --git a/src/chainparams.h b/src/chainparams.h index ce30aaad77c2..bbf17c2fc930 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -70,6 +70,10 @@ class CChainParams /** Require addresses specified with "-externalip" parameter to be routable */ bool RequireRoutableExternalIP() const { return fRequireRoutableExternalIP; } uint64_t PruneAfterHeight() const { return nPruneAfterHeight; } + /** Minimum free space (in GB) needed for data directory */ + uint64_t AssumedBlockchainSize() const { return m_assumed_blockchain_size; } + /** Minimum free space (in GB) needed for data directory when pruned; Does not include prune target*/ + uint64_t AssumedChainStateSize() const { return m_assumed_chain_state_size; } /** Make miner stop after a block is found. In RPC, don't return until nGenProcLimit blocks are generated */ bool MineBlocksOnDemand() const { return fMineBlocksOnDemand; } /** Allow multiple addresses to be selected from the same network group (e.g. 192.168.x.x) */ @@ -109,6 +113,8 @@ class CChainParams CMessageHeader::MessageStartChars pchMessageStart; int nDefaultPort; uint64_t nPruneAfterHeight; + uint64_t m_assumed_blockchain_size; + uint64_t m_assumed_chain_state_size; std::vector vSeeds; std::vector base58Prefixes[MAX_BASE58_TYPES]; int nExtCoinType; diff --git a/src/interfaces/node.cpp b/src/interfaces/node.cpp index c9c647d8caf0..b1ffa68abe34 100644 --- a/src/interfaces/node.cpp +++ b/src/interfaces/node.cpp @@ -169,6 +169,8 @@ class NodeImpl : public Node bool softSetArg(const std::string& arg, const std::string& value) override { return gArgs.SoftSetArg(arg, value); } bool softSetBoolArg(const std::string& arg, bool value) override { return gArgs.SoftSetBoolArg(arg, value); } void selectParams(const std::string& network) override { SelectParams(network); } + uint64_t getAssumedBlockchainSize() override { return Params().AssumedBlockchainSize(); } + uint64_t getAssumedChainStateSize() override { return Params().AssumedChainStateSize(); } std::string getNetwork() override { return Params().NetworkIDString(); } void initLogging() override { InitLogging(); } void initParameterInteraction() override { InitParameterInteraction(); } diff --git a/src/interfaces/node.h b/src/interfaces/node.h index f7d9715d6ca6..40f68e30521c 100644 --- a/src/interfaces/node.h +++ b/src/interfaces/node.h @@ -108,6 +108,12 @@ class Node //! Choose network parameters. virtual void selectParams(const std::string& network) = 0; + //! Get the (assumed) blockchain size. + virtual uint64_t getAssumedBlockchainSize() = 0; + + //! Get the (assumed) chain state size. + virtual uint64_t getAssumedChainStateSize() = 0; + //! Get network name. virtual std::string getNetwork() = 0; diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index 076a70fdaa10..14bed2451074 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -23,10 +23,6 @@ #include static const uint64_t GB_BYTES = 1000000000LL; -/* Minimum free space (in GB) needed for data directory */ -static const uint64_t BLOCK_CHAIN_SIZE = 35; -/* Minimum free space (in GB) needed for data directory when pruned; Does not include prune target */ -static const uint64_t CHAIN_STATE_SIZE = 1; /* Total required space (in GB) depending on user choice (prune, not prune) */ static uint64_t requiredSpace; @@ -115,11 +111,13 @@ void FreespaceChecker::check() } -Intro::Intro(QWidget *parent) : +Intro::Intro(QWidget *parent, uint64_t blockchain_size, uint64_t chain_state_size) : QDialog(parent), ui(new Ui::Intro), thread(0), - signalled(false) + signalled(false), + m_blockchain_size(blockchain_size), + m_chain_state_size(chain_state_size) { ui->setupUi(this); ui->welcomeLabel->setText(ui->welcomeLabel->text().arg(tr(PACKAGE_NAME))); @@ -127,14 +125,14 @@ Intro::Intro(QWidget *parent) : ui->lblExplanation1->setText(ui->lblExplanation1->text() .arg(tr(PACKAGE_NAME)) - .arg(BLOCK_CHAIN_SIZE) + .arg(m_blockchain_size) .arg(2014) .arg("Dash") ); ui->lblExplanation2->setText(ui->lblExplanation2->text().arg(tr(PACKAGE_NAME))); uint64_t pruneTarget = std::max(0, gArgs.GetArg("-prune", 0)); - requiredSpace = BLOCK_CHAIN_SIZE; + requiredSpace = m_blockchain_size; QString storageRequiresMsg = tr("At least %1 GB of data will be stored in this directory, and it will grow over time."); if (pruneTarget) { uint64_t prunedGBs = std::ceil(pruneTarget * 1024 * 1024.0 / GB_BYTES); @@ -146,7 +144,7 @@ Intro::Intro(QWidget *parent) : } else { ui->lblExplanation3->setVisible(false); } - requiredSpace += CHAIN_STATE_SIZE; + requiredSpace += m_chain_state_size; ui->sizeWarningLabel->setText( tr("%1 will download and store a copy of the Dash block chain.").arg(tr(PACKAGE_NAME)) + " " + storageRequiresMsg.arg(requiredSpace) + " " + @@ -205,8 +203,15 @@ bool Intro::pickDataDirectory(interfaces::Node& node) if(!fs::exists(GUIUtil::qstringToBoostPath(dataDir)) || gArgs.GetBoolArg("-choosedatadir", DEFAULT_CHOOSE_DATADIR) || dataDirDefaultCurrent != dataDirDefaultSettings) { + /* Use selectParams here to guarantee Params() can be used by node interface */ + try { + node.selectParams(gArgs.GetChainName()); + } catch (const std::exception&) { + return false; + } + /* Let the user choose one */ - Intro intro; + Intro intro(0, node.getAssumedChainStateSize(), node.getAssumedChainStateSize()); GUIUtil::disableMacFocusRect(&intro); GUIUtil::loadStyleSheet(true); intro.setDataDirectory(dataDirDefaultCurrent); diff --git a/src/qt/intro.h b/src/qt/intro.h index ad1a6368c96e..5ae15412215a 100644 --- a/src/qt/intro.h +++ b/src/qt/intro.h @@ -30,7 +30,8 @@ class Intro : public QDialog Q_OBJECT public: - explicit Intro(QWidget *parent = 0); + explicit Intro(QWidget *parent = 0, + uint64_t blockchain_size = 0, uint64_t chain_state_size = 0); ~Intro(); QString getDataDirectory(); @@ -71,6 +72,8 @@ private Q_SLOTS: QMutex mutex; bool signalled; QString pathToCheck; + uint64_t m_blockchain_size; + uint64_t m_chain_state_size; void startThread(); void checkPath(const QString &dataDir); From f239861ebabf4976b67a387d44db7f636b6b851a Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 14 Jan 2019 15:20:45 +0100 Subject: [PATCH 06/23] Merge #15114: Qt: Replace remaining 0 with nullptr 3a0e76fc12b91b2846d756981e15f09b767a9c37 Replace remaining 0 with nullptr in Qt code (Ben Woosley) 9096276e0b2d5b7e19af9a5f3c144ef108ee55e0 Don't use zero as null pointer constant (-Wzero-as-null-pointer-constant) (practicalswift) Pull request description: This corrects all violations of `-Wzero-as-null-pointer-constant` identified in the Qt codebase. These changes are extracted from #15112 as suggested by @MarcoFalke to ease review. This is in service of enabling `-Wzero-as-null-pointer-constant`, which should eliminate this as a concern going forward. Note there are 2 non-Qt changes: `src/test/allocator_tests.cpp` and `src/wallet/db.cpp`. Tree-SHA512: 206bd668802147ba42bc413c2d7d259cb59aca9ec1da74a6bf2ca3932e60ae492faacbc61bcee0fd6b4b49a4d59d075b7e5404f0526b36c47718f9b0587e7768 --- src/qt/addressbookpage.cpp | 2 +- src/qt/addressbookpage.h | 2 +- src/qt/addresstablemodel.cpp | 6 ++--- src/qt/addresstablemodel.h | 2 +- src/qt/askpassphrasedialog.cpp | 2 +- src/qt/bantablemodel.cpp | 5 ++-- src/qt/bantablemodel.h | 2 +- src/qt/bitcoinamountfield.cpp | 6 ++--- src/qt/bitcoinamountfield.h | 4 ++-- src/qt/bitcoingui.cpp | 8 +++---- src/qt/bitcoingui.h | 2 +- src/qt/clientmodel.cpp | 6 ++--- src/qt/clientmodel.h | 2 +- src/qt/coincontroltreewidget.h | 2 +- src/qt/csvmodelwriter.cpp | 2 +- src/qt/csvmodelwriter.h | 2 +- src/qt/dash.cpp | 38 +++++++++++++++--------------- src/qt/editaddressdialog.cpp | 4 ++-- src/qt/editaddressdialog.h | 2 +- src/qt/guiutil.h | 2 +- src/qt/intro.cpp | 6 ++--- src/qt/intro.h | 2 +- src/qt/networkstyle.cpp | 2 +- src/qt/optionsdialog.cpp | 6 ++--- src/qt/optionsmodel.h | 2 +- src/qt/overviewpage.cpp | 4 ++-- src/qt/overviewpage.h | 2 +- src/qt/paymentserver.cpp | 8 +++---- src/qt/peertablemodel.cpp | 7 +++--- src/qt/peertablemodel.h | 2 +- src/qt/qvalidatedlineedit.cpp | 2 +- src/qt/qvaluecombobox.h | 2 +- src/qt/receivecoinsdialog.cpp | 4 ++-- src/qt/receivecoinsdialog.h | 2 +- src/qt/receiverequestdialog.cpp | 4 ++-- src/qt/receiverequestdialog.h | 4 ++-- src/qt/sendcoinsdialog.cpp | 6 ++--- src/qt/sendcoinsdialog.h | 4 ++-- src/qt/sendcoinsentry.cpp | 4 ++-- src/qt/sendcoinsentry.h | 2 +- src/qt/signverifymessagedialog.cpp | 4 ++-- src/qt/splashscreen.cpp | 2 +- src/qt/trafficgraphwidget.cpp | 4 ++-- src/qt/trafficgraphwidget.h | 2 +- src/qt/transactiondescdialog.h | 2 +- src/qt/transactionfilterproxy.h | 2 +- src/qt/transactiontablemodel.cpp | 2 +- src/qt/transactiontablemodel.h | 2 +- src/qt/transactionview.cpp | 4 ++-- src/qt/transactionview.h | 2 +- src/qt/utilitydialog.h | 2 +- src/qt/walletframe.h | 2 +- src/qt/walletmodel.cpp | 6 ++--- src/qt/walletmodel.h | 2 +- src/qt/walletview.cpp | 4 ++-- src/test/allocator_tests.cpp | 6 ++--- 56 files changed, 111 insertions(+), 113 deletions(-) diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index 28378ebb2a24..5ff49bb50ce4 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -61,7 +61,7 @@ class AddressBookSortFilterProxyModel final : public QSortFilterProxyModel AddressBookPage::AddressBookPage(Mode _mode, Tabs _tab, QWidget* parent) : QDialog(parent), ui(new Ui::AddressBookPage), - model(0), + model(nullptr), mode(_mode), tab(_tab) { diff --git a/src/qt/addressbookpage.h b/src/qt/addressbookpage.h index e76f41f5727c..1080e9a7f617 100644 --- a/src/qt/addressbookpage.h +++ b/src/qt/addressbookpage.h @@ -37,7 +37,7 @@ class AddressBookPage : public QDialog ForEditing /**< Open address book for editing */ }; - explicit AddressBookPage(Mode mode, Tabs tab, QWidget* parent = 0); + explicit AddressBookPage(Mode mode, Tabs tab, QWidget* parent = nullptr); ~AddressBookPage(); void setModel(AddressTableModel *model); diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index 35e189777613..dd689f587ed4 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -155,7 +155,7 @@ class AddressTablePriv } else { - return 0; + return nullptr; } } }; @@ -306,8 +306,8 @@ QVariant AddressTableModel::headerData(int section, Qt::Orientation orientation, Qt::ItemFlags AddressTableModel::flags(const QModelIndex &index) const { - if(!index.isValid()) - return 0; + if (!index.isValid()) return Qt::NoItemFlags; + AddressTableEntry *rec = static_cast(index.internalPointer()); Qt::ItemFlags retval = Qt::ItemIsSelectable | Qt::ItemIsEnabled; diff --git a/src/qt/addresstablemodel.h b/src/qt/addresstablemodel.h index 49dcbb8f86d1..bd50628860fa 100644 --- a/src/qt/addresstablemodel.h +++ b/src/qt/addresstablemodel.h @@ -25,7 +25,7 @@ class AddressTableModel : public QAbstractTableModel Q_OBJECT public: - explicit AddressTableModel(WalletModel *parent = 0); + explicit AddressTableModel(WalletModel *parent = nullptr); ~AddressTableModel(); enum ColumnIndex { diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index 6736a0ff4ca4..7723c299dc03 100644 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -24,7 +24,7 @@ AskPassphraseDialog::AskPassphraseDialog(Mode _mode, QWidget *parent) : QDialog(parent), ui(new Ui::AskPassphraseDialog), mode(_mode), - model(0), + model(nullptr), fCapsLock(false) { ui->setupUi(this); diff --git a/src/qt/bantablemodel.cpp b/src/qt/bantablemodel.cpp index 2bab9f425440..93d2842dcff9 100644 --- a/src/qt/bantablemodel.cpp +++ b/src/qt/bantablemodel.cpp @@ -78,7 +78,7 @@ class BanTablePriv if (idx >= 0 && idx < cachedBanlist.size()) return &cachedBanlist[idx]; - return 0; + return nullptr; } }; @@ -151,8 +151,7 @@ QVariant BanTableModel::headerData(int section, Qt::Orientation orientation, int Qt::ItemFlags BanTableModel::flags(const QModelIndex &index) const { - if(!index.isValid()) - return 0; + if (!index.isValid()) return Qt::NoItemFlags; Qt::ItemFlags retval = Qt::ItemIsSelectable | Qt::ItemIsEnabled; return retval; diff --git a/src/qt/bantablemodel.h b/src/qt/bantablemodel.h index 1be29543f927..de0a6a7e4c19 100644 --- a/src/qt/bantablemodel.h +++ b/src/qt/bantablemodel.h @@ -45,7 +45,7 @@ class BanTableModel : public QAbstractTableModel Q_OBJECT public: - explicit BanTableModel(interfaces::Node& node, ClientModel *parent = 0); + explicit BanTableModel(interfaces::Node& node, ClientModel *parent = nullptr); ~BanTableModel(); void startAutoRefresh(); void stopAutoRefresh(); diff --git a/src/qt/bitcoinamountfield.cpp b/src/qt/bitcoinamountfield.cpp index cc59afdd1f06..58fe832452dd 100644 --- a/src/qt/bitcoinamountfield.cpp +++ b/src/qt/bitcoinamountfield.cpp @@ -18,7 +18,7 @@ * return validity. * @note Must return 0 if !valid. */ -static CAmount parse(const QString &text, int nUnit, bool *valid_out=0) +static CAmount parse(const QString &text, int nUnit, bool *valid_out= nullptr) { CAmount val = 0; bool valid = BitcoinUnits::parse(nUnit, text, &val); @@ -87,7 +87,7 @@ class AmountLineEdit: public QLineEdit } } - CAmount value(bool *valid_out=0) const + CAmount value(bool *valid_out=nullptr) const { return parse(text(), currentUnit, valid_out); } @@ -158,7 +158,7 @@ class AmountLineEdit: public QLineEdit BitcoinAmountField::BitcoinAmountField(QWidget *parent) : QWidget(parent), - amount(0) + amount(nullptr) { amount = new AmountLineEdit(this); amount->setLocale(QLocale::c()); diff --git a/src/qt/bitcoinamountfield.h b/src/qt/bitcoinamountfield.h index 07eee581e166..87fcf719a7c6 100644 --- a/src/qt/bitcoinamountfield.h +++ b/src/qt/bitcoinamountfield.h @@ -28,9 +28,9 @@ class BitcoinAmountField: public QWidget Q_PROPERTY(qint64 value READ value WRITE setValue NOTIFY valueChanged USER true) public: - explicit BitcoinAmountField(QWidget *parent = 0); + explicit BitcoinAmountField(QWidget *parent = nullptr); - CAmount value(bool *value=0) const; + CAmount value(bool *value=nullptr) const; void setValue(const CAmount& value); /** Make read-only **/ diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 1bedc3f6fa40..091ac1288542 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -1697,7 +1697,7 @@ void BitcoinGUI::updateProxyIcon() bool proxy_enabled = clientModel->getProxyInfo(ip_port); if (proxy_enabled) { - if (labelProxyIcon->pixmap() == 0) { + if (labelProxyIcon->pixmap() == nullptr) { QString ip_port_q = QString::fromStdString(ip_port); labelProxyIcon->setPixmap(GUIUtil::getIcon("proxy", GUIUtil::ThemedColor::GREEN).pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE)); labelProxyIcon->setToolTip(tr("Proxy is enabled: %1").arg(ip_port_q)); @@ -1743,7 +1743,7 @@ void BitcoinGUI::showProgress(const QString &title, int nProgress) progressDialog = new QProgressDialog(title, "", 0, 100, this); progressDialog->setWindowModality(Qt::ApplicationModal); progressDialog->setMinimumDuration(0); - progressDialog->setCancelButton(0); + progressDialog->setCancelButton(nullptr); progressDialog->setAutoClose(false); progressDialog->setValue(0); } @@ -1818,8 +1818,8 @@ void BitcoinGUI::handleRestart(QStringList args) } UnitDisplayStatusBarControl::UnitDisplayStatusBarControl() : - optionsModel(0), - menu(0) + optionsModel(nullptr), + menu(nullptr) { createContextMenu(); setToolTip(tr("Unit to show amounts in. Click to select another unit.")); diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 12418bc1698a..dc05219718db 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -67,7 +67,7 @@ class BitcoinGUI : public QMainWindow public: static const std::string DEFAULT_UIPLATFORM; - explicit BitcoinGUI(interfaces::Node& node, const NetworkStyle* networkStyle, QWidget* parent = 0); + explicit BitcoinGUI(interfaces::Node& node, const NetworkStyle* networkStyle, QWidget* parent = nullptr); ~BitcoinGUI(); /** Set the client model. diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index d38c064a2fbf..6fb1e42e77a6 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -38,9 +38,9 @@ ClientModel::ClientModel(interfaces::Node& node, OptionsModel *_optionsModel, QO QObject(parent), m_node(node), optionsModel(_optionsModel), - peerTableModel(0), - banTableModel(0), - pollTimer(0) + peerTableModel(nullptr), + banTableModel(nullptr), + pollTimer(nullptr) { cachedBestHeaderHeight = -1; cachedBestHeaderTime = -1; diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index 510cabcdca2b..ae5efa409893 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -48,7 +48,7 @@ class ClientModel : public QObject Q_OBJECT public: - explicit ClientModel(interfaces::Node& node, OptionsModel *optionsModel, QObject *parent = 0); + explicit ClientModel(interfaces::Node& node, OptionsModel *optionsModel, QObject *parent = nullptr); ~ClientModel(); interfaces::Node& node() const { return m_node; } diff --git a/src/qt/coincontroltreewidget.h b/src/qt/coincontroltreewidget.h index 09059f993416..790f2a4a29c1 100644 --- a/src/qt/coincontroltreewidget.h +++ b/src/qt/coincontroltreewidget.h @@ -13,7 +13,7 @@ class CoinControlTreeWidget : public QTreeWidget Q_OBJECT public: - explicit CoinControlTreeWidget(QWidget *parent = 0); + explicit CoinControlTreeWidget(QWidget *parent = nullptr); protected: virtual void keyPressEvent(QKeyEvent *event) override; diff --git a/src/qt/csvmodelwriter.cpp b/src/qt/csvmodelwriter.cpp index 14af855acb39..6b89497f6d4d 100644 --- a/src/qt/csvmodelwriter.cpp +++ b/src/qt/csvmodelwriter.cpp @@ -10,7 +10,7 @@ CSVModelWriter::CSVModelWriter(const QString &_filename, QObject *parent) : QObject(parent), - filename(_filename), model(0) + filename(_filename), model(nullptr) { } diff --git a/src/qt/csvmodelwriter.h b/src/qt/csvmodelwriter.h index edea369ad1fa..e8611bea355d 100644 --- a/src/qt/csvmodelwriter.h +++ b/src/qt/csvmodelwriter.h @@ -20,7 +20,7 @@ class CSVModelWriter : public QObject Q_OBJECT public: - explicit CSVModelWriter(const QString &filename, QObject *parent = 0); + explicit CSVModelWriter(const QString &filename, QObject *parent = nullptr); void setModel(const QAbstractItemModel *model); void addColumn(const QString &title, int column, int role=Qt::EditRole); diff --git a/src/qt/dash.cpp b/src/qt/dash.cpp index 835e31cde1f3..4d7c98328b12 100644 --- a/src/qt/dash.cpp +++ b/src/qt/dash.cpp @@ -294,14 +294,14 @@ void BitcoinCore::shutdown() BitcoinApplication::BitcoinApplication(interfaces::Node& node, int &argc, char **argv): QApplication(argc, argv), - coreThread(0), + coreThread(nullptr), m_node(node), - optionsModel(0), - clientModel(0), - window(0), - pollShutdownTimer(0), + optionsModel(nullptr), + clientModel(nullptr), + window(nullptr), + pollShutdownTimer(nullptr), #ifdef ENABLE_WALLET - paymentServer(0), + paymentServer(nullptr), m_wallet_models(), #endif returnValue(0) @@ -320,10 +320,10 @@ BitcoinApplication::~BitcoinApplication() } delete window; - window = 0; + window = nullptr; #ifdef ENABLE_WALLET delete paymentServer; - paymentServer = 0; + paymentServer = nullptr; #endif // Delete Qt-settings if user clicked on "Reset Options" QSettings settings; @@ -332,7 +332,7 @@ BitcoinApplication::~BitcoinApplication() settings.sync(); } delete optionsModel; - optionsModel = 0; + optionsModel = nullptr; } #ifdef ENABLE_WALLET @@ -349,14 +349,14 @@ void BitcoinApplication::createOptionsModel(bool resetSettings) void BitcoinApplication::createWindow(const NetworkStyle *networkStyle) { - window = new BitcoinGUI(m_node, networkStyle, 0); + window = new BitcoinGUI(m_node, networkStyle, nullptr); pollShutdownTimer = new QTimer(window); connect(pollShutdownTimer, &QTimer::timeout, window, &BitcoinGUI::detectShutdown); } void BitcoinApplication::createSplashScreen(const NetworkStyle *networkStyle) { - SplashScreen *splash = new SplashScreen(m_node, 0, networkStyle); + SplashScreen *splash = new SplashScreen(m_node, nullptr, networkStyle); // We don't hold a direct pointer to the splash screen after creation, but the splash // screen will take care of deleting itself when slotFinish happens. splash->show(); @@ -413,7 +413,7 @@ void BitcoinApplication::requestShutdown() qDebug() << __func__ << ": Requesting shutdown"; startThread(); window->hide(); - window->setClientModel(0); + window->setClientModel(nullptr); pollShutdownTimer->stop(); #ifdef ENABLE_WALLET @@ -424,7 +424,7 @@ void BitcoinApplication::requestShutdown() m_wallet_models.clear(); #endif delete clientModel; - clientModel = 0; + clientModel = nullptr; m_node.startShutdown(); @@ -526,7 +526,7 @@ void BitcoinApplication::shutdownResult() void BitcoinApplication::handleRunawayException(const QString &message) { - QMessageBox::critical(0, "Runaway exception", BitcoinGUI::tr("A fatal error occurred. Dash Core can no longer continue safely and will quit.") + QString("\n\n") + message); + QMessageBox::critical(nullptr, "Runaway exception", BitcoinGUI::tr("A fatal error occurred. Dash Core can no longer continue safely and will quit.") + QString("\n\n") + message); ::exit(EXIT_FAILURE); } @@ -608,7 +608,7 @@ int main(int argc, char *argv[]) SetupUIArgs(); std::string error; if (!node->parseParameters(argc, argv, error)) { - QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), + QMessageBox::critical(nullptr, QObject::tr(PACKAGE_NAME), QObject::tr("Error parsing command line arguments: %1.").arg(QString::fromStdString(error))); return EXIT_FAILURE; } @@ -649,12 +649,12 @@ int main(int argc, char *argv[]) /// - Do not call GetDataDir(true) before this step finishes if (!fs::is_directory(GetDataDir(false))) { - QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), - QObject::tr("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(gArgs.GetArg("-datadir", "")))); + QMessageBox::critical(nullptr, QObject::tr(PACKAGE_NAME), + QObject::tr("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(gArgs.GetArg("-datadir", "")))); return EXIT_FAILURE; } if (!node->readConfigFiles(error)) { - QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), + QMessageBox::critical(nullptr, QObject::tr(PACKAGE_NAME), QObject::tr("Error: Cannot parse configuration file: %1.").arg(QString::fromStdString(error))); return EXIT_FAILURE; } @@ -669,7 +669,7 @@ int main(int argc, char *argv[]) try { node->selectParams(gArgs.GetChainName()); } catch(std::exception &e) { - QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), QObject::tr("Error: %1").arg(e.what())); + QMessageBox::critical(nullptr, QObject::tr(PACKAGE_NAME), QObject::tr("Error: %1").arg(e.what())); return EXIT_FAILURE; } #ifdef ENABLE_WALLET diff --git a/src/qt/editaddressdialog.cpp b/src/qt/editaddressdialog.cpp index 78293d25d1b4..3426da189569 100644 --- a/src/qt/editaddressdialog.cpp +++ b/src/qt/editaddressdialog.cpp @@ -15,9 +15,9 @@ EditAddressDialog::EditAddressDialog(Mode _mode, QWidget *parent) : QDialog(parent), ui(new Ui::EditAddressDialog), - mapper(0), + mapper(nullptr), mode(_mode), - model(0) + model(nullptr) { ui->setupUi(this); diff --git a/src/qt/editaddressdialog.h b/src/qt/editaddressdialog.h index 864f799bf7ef..75b8844b11d0 100644 --- a/src/qt/editaddressdialog.h +++ b/src/qt/editaddressdialog.h @@ -30,7 +30,7 @@ class EditAddressDialog : public QDialog EditSendingAddress }; - explicit EditAddressDialog(Mode mode, QWidget *parent = 0); + explicit EditAddressDialog(Mode mode, QWidget *parent = nullptr); ~EditAddressDialog(); void setModel(AddressTableModel *model); diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index 97454f8b8823..93ad2d7f190b 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -202,7 +202,7 @@ namespace GUIUtil Q_OBJECT public: - explicit ToolTipToRichTextFilter(int size_threshold, QObject *parent = 0); + explicit ToolTipToRichTextFilter(int size_threshold, QObject *parent = nullptr); protected: bool eventFilter(QObject *obj, QEvent *evt) override; diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index 14bed2451074..f2eca1c4158f 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -114,7 +114,7 @@ void FreespaceChecker::check() Intro::Intro(QWidget *parent, uint64_t blockchain_size, uint64_t chain_state_size) : QDialog(parent), ui(new Ui::Intro), - thread(0), + thread(nullptr), signalled(false), m_blockchain_size(blockchain_size), m_chain_state_size(chain_state_size) @@ -232,7 +232,7 @@ bool Intro::pickDataDirectory(interfaces::Node& node) } break; } catch (const fs::filesystem_error&) { - QMessageBox::critical(0, tr(PACKAGE_NAME), + QMessageBox::critical(nullptr, tr(PACKAGE_NAME), tr("Error: Specified data directory \"%1\" cannot be created.").arg(dataDir)); /* fall through, back to choosing screen */ } @@ -292,7 +292,7 @@ void Intro::on_dataDirectory_textChanged(const QString &dataDirStr) void Intro::on_ellipsisButton_clicked() { - QString dir = QDir::toNativeSeparators(QFileDialog::getExistingDirectory(0, "Choose data directory", ui->dataDirectory->text())); + QString dir = QDir::toNativeSeparators(QFileDialog::getExistingDirectory(nullptr, "Choose data directory", ui->dataDirectory->text())); if(!dir.isEmpty()) ui->dataDirectory->setText(dir); } diff --git a/src/qt/intro.h b/src/qt/intro.h index 5ae15412215a..fab14c443369 100644 --- a/src/qt/intro.h +++ b/src/qt/intro.h @@ -30,7 +30,7 @@ class Intro : public QDialog Q_OBJECT public: - explicit Intro(QWidget *parent = 0, + explicit Intro(QWidget *parent = nullptr, uint64_t blockchain_size = 0, uint64_t chain_state_size = 0); ~Intro(); diff --git a/src/qt/networkstyle.cpp b/src/qt/networkstyle.cpp index 7a9c277e2c8a..2f64c518b09d 100644 --- a/src/qt/networkstyle.cpp +++ b/src/qt/networkstyle.cpp @@ -108,5 +108,5 @@ const NetworkStyle *NetworkStyle::instantiate(const QString &networkId) titleAddText.c_str()); } } - return 0; + return nullptr; } diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index b9761ecb3d58..2708f8e52443 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -34,9 +34,9 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) : QDialog(parent), ui(new Ui::OptionsDialog), - model(0), - mapper(0), - pageButtons(0) + model(nullptr), + mapper(nullptr), + pageButtons(nullptr) { ui->setupUi(this); diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h index 8789f6e7938c..541d6385f8e0 100644 --- a/src/qt/optionsmodel.h +++ b/src/qt/optionsmodel.h @@ -31,7 +31,7 @@ class OptionsModel : public QAbstractListModel Q_OBJECT public: - explicit OptionsModel(interfaces::Node& node, QObject *parent = 0, bool resetSettings = false); + explicit OptionsModel(interfaces::Node& node, QObject *parent = nullptr, bool resetSettings = false); enum OptionID { StartAtStartup, // bool diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index e3a42ca5d09b..481546c72e03 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -112,8 +112,8 @@ OverviewPage::OverviewPage(QWidget* parent) : QWidget(parent), timer(nullptr), ui(new Ui::OverviewPage), - clientModel(0), - walletModel(0), + clientModel(nullptr), + walletModel(nullptr), cachedNumISLocks(-1), txdelegate(new TxViewDelegate(this)) { diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h index 0e24c6df6b84..8b0f12dfd14c 100644 --- a/src/qt/overviewpage.h +++ b/src/qt/overviewpage.h @@ -29,7 +29,7 @@ class OverviewPage : public QWidget Q_OBJECT public: - explicit OverviewPage(QWidget* parent = 0); + explicit OverviewPage(QWidget* parent = nullptr); ~OverviewPage(); void setClientModel(ClientModel *clientModel); diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 190d1d7f3ac1..c4ffba31401a 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -292,9 +292,9 @@ bool PaymentServer::ipcSendCommandLine() PaymentServer::PaymentServer(QObject* parent, bool startLocalServer) : QObject(parent), saveURIs(true), - uriServer(0), - netManager(0), - optionsModel(0) + uriServer(nullptr), + netManager(nullptr), + optionsModel(nullptr) { // Verify that the version of the library that we linked against is // compatible with the version of the headers we compiled against. @@ -317,7 +317,7 @@ PaymentServer::PaymentServer(QObject* parent, bool startLocalServer) : if (!uriServer->listen(name)) { // constructor is called early in init, so don't use "Q_EMIT message()" here - QMessageBox::critical(0, tr("Payment request error"), + QMessageBox::critical(nullptr, tr("Payment request error"), tr("Cannot start dash: click-to-pay handler")); } else { diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp index b4bac4f166f8..4f77b42f098a 100644 --- a/src/qt/peertablemodel.cpp +++ b/src/qt/peertablemodel.cpp @@ -99,7 +99,7 @@ class PeerTablePriv if (idx >= 0 && idx < cachedNodeStats.size()) return &cachedNodeStats[idx]; - return 0; + return nullptr; } }; @@ -107,7 +107,7 @@ PeerTableModel::PeerTableModel(interfaces::Node& node, ClientModel *parent) : QAbstractTableModel(parent), m_node(node), clientModel(parent), - timer(0) + timer(nullptr) { columns << tr("NodeId") << tr("Node/Service") << tr("Ping") << tr("Sent") << tr("Received") << tr("User Agent"); priv.reset(new PeerTablePriv()); @@ -204,8 +204,7 @@ QVariant PeerTableModel::headerData(int section, Qt::Orientation orientation, in Qt::ItemFlags PeerTableModel::flags(const QModelIndex &index) const { - if(!index.isValid()) - return 0; + if (!index.isValid()) return Qt::NoItemFlags; Qt::ItemFlags retval = Qt::ItemIsSelectable | Qt::ItemIsEnabled; return retval; diff --git a/src/qt/peertablemodel.h b/src/qt/peertablemodel.h index 80a5c17f6e20..852fe2eed38e 100644 --- a/src/qt/peertablemodel.h +++ b/src/qt/peertablemodel.h @@ -51,7 +51,7 @@ class PeerTableModel : public QAbstractTableModel Q_OBJECT public: - explicit PeerTableModel(interfaces::Node& node, ClientModel *parent = 0); + explicit PeerTableModel(interfaces::Node& node, ClientModel *parent = nullptr); ~PeerTableModel(); const CNodeCombinedStats *getNodeStats(int idx); int getRowByNodeId(NodeId nodeid); diff --git a/src/qt/qvalidatedlineedit.cpp b/src/qt/qvalidatedlineedit.cpp index 73d30185f98f..43bfc5d7abfb 100644 --- a/src/qt/qvalidatedlineedit.cpp +++ b/src/qt/qvalidatedlineedit.cpp @@ -10,7 +10,7 @@ QValidatedLineEdit::QValidatedLineEdit(QWidget *parent) : QLineEdit(parent), valid(true), - checkValidator(0) + checkValidator(nullptr) { connect(this, &QValidatedLineEdit::textChanged, this, &QValidatedLineEdit::markValid); } diff --git a/src/qt/qvaluecombobox.h b/src/qt/qvaluecombobox.h index f266302310f1..8892071fbaf9 100644 --- a/src/qt/qvaluecombobox.h +++ b/src/qt/qvaluecombobox.h @@ -16,7 +16,7 @@ class QValueComboBox : public QComboBox Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged USER true) public: - explicit QValueComboBox(QWidget *parent = 0); + explicit QValueComboBox(QWidget *parent = nullptr); QVariant value() const; void setValue(const QVariant &value); diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index f70ee84b483d..755181455b35 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -22,8 +22,8 @@ ReceiveCoinsDialog::ReceiveCoinsDialog(QWidget* parent) : QDialog(parent), ui(new Ui::ReceiveCoinsDialog), - columnResizingFixer(0), - model(0) + columnResizingFixer(nullptr), + model(nullptr) { ui->setupUi(this); diff --git a/src/qt/receivecoinsdialog.h b/src/qt/receivecoinsdialog.h index 12a9762d7b90..8674ad3594fa 100644 --- a/src/qt/receivecoinsdialog.h +++ b/src/qt/receivecoinsdialog.h @@ -38,7 +38,7 @@ class ReceiveCoinsDialog : public QDialog MINIMUM_COLUMN_WIDTH = 130 }; - explicit ReceiveCoinsDialog(QWidget* parent = 0); + explicit ReceiveCoinsDialog(QWidget* parent = nullptr); ~ReceiveCoinsDialog(); void setModel(WalletModel *model); diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp index d7da72d60155..a516380e4196 100644 --- a/src/qt/receiverequestdialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -26,7 +26,7 @@ #endif QRImageWidget::QRImageWidget(QWidget *parent): - QLabel(parent), contextMenu(0) + QLabel(parent), contextMenu(nullptr) { contextMenu = new QMenu(this); QAction *saveImageAction = new QAction(tr("&Save Image..."), this); @@ -88,7 +88,7 @@ void QRImageWidget::contextMenuEvent(QContextMenuEvent *event) ReceiveRequestDialog::ReceiveRequestDialog(QWidget *parent) : QDialog(parent), ui(new Ui::ReceiveRequestDialog), - model(0) + model(nullptr) { ui->setupUi(this); diff --git a/src/qt/receiverequestdialog.h b/src/qt/receiverequestdialog.h index 71feb54f42f8..45bbeafbea31 100644 --- a/src/qt/receiverequestdialog.h +++ b/src/qt/receiverequestdialog.h @@ -28,7 +28,7 @@ class QRImageWidget : public QLabel Q_OBJECT public: - explicit QRImageWidget(QWidget *parent = 0); + explicit QRImageWidget(QWidget *parent = nullptr); QImage exportImage(); public Q_SLOTS: @@ -48,7 +48,7 @@ class ReceiveRequestDialog : public QDialog Q_OBJECT public: - explicit ReceiveRequestDialog(QWidget *parent = 0); + explicit ReceiveRequestDialog(QWidget *parent = nullptr); ~ReceiveRequestDialog(); void setModel(WalletModel *model); diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index f476b2de7834..3fe43ff6f543 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -513,7 +513,7 @@ SendCoinsEntry *SendCoinsDialog::addEntry() void SendCoinsDialog::updateTabsAndLabels() { - setupTabChain(0); + setupTabChain(nullptr); coinControlUpdateLabels(); } @@ -548,7 +548,7 @@ QWidget *SendCoinsDialog::setupTabChain(QWidget *prev) void SendCoinsDialog::setAddress(const QString &address) { - SendCoinsEntry *entry = 0; + SendCoinsEntry *entry = nullptr; // Replace the first entry if it is still unused if(ui->entries->count() == 1) { @@ -571,7 +571,7 @@ void SendCoinsDialog::pasteEntry(const SendCoinsRecipient &rv) if(!fNewRecipientAllowed) return; - SendCoinsEntry *entry = 0; + SendCoinsEntry *entry = nullptr; // Replace the first entry if it is still unused if(ui->entries->count() == 1) { diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h index 32eed4453dfa..2bd7dc73cc50 100644 --- a/src/qt/sendcoinsdialog.h +++ b/src/qt/sendcoinsdialog.h @@ -34,7 +34,7 @@ class SendCoinsDialog : public QDialog Q_OBJECT public: - explicit SendCoinsDialog(bool fCoinJoin = false, QWidget* parent = 0); + explicit SendCoinsDialog(bool fCoinJoin = false, QWidget* parent = nullptr); ~SendCoinsDialog(); void setClientModel(ClientModel *clientModel); @@ -113,7 +113,7 @@ class SendConfirmationDialog : public QMessageBox Q_OBJECT public: - SendConfirmationDialog(const QString &title, const QString &text, int secDelay = 0, QWidget *parent = 0); + SendConfirmationDialog(const QString &title, const QString &text, int secDelay = 0, QWidget *parent = nullptr); int exec() override; private Q_SLOTS: diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp index f924f6b09ab9..a3848d650847 100644 --- a/src/qt/sendcoinsentry.cpp +++ b/src/qt/sendcoinsentry.cpp @@ -17,7 +17,7 @@ SendCoinsEntry::SendCoinsEntry(QWidget* parent) : QStackedWidget(parent), ui(new Ui::SendCoinsEntry), - model(0) + model(nullptr) { ui->setupUi(this); @@ -156,7 +156,7 @@ bool SendCoinsEntry::validate(interfaces::Node& node) } // Sending a zero amount is invalid - if (ui->payAmount->value(0) <= 0) + if (ui->payAmount->value(nullptr) <= 0) { ui->payAmount->setValid(false); retval = false; diff --git a/src/qt/sendcoinsentry.h b/src/qt/sendcoinsentry.h index ee662687175e..e5d7a5cb6559 100644 --- a/src/qt/sendcoinsentry.h +++ b/src/qt/sendcoinsentry.h @@ -25,7 +25,7 @@ class SendCoinsEntry : public QStackedWidget Q_OBJECT public: - explicit SendCoinsEntry(QWidget* parent = 0); + explicit SendCoinsEntry(QWidget* parent = nullptr); ~SendCoinsEntry(); void setModel(WalletModel *model); diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp index 7da33bdfeff2..cfe8839feab1 100644 --- a/src/qt/signverifymessagedialog.cpp +++ b/src/qt/signverifymessagedialog.cpp @@ -24,8 +24,8 @@ SignVerifyMessageDialog::SignVerifyMessageDialog(QWidget* parent) : QDialog(parent), ui(new Ui::SignVerifyMessageDialog), - model(0), - pageButtons(0) + model(nullptr), + pageButtons(nullptr) { ui->setupUi(this); diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index bd892a081124..fce656e7dcfe 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -28,7 +28,7 @@ SplashScreen::SplashScreen(interfaces::Node& node, Qt::WindowFlags f, const NetworkStyle *networkStyle) : - QWidget(0, f), curAlignment(0), m_node(node) + QWidget(nullptr, f), curAlignment(0), m_node(node) { // transparent background diff --git a/src/qt/trafficgraphwidget.cpp b/src/qt/trafficgraphwidget.cpp index 4562e71fe301..317cd48c61d9 100644 --- a/src/qt/trafficgraphwidget.cpp +++ b/src/qt/trafficgraphwidget.cpp @@ -21,10 +21,10 @@ TrafficGraphWidget::TrafficGraphWidget(QWidget *parent) : QWidget(parent), - timer(0), + timer(nullptr), fMax(DEFAULT_SAMPLE_HEIGHT), nMins(0), - clientModel(0), + clientModel(nullptr), trafficGraphData(TrafficGraphData::Range_30m) { timer = new QTimer(this); diff --git a/src/qt/trafficgraphwidget.h b/src/qt/trafficgraphwidget.h index 3190d4f66e1e..bcfc852d5365 100644 --- a/src/qt/trafficgraphwidget.h +++ b/src/qt/trafficgraphwidget.h @@ -24,7 +24,7 @@ class TrafficGraphWidget : public QWidget Q_OBJECT public: - explicit TrafficGraphWidget(QWidget *parent = 0); + explicit TrafficGraphWidget(QWidget *parent = nullptr); void setClientModel(ClientModel *model); int getGraphRangeMins() const; diff --git a/src/qt/transactiondescdialog.h b/src/qt/transactiondescdialog.h index f1371b385648..8fd3f3166a6c 100644 --- a/src/qt/transactiondescdialog.h +++ b/src/qt/transactiondescdialog.h @@ -21,7 +21,7 @@ class TransactionDescDialog : public QDialog Q_OBJECT public: - explicit TransactionDescDialog(const QModelIndex &idx, QWidget *parent = 0); + explicit TransactionDescDialog(const QModelIndex &idx, QWidget *parent = nullptr); ~TransactionDescDialog(); private: diff --git a/src/qt/transactionfilterproxy.h b/src/qt/transactionfilterproxy.h index 92482da71108..b3a66c64583d 100644 --- a/src/qt/transactionfilterproxy.h +++ b/src/qt/transactionfilterproxy.h @@ -16,7 +16,7 @@ class TransactionFilterProxy : public QSortFilterProxyModel Q_OBJECT public: - explicit TransactionFilterProxy(QObject *parent = 0); + explicit TransactionFilterProxy(QObject *parent = nullptr); /** Earliest date that can be represented (far in the past) */ static const QDateTime MIN_DATE; diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index e7e062c48abb..d935ee26a6bc 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -204,7 +204,7 @@ class TransactionTablePriv } return rec; } - return 0; + return nullptr; } QString describe(interfaces::Node& node, interfaces::Wallet& wallet, TransactionRecord *rec, int unit) diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h index 965333c19b53..5d1f6aadc1e7 100644 --- a/src/qt/transactiontablemodel.h +++ b/src/qt/transactiontablemodel.h @@ -27,7 +27,7 @@ class TransactionTableModel : public QAbstractTableModel Q_OBJECT public: - explicit TransactionTableModel(WalletModel *parent = 0); + explicit TransactionTableModel(WalletModel *parent = nullptr); ~TransactionTableModel(); enum ColumnIndex { diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index 2f9955bfb8eb..2d7aa53a9197 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -44,8 +44,8 @@ static const char* PERSISTENCE_DATE_FORMAT = "yyyy-MM-dd"; TransactionView::TransactionView(QWidget* parent) : - QWidget(parent), model(0), transactionProxyModel(0), - transactionView(0), abandonAction(0), columnResizingFixer(0) +QWidget(parent), model(nullptr), transactionProxyModel(nullptr), +transactionView(nullptr), abandonAction(nullptr), columnResizingFixer(nullptr) { QSettings settings; // Build filter row diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h index 4b403844af9d..badee36c93b7 100644 --- a/src/qt/transactionview.h +++ b/src/qt/transactionview.h @@ -35,7 +35,7 @@ class TransactionView : public QWidget Q_OBJECT public: - explicit TransactionView(QWidget* parent = 0); + explicit TransactionView(QWidget* parent = nullptr); void setModel(WalletModel *model); diff --git a/src/qt/utilitydialog.h b/src/qt/utilitydialog.h index 04091cd18f53..aa2de6e76f84 100644 --- a/src/qt/utilitydialog.h +++ b/src/qt/utilitydialog.h @@ -51,7 +51,7 @@ class ShutdownWindow : public QWidget Q_OBJECT public: - explicit ShutdownWindow(interfaces::Node& node, QWidget *parent=0, Qt::WindowFlags f=0); + explicit ShutdownWindow(interfaces::Node& node, QWidget *parent=nullptr, Qt::WindowFlags f=Qt::Widget); static QWidget *showShutdownWindow(interfaces::Node& node, BitcoinGUI *window); protected: diff --git a/src/qt/walletframe.h b/src/qt/walletframe.h index 4e02de5aeea8..b6b0483e2a05 100644 --- a/src/qt/walletframe.h +++ b/src/qt/walletframe.h @@ -31,7 +31,7 @@ class WalletFrame : public QFrame Q_OBJECT public: - explicit WalletFrame(BitcoinGUI* _gui = 0); + explicit WalletFrame(BitcoinGUI* _gui = nullptr); ~WalletFrame(); void setClientModel(ClientModel *clientModel); diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index a8f5090813b7..b23137415366 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -30,9 +30,9 @@ WalletModel::WalletModel(std::unique_ptr wallet, interfaces::Node& node, OptionsModel *_optionsModel, QObject *parent) : - QObject(parent), m_wallet(std::move(wallet)), m_node(node), optionsModel(_optionsModel), addressTableModel(0), - transactionTableModel(0), - recentRequestsTableModel(0), + QObject(parent), m_wallet(std::move(wallet)), m_node(node), optionsModel(_optionsModel), addressTableModel(nullptr), + transactionTableModel(nullptr), + recentRequestsTableModel(nullptr), cachedEncryptionStatus(Unencrypted), cachedNumBlocks(-1), cachedNumISLocks(0), diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index 68806ce5112e..87305e242b96 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -102,7 +102,7 @@ class WalletModel : public QObject Q_OBJECT public: - explicit WalletModel(std::unique_ptr wallet, interfaces::Node& node, OptionsModel *optionsModel, QObject *parent = 0); + explicit WalletModel(std::unique_ptr wallet, interfaces::Node& node, OptionsModel *optionsModel, QObject *parent = nullptr); ~WalletModel(); enum StatusCode // Returned by sendCoins diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index 4a508ae23eec..eae1a7dd1f98 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -34,8 +34,8 @@ WalletView::WalletView(QWidget* parent) : QStackedWidget(parent), - clientModel(0), - walletModel(0) + clientModel(nullptr), + walletModel(nullptr) { // Create tabs overviewPage = new OverviewPage(); diff --git a/src/test/allocator_tests.cpp b/src/test/allocator_tests.cpp index 1e795843c9c7..acea7d9e1fb5 100644 --- a/src/test/allocator_tests.cpp +++ b/src/test/allocator_tests.cpp @@ -105,13 +105,13 @@ BOOST_AUTO_TEST_CASE(arena_tests) // Go entirely wild: free and alloc interleaved, // generate targets and sizes using pseudo-randomness. for (int x=0; x<2048; ++x) - addr.push_back(0); + addr.push_back(nullptr); uint32_t s = 0x12345678; for (int x=0; x<5000; ++x) { int idx = s & (addr.size()-1); if (s & 0x80000000) { b.free(addr[idx]); - addr[idx] = 0; + addr[idx] = nullptr; } else if(!addr[idx]) { addr[idx] = b.alloc((s >> 16) & 2047); } @@ -146,7 +146,7 @@ class TestLockedPageAllocator: public LockedPageAllocator return reinterpret_cast(0x08000000 + (count<<24)); // Fake address, do not actually use this memory } - return 0; + return nullptr; } void FreeLocked(void* addr, size_t len) override { From d5f50c3df875f3725e6b1fe5560fee10155b6acb Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Tue, 15 Jan 2019 13:41:59 -0500 Subject: [PATCH 07/23] Merge #14963: mempool, validation: Explain cs_main locking semantics fa5e373365 validation: Add cs_main locking annotations (MarcoFalke) fa5c346c5a doc: Add comment to cs_main and mempool::cs (MarcoFalke) fafe941bdd test: Add missing validation locks (MarcoFalke) fac4558462 sync: Add RecursiveMutex type alias (MarcoFalke) Pull request description: Both the chain state and the transaction pool are validation specific, but access to them is protected by two locks. The two locks have the following semantics: * Writing to the chain state or adding transactions to the transaction pool -> Take both `cs_main` and `mempool::cs` * Reading either or removing transactions from the the transaction pool -> Take only the appropriate lock Tree-SHA512: 6f6e612ffc391904c6434a79a4f3f8de1b928bf0a3e3434b73561037b395e2b40a70a5a4bd8472dd230e9eacc8e5d5374c904a3c509910cf3971dd7ff59a626c --- src/bench/mempool_eviction.cpp | 4 +-- src/sync.h | 3 +- src/test/blockencodings_tests.cpp | 6 ++-- src/test/mempool_tests.cpp | 10 +++---- src/test/miner_tests.cpp | 2 +- src/test/policyestimator_tests.cpp | 2 +- src/txmempool.h | 46 ++++++++++++++++++++++++++---- src/validation.cpp | 16 ++++++++--- 8 files changed, 67 insertions(+), 22 deletions(-) diff --git a/src/bench/mempool_eviction.cpp b/src/bench/mempool_eviction.cpp index e6402d3a08c9..5945d22081fe 100644 --- a/src/bench/mempool_eviction.cpp +++ b/src/bench/mempool_eviction.cpp @@ -9,7 +9,7 @@ #include #include -static void AddTx(const CMutableTransaction& tx, const CAmount& nFee, CTxMemPool& pool) EXCLUSIVE_LOCKS_REQUIRED(pool.cs) +static void AddTx(const CMutableTransaction& tx, const CAmount& nFee, CTxMemPool& pool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, pool.cs) { int64_t nTime = 0; unsigned int nHeight = 1; @@ -97,7 +97,7 @@ static void MempoolEviction(benchmark::Bench& bench) tx7.vout[1].nValue = 10 * COIN; CTxMemPool pool; - LOCK(pool.cs); + LOCK2(cs_main, pool.cs); bench.run([&]() NO_THREAD_SAFETY_ANALYSIS { AddTx(tx1, 10000LL, pool); diff --git a/src/sync.h b/src/sync.h index d5798e8f5e0b..f5ecd2fc02ab 100644 --- a/src/sync.h +++ b/src/sync.h @@ -21,7 +21,7 @@ ///////////////////////////////////////////////// /* -CCriticalSection mutex; +RecursiveMutex mutex; std::recursive_mutex mutex; LOCK(mutex); @@ -113,6 +113,7 @@ class LOCKABLE AnnotatedMixin : public PARENT * Wrapped mutex: supports recursive locking, but no waiting * TODO: We should move away from using the recursive lock by default. */ +using RecursiveMutex = AnnotatedMixin; typedef AnnotatedMixin CCriticalSection; /** Wrapped mutex: supports waiting but not recursive locking */ diff --git a/src/test/blockencodings_tests.cpp b/src/test/blockencodings_tests.cpp index 8b6221bad360..067f62a72641 100644 --- a/src/test/blockencodings_tests.cpp +++ b/src/test/blockencodings_tests.cpp @@ -62,7 +62,7 @@ BOOST_AUTO_TEST_CASE(SimpleRoundTripTest) TestMemPoolEntryHelper entry; CBlock block(BuildBlockTestCase()); - LOCK(pool.cs); + LOCK2(cs_main, pool.cs); pool.addUnchecked(entry.FromTx(block.vtx[2])); BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[2]->GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 0); @@ -145,7 +145,7 @@ BOOST_AUTO_TEST_CASE(NonCoinbasePreforwardRTTest) TestMemPoolEntryHelper entry; CBlock block(BuildBlockTestCase()); - LOCK(pool.cs); + LOCK2(cs_main, pool.cs); pool.addUnchecked(entry.FromTx(block.vtx[2])); BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[2]->GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 0); @@ -215,7 +215,7 @@ BOOST_AUTO_TEST_CASE(SufficientPreforwardRTTest) TestMemPoolEntryHelper entry; CBlock block(BuildBlockTestCase()); - LOCK(pool.cs); + LOCK2(cs_main, pool.cs); pool.addUnchecked(entry.FromTx(block.vtx[1])); BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[1]->GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 0); diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp index 0438c450152c..688a736dfb82 100644 --- a/src/test/mempool_tests.cpp +++ b/src/test/mempool_tests.cpp @@ -54,7 +54,7 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest) CTxMemPool testPool; - LOCK(testPool.cs); + LOCK2(cs_main, testPool.cs); // Nothing in pool, remove should do nothing: unsigned int poolSize = testPool.size(); @@ -119,7 +119,7 @@ static void CheckSort(CTxMemPool &pool, std::vector &sortedOrder) E BOOST_AUTO_TEST_CASE(MempoolIndexingTest) { CTxMemPool pool; - LOCK(pool.cs); + LOCK2(cs_main, pool.cs); TestMemPoolEntryHelper entry; /* 3rd highest fee */ @@ -292,7 +292,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest) { CTxMemPool pool; - LOCK(pool.cs); + LOCK2(cs_main, pool.cs); TestMemPoolEntryHelper entry; /* 3rd highest fee */ @@ -421,7 +421,7 @@ BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest) BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest) { CTxMemPool pool; - LOCK(pool.cs); + LOCK2(cs_main, pool.cs); TestMemPoolEntryHelper entry; CMutableTransaction tx1 = CMutableTransaction(); @@ -594,7 +594,7 @@ BOOST_AUTO_TEST_CASE(MempoolAncestryTests) size_t ancestors, descendants; CTxMemPool pool; - LOCK(pool.cs); + LOCK2(cs_main, pool.cs); TestMemPoolEntryHelper entry; /* Base transaction */ diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 300fb7a01f7c..78d75e572fa5 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -92,7 +92,7 @@ static bool TestSequenceLocks(const CTransaction &tx, int flags) EXCLUSIVE_LOCKS // Test suite for ancestor feerate transaction selection. // Implemented as an additional function, rather than a separate test case, // to allow reusing the blockchain created in CreateNewBlock_validity. -static void TestPackageSelection(const CChainParams& chainparams, const CScript& scriptPubKey, const std::vector& txFirst) EXCLUSIVE_LOCKS_REQUIRED(::mempool.cs) +static void TestPackageSelection(const CChainParams& chainparams, const CScript& scriptPubKey, const std::vector& txFirst) EXCLUSIVE_LOCKS_REQUIRED(cs_main, ::mempool.cs) { // Disable free transactions, otherwise TX selection is non-deterministic gArgs.SoftSetArg("-blockprioritysize", "0"); diff --git a/src/test/policyestimator_tests.cpp b/src/test/policyestimator_tests.cpp index e02f23910368..95ca57639ae1 100644 --- a/src/test/policyestimator_tests.cpp +++ b/src/test/policyestimator_tests.cpp @@ -17,7 +17,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) { CBlockPolicyEstimator feeEst; CTxMemPool mpool(&feeEst); - LOCK(mpool.cs); + LOCK2(cs_main, mpool.cs); TestMemPoolEntryHelper entry; CAmount basefee(2000); CAmount deltaFee(100); diff --git a/src/txmempool.h b/src/txmempool.h index e224efe1b326..8fb1aa6f4877 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -493,7 +493,43 @@ class CTxMemPool > > indexed_transaction_set; - mutable CCriticalSection cs; + /** + * This mutex needs to be locked when accessing `mapTx` or other members + * that are guarded by it. + * + * @par Consistency guarantees + * + * By design, it is guaranteed that: + * + * 1. Locking both `cs_main` and `mempool.cs` will give a view of mempool + * that is consistent with current chain tip (`chainActive` and + * `pcoinsTip`) and is fully populated. Fully populated means that if the + * current active chain is missing transactions that were present in a + * previously active chain, all the missing transactions will have been + * re-added to the mempool and should be present if they meet size and + * consistency constraints. + * + * 2. Locking `mempool.cs` without `cs_main` will give a view of a mempool + * consistent with some chain that was active since `cs_main` was last + * locked, and that is fully populated as described above. It is ok for + * code that only needs to query or remove transactions from the mempool + * to lock just `mempool.cs` without `cs_main`. + * + * To provide these guarantees, it is necessary to lock both `cs_main` and + * `mempool.cs` whenever adding transactions to the mempool and whenever + * changing the chain tip. It's necessary to keep both mutexes locked until + * the mempool is consistent with the new chain tip and fully populated. + * + * @par Consistency bug + * + * The second guarantee above is not currently enforced, but + * https://github.com/bitcoin/bitcoin/pull/14193 will fix it. No known code + * in bitcoin currently depends on second guarantee, but it is important to + * fix for third party code that needs be able to frequently poll the + * mempool without locking `cs_main` and without encountering missing + * transactions during reorgs. + */ + mutable RecursiveMutex cs; indexed_transaction_set mapTx GUARDED_BY(cs); using txiter = indexed_transaction_set::nth_index<0>::type::const_iterator; @@ -567,8 +603,8 @@ class CTxMemPool // Note that addUnchecked is ONLY called from ATMP outside of tests // and any other callers may break wallet's in-mempool tracking (due to // lack of CValidationInterface::TransactionAddedToMempool callbacks). - void addUnchecked(const CTxMemPoolEntry& entry, bool validFeeEstimate = true) EXCLUSIVE_LOCKS_REQUIRED(cs); - void addUnchecked(const CTxMemPoolEntry& entry, setEntries& setAncestors, bool validFeeEstimate = true) EXCLUSIVE_LOCKS_REQUIRED(cs); + void addUnchecked(const CTxMemPoolEntry& entry, bool validFeeEstimate = true) EXCLUSIVE_LOCKS_REQUIRED(cs, cs_main); + void addUnchecked(const CTxMemPoolEntry& entry, setEntries& setAncestors, bool validFeeEstimate = true) EXCLUSIVE_LOCKS_REQUIRED(cs, cs_main); void addAddressIndex(const CTxMemPoolEntry &entry, const CCoinsViewCache &view); bool getAddressIndex(std::vector > &addresses, @@ -635,7 +671,7 @@ class CTxMemPool * for). Note: vHashesToUpdate should be the set of transactions from the * disconnected block that have been accepted back into the mempool. */ - void UpdateTransactionsFromBlock(const std::vector &vHashesToUpdate); + void UpdateTransactionsFromBlock(const std::vector& vHashesToUpdate) EXCLUSIVE_LOCKS_REQUIRED(cs_main); /** Try to calculate all in-mempool ancestors of entry. * (these are all calculated including the tx itself) @@ -677,7 +713,7 @@ class CTxMemPool */ void GetTransactionAncestry(const uint256& txid, size_t& ancestors, size_t& descendants) const; - unsigned long size() + unsigned long size() const { LOCK(cs); return mapTx.size(); diff --git a/src/validation.cpp b/src/validation.cpp index f4603a5977d4..d0c997ef83cd 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -201,7 +201,7 @@ class CChainState { CCoinsViewCache& view, const CChainParams& chainparams, bool fJustCheck = false) EXCLUSIVE_LOCKS_REQUIRED(cs_main); // Block disconnection on our pcoinsTip: - bool DisconnectTip(CValidationState& state, const CChainParams& chainparams, DisconnectedBlockTransactions *disconnectpool); + bool DisconnectTip(CValidationState& state, const CChainParams& chainparams, DisconnectedBlockTransactions* disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main); // Manual block validity manipulation: bool PreciousBlock(CValidationState& state, const CChainParams& params, CBlockIndex* pindex) LOCKS_EXCLUDED(cs_main); @@ -239,9 +239,17 @@ class CChainState { bool RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& inputs, const CChainParams& params) EXCLUSIVE_LOCKS_REQUIRED(cs_main); } g_chainstate; - - -CCriticalSection cs_main; +/** + * Mutex to guard access to validation specific variables, such as reading + * or changing the chainstate. + * + * This may also need to be locked when updating the transaction pool, e.g. on + * AcceptToMemoryPool. See CTxMemPool::cs comment for details. + * + * The transaction pool has a separate lock to allow reading from it and the + * chainstate at the same time. + */ +RecursiveMutex cs_main; BlockMap& mapBlockIndex = g_chainstate.mapBlockIndex; PrevBlockMap& mapPrevBlockIndex = g_chainstate.mapPrevBlockIndex; From 6e81d04ecc7184273a60dfc6b8134e3208541aef Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 16 Jan 2019 12:12:02 +0100 Subject: [PATCH 08/23] Merge #15165: contrib: Allow use of github API authentication in github-merge f1bd219a5b318e4bea361e1247a233e4f251f517 contrib: Allow use of github API authentication in github-merge (Wladimir J. van der Laan) a4c5bbfcd3a12f310b26cccc78ded32dd3f32ebb contrib: Add support for http[s] URLs in github-merge (Wladimir J. van der Laan) 059a3cffdfa596aa3adaace3f57fa86fdd3f80fc contrib: Detailed reporting for http errors in github-merge (Wladimir J. van der Laan) Pull request description: Three commits I had locally for `github-merge.py`: - *Detailed reporting for http errors in github-merge*: Print detailed error, this makes it easier to diagnose github API issues. - *Add support for http[s] URLs in github-merge*: Sometimes it can be useful to use github-merge with read-only access (say, for reviewing and testing from untrusted VMs). - *Allow use of github API authentication in github-merge*: The API request limit for unauthenticated requests is quite low. I started running into rate limiting errors. The limit for authenticated requests is much higher. This patch adds an optional configuration setting `user.ghtoken` that, when set, is used to authenticate requests to the API. Tree-SHA512: ca8ae1874a787263e49d915d7cf31c0c0f50aba229c9440265bf1fda69f7e00641d1492512b93d76c17ff1766859283d640d37770acb120898736ad97efbd5c2 --- contrib/devtools/README.md | 20 +++++++++++++++++++- contrib/devtools/github-merge.py | 19 ++++++++++++++++--- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/contrib/devtools/README.md b/contrib/devtools/README.md index 64a83045c272..9782dab0c0bf 100644 --- a/contrib/devtools/README.md +++ b/contrib/devtools/README.md @@ -122,7 +122,25 @@ Configuring the github-merge tool for the bitcoin repository is done in the foll git config githubmerge.repository dashpay/dash git config githubmerge.testcmd "make -j4 check" (adapt to whatever you want to use for testing) - git config --global user.signingkey mykeyid (if you want to GPG sign) + git config --global user.signingkey mykeyid + +Authentication (optional) +-------------------------- + +The API request limit for unauthenticated requests is quite low, but the +limit for authenticated requests is much higher. If you start running +into rate limiting errors it can be useful to set an authentication token +so that the script can authenticate requests. + +- First, go to [Personal access tokens](https://github.com/settings/tokens). +- Click 'Generate new token'. +- Fill in an arbitrary token description. No further privileges are needed. +- Click the `Generate token` button at the bottom of the form. +- Copy the generated token (should be a hexadecimal string) + +Then do: + + git config --global user.ghtoken "pasted token" Create and verify timestamps of merge commits --------------------------------------------- diff --git a/contrib/devtools/github-merge.py b/contrib/devtools/github-merge.py index 93309d4c2bdf..274d00eb4fa2 100755 --- a/contrib/devtools/github-merge.py +++ b/contrib/devtools/github-merge.py @@ -23,6 +23,7 @@ import json import codecs from urllib.request import Request, urlopen +from urllib.error import HTTPError # External tools (can be overridden using environment) GIT = os.getenv('GIT','git') @@ -46,17 +47,24 @@ def git_config_get(option, default=None): except subprocess.CalledProcessError: return default -def retrieve_pr_info(repo,pull): +def retrieve_pr_info(repo,pull,ghtoken): ''' Retrieve pull request information from github. Return None if no title can be found, or an error happens. ''' try: req = Request("https://api.github.com/repos/"+repo+"/pulls/"+pull) + if ghtoken is not None: + req.add_header('Authorization', 'token ' + ghtoken) result = urlopen(req) reader = codecs.getreader('utf-8') obj = json.load(reader(result)) return obj + except HTTPError as e: + error_message = e.read() + print('Warning: unable to retrieve pull information from github: %s' % e) + print('Detailed error: %s' % error_message) + return None except Exception as e: print('Warning: unable to retrieve pull information from github: %s' % e) return None @@ -134,6 +142,7 @@ def parse_arguments(): In addition, you can set the following git configuration variables: githubmerge.repository (mandatory), user.signingkey (mandatory), + user.ghtoken (default: none). githubmerge.host (default: git@github.com), githubmerge.branch (no default), githubmerge.testcmd (default: none). @@ -152,6 +161,7 @@ def main(): host = git_config_get('githubmerge.host','git@github.com') opt_branch = git_config_get('githubmerge.branch',None) testcmd = git_config_get('githubmerge.testcmd') + ghtoken = git_config_get('user.ghtoken') signingkey = git_config_get('user.signingkey') if repo is None: print("ERROR: No repository configured. Use this command to set:", file=stderr) @@ -162,14 +172,17 @@ def main(): print("git config --global user.signingkey ",file=stderr) sys.exit(1) - host_repo = host+":"+repo # shortcut for push/pull target + if host.startswith(('https:','http:')): + host_repo = host+"/"+repo+".git" + else: + host_repo = host+":"+repo # Extract settings from command line args = parse_arguments() pull = str(args.pull[0]) # Receive pull information from github - info = retrieve_pr_info(repo,pull) + info = retrieve_pr_info(repo,pull,ghtoken) if info is None: sys.exit(1) title = info['title'].strip() From 2153f8a74adcd1211d813bb0b0f028f4b8f549a2 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 17 Jan 2019 11:16:54 -1000 Subject: [PATCH 09/23] Merge #15040: qt: Add workaround for QProgressDialog bug on macOS 7c572c488 Add workaround for QProgressDialog bug on macOS (Hennadii Stepanov) Pull request description: Fix #15016. Refs: - [QTBUG-65750: QProgressDialog too small width at larger font size on Mac](https://bugreports.qt.io/browse/QTBUG-65750) - [QTBUG-70357: QProgressDialog is too narrow to fit the text of its label](https://bugreports.qt.io/browse/QTBUG-70357) With this PR: ![screenshot from 2018-12-26 22-01-30](https://user-images.githubusercontent.com/32963518/50456571-1aa35b80-095e-11e9-8442-c285555f2bee.png) Tree-SHA512: dde668dfa7d2144973c0e868aea7fdb7d90f78584836d024ffefb8df4a709d6842fa3601954759b4462856a80e81df15b861ea39506599230a16928b621d9f8f --- src/qt/bitcoingui.cpp | 18 +++++++----------- src/qt/guiutil.cpp | 16 +++++++++++++++- src/qt/guiutil.h | 4 ++++ src/qt/walletview.cpp | 17 ++++++----------- 4 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 091ac1288542..3836d8c37f28 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -1738,26 +1738,22 @@ void BitcoinGUI::detectShutdown() void BitcoinGUI::showProgress(const QString &title, int nProgress) { - if (nProgress == 0) - { - progressDialog = new QProgressDialog(title, "", 0, 100, this); + if (nProgress == 0) { + progressDialog = new QProgressDialog(title, QString(), 0, 100, this); + GUIUtil::PolishProgressDialog(progressDialog); progressDialog->setWindowModality(Qt::ApplicationModal); progressDialog->setMinimumDuration(0); - progressDialog->setCancelButton(nullptr); progressDialog->setAutoClose(false); progressDialog->setValue(0); - } - else if (nProgress == 100) - { - if (progressDialog) - { + } else if (nProgress == 100) { + if (progressDialog) { progressDialog->close(); progressDialog->deleteLater(); progressDialog = nullptr; } - } - else if (progressDialog) + } else if (progressDialog) { progressDialog->setValue(nProgress); + } } void BitcoinGUI::setTrayIconVisible(bool fHideTrayIcon) diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index fddbb0b5ed72..00c926a84c58 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -57,15 +57,17 @@ #include #include #include +#include #include #include +#include #include +#include #include #include // for Qt::mightBeRichText #include #include #include -#include #include #if defined(Q_OS_MAC) @@ -1928,4 +1930,16 @@ bool ItemDelegate::eventFilter(QObject *object, QEvent *event) return QItemDelegate::eventFilter(object, event); } +void PolishProgressDialog(QProgressDialog* dialog) +{ +#ifdef Q_OS_MAC + // Workaround for macOS-only Qt bug; see: QTBUG-65750, QTBUG-70357. + const int margin = dialog->fontMetrics().width("X"); + dialog->resize(dialog->width() + 2 * margin, dialog->height()); + dialog->show(); +#else + Q_UNUSED(dialog); +#endif +} + } // namespace GUIUtil diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index 93ad2d7f190b..1a95ecf677fb 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -35,6 +35,7 @@ class QButtonGroup; class QDateTime; class QFont; class QLineEdit; +class QProgressDialog; class QUrl; class QWidget; QT_END_NAMESPACE @@ -443,6 +444,9 @@ namespace GUIUtil private: bool eventFilter(QObject *object, QEvent *event) override; }; + + // Fix known bugs in QProgressDialog class. + void PolishProgressDialog(QProgressDialog* dialog); } // namespace GUIUtil #endif // BITCOIN_QT_GUIUTIL_H diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index eae1a7dd1f98..83d81405f189 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -383,25 +383,20 @@ void WalletView::usedReceivingAddresses() void WalletView::showProgress(const QString &title, int nProgress) { - if (nProgress == 0) - { - progressDialog = new QProgressDialog(title, "", 0, 100, this); + if (nProgress == 0) { + progressDialog = new QProgressDialog(title, tr("Cancel"), 0, 100, this); + GUIUtil::PolishProgressDialog(progressDialog); progressDialog->setWindowModality(Qt::ApplicationModal); progressDialog->setMinimumDuration(0); progressDialog->setAutoClose(false); progressDialog->setValue(0); - progressDialog->setCancelButtonText(tr("Cancel")); - } - else if (nProgress == 100) - { - if (progressDialog) - { + } else if (nProgress == 100) { + if (progressDialog) { progressDialog->close(); progressDialog->deleteLater(); progressDialog = nullptr; } - } - else if (progressDialog) { + } else if (progressDialog) { if (progressDialog->wasCanceled()) { getWalletModel()->wallet().abortRescan(); } else { From 30f6319fd0c0383e500965bc7f3ab9ca4af36e99 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sun, 20 Jan 2019 16:10:44 +0100 Subject: [PATCH 10/23] Merge #15194: Add comment describing fDisconnect behavior 5b4283cb81b5d3023b9868d121b22b1f387a50ca Add comment describing fDisconnect behavior (Carl Dong) Pull request description: Motivated by @Sjors here: https://github.com/bitcoin/bitcoin/pull/14605#discussion_r248384309 Tree-SHA512: 8fc52eb4d3b5651c19c49b47fad75e8fb939cf524ada647e88d8d5aad7726052d94e500c1ebdb2a41b67bc4669ee61ff151a5cff81a52c68c900da562ef21751 --- src/net.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/net.h b/src/net.h index 52b41770ac23..cb6d6d722f77 100644 --- a/src/net.h +++ b/src/net.h @@ -895,6 +895,8 @@ class CNode std::atomic_bool fDisconnect; std::atomic nDisconnectLingerTime{0}; std::atomic_bool fSocketShutdown{false}; + // Setting fDisconnect to true will cause the node to be disconnected the + // next time DisconnectNodes() runs std::atomic_bool fOtherSideDisconnected { false }; // We use fRelayTxes for two purposes - // a) it allows us to not relay tx invs before receiving the peer's version message From 2813709e908929556876216da746fec21210a68e Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 21 Jan 2019 17:39:30 +0100 Subject: [PATCH 11/23] Merge #15167: qt: Fix wallet selector size adjustment ca91661adf9fa22bf1c919d118de27bfac04e94c Fix wallet selector size adjustment (Hennadii Stepanov) Pull request description: This PR sets `QComboBox::AdjustToContents` instead of default `QComboBox::AdjustToContentsOnFirstShow` for wallet selectors. Before (in master): ![screenshot from 2019-01-14 20-47-22](https://user-images.githubusercontent.com/32963518/51133771-83d00d80-183e-11e9-812c-3a1119fa766e.png) After (with this PR): ![screenshot from 2019-01-14 20-48-43](https://user-images.githubusercontent.com/32963518/51133788-90546600-183e-11e9-8394-eb62a998b90f.png) Tree-SHA512: c23ac91905bb31aaa32f2fccc02b01f5707d8b094020fe6a75a9e099e78f9191670474920234a01c46480f67d3d311f44ff46f1f4202cd50a4a6d4d09a8342ce --- src/qt/bitcoingui.cpp | 1 + src/qt/forms/debugwindow.ui | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 3836d8c37f28..9b014da4e965 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -614,6 +614,7 @@ void BitcoinGUI::createToolBars() #ifdef ENABLE_WALLET m_wallet_selector = new QComboBox(this); + m_wallet_selector->setSizeAdjustPolicy(QComboBox::AdjustToContents); connect(m_wallet_selector, static_cast(&QComboBox::currentIndexChanged), this, &BitcoinGUI::setCurrentWalletBySelectorIndex); QVBoxLayout* walletSelectorLayout = new QVBoxLayout(this); diff --git a/src/qt/forms/debugwindow.ui b/src/qt/forms/debugwindow.ui index 3a50c9e239da..e8f275b3f588 100644 --- a/src/qt/forms/debugwindow.ui +++ b/src/qt/forms/debugwindow.ui @@ -604,6 +604,9 @@ + + QComboBox::AdjustToContents + (none) From 846473aed2f2a8834c669b5c3c73e30ad664603e Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 21 Jan 2019 20:50:32 +0100 Subject: [PATCH 12/23] Merge #15219: lint: Enable python linters via an array 948d8f4f10c31220ba4b6779cc862e2b6a0af5f6 lint: Enable python linters via an array (Ben Woosley) Pull request description: This assures consistent recording of the enabled linters. This applies the same fix as #15170 to lint-python.sh Tree-SHA512: 6d03f919e86e7c2465475c88b25dd84391282bcc11728078024daf0432a7dccddf9e4a2cdae35d6ef374971cb4e12f0fa21b58f757e25f2fe7c12ceb4f4b2c57 --- test/lint/lint-python.sh | 147 ++++++++++++++++++++------------------- 1 file changed, 75 insertions(+), 72 deletions(-) diff --git a/test/lint/lint-python.sh b/test/lint/lint-python.sh index 1748fb945359..34fe80729711 100755 --- a/test/lint/lint-python.sh +++ b/test/lint/lint-python.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/usr/bin/env bash # # Copyright (c) 2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying @@ -8,76 +8,79 @@ export LC_ALL=C -# E101 indentation contains mixed spaces and tabs -# E112 expected an indented block -# E113 unexpected indentation -# E115 expected an indented block (comment) -# E116 unexpected indentation (comment) -# E125 continuation line with same indent as next logical line -# E129 visually indented line with same indent as next logical line -# E131 continuation line unaligned for hanging indent -# E133 closing bracket is missing indentation -# E223 tab before operator -# E224 tab after operator -# E242 tab after ',' -# E266 too many leading '#' for block comment -# E271 multiple spaces after keyword -# E272 multiple spaces before keyword -# E273 tab after keyword -# E274 tab before keyword -# E275 missing whitespace after keyword -# E304 blank lines found after function decorator -# E306 expected 1 blank line before a nested definition -# E401 multiple imports on one line -# E402 module level import not at top of file -# F403 'from foo_module import *' used; unable to detect undefined names -# F405 foo_function may be undefined, or defined from star imports: bar_module -# E502 the backslash is redundant between brackets -# E701 multiple statements on one line (colon) -# E702 multiple statements on one line (semicolon) -# E703 statement ends with a semicolon -# E714 test for object identity should be "is not" -# E721 do not compare types, use "isinstance()" -# E741 do not use variables named "l", "O", or "I" # disabled -# E742 do not define classes named "l", "O", or "I" -# E743 do not define functions named "l", "O", or "I" -# E901 SyntaxError: invalid syntax -# E902 TokenError: EOF in multi-line string -# F401 module imported but unused -# F402 import module from line N shadowed by loop variable -# F404 future import(s) name after other statements -# F406 "from module import *" only allowed at module level -# F407 an undefined __future__ feature name was imported -# F601 dictionary key name repeated with different values -# F602 dictionary key variable name repeated with different values -# F621 too many expressions in an assignment with star-unpacking -# F622 two or more starred expressions in an assignment (a, *b, *c = d) -# F631 assertion test is a tuple, which are always True -# F701 a break statement outside of a while or for loop -# F702 a continue statement outside of a while or for loop -# F703 a continue statement in a finally block in a loop -# F704 a yield or yield from statement outside of a function -# F705 a return statement with arguments inside a generator -# F706 a return statement outside of a function/method -# F707 an except: block as not the last exception handler -# F811 redefinition of unused name from line N -# F812 list comprehension redefines 'foo' from line N -# F821 undefined name 'Foo' -# F822 undefined name name in __all__ -# F823 local variable name … referenced before assignment -# F831 duplicate argument name in function definition -# F841 local variable 'foo' is assigned to but never used -# W191 indentation contains tabs -# W291 trailing whitespace -# W292 no newline at end of file -# W293 blank line contains whitespace -# W504 line break after binary operator # disabled -# W601 .has_key() is deprecated, use "in" -# W602 deprecated form of raising exception -# W603 "<>" is deprecated, use "!=" -# W604 backticks are deprecated, use "repr()" -# W605 invalid escape sequence "x" # disabled -# W606 'async' and 'await' are reserved keywords starting with Python 3.7 +enabled=( + E101 # indentation contains mixed spaces and tabs + E112 # expected an indented block + E113 # unexpected indentation + E115 # expected an indented block (comment) + E116 # unexpected indentation (comment) + E125 # continuation line with same indent as next logical line + E129 # visually indented line with same indent as next logical line + E131 # continuation line unaligned for hanging indent + E133 # closing bracket is missing indentation + E223 # tab before operator + E224 # tab after operator + E242 # tab after ',' + E266 # too many leading '#' for block comment + E271 # multiple spaces after keyword + E272 # multiple spaces before keyword + E273 # tab after keyword + E274 # tab before keyword + E275 # missing whitespace after keyword + E304 # blank lines found after function decorator + E306 # expected 1 blank line before a nested definition + E401 # multiple imports on one line + E402 # module level import not at top of file + E502 # the backslash is redundant between brackets + E701 # multiple statements on one line (colon) + E702 # multiple statements on one line (semicolon) + E703 # statement ends with a semicolon + # E711 # comparison to None should be 'if cond is None:' + E714 # test for object identity should be "is not" + E721 # do not compare types, use "isinstance()" + # E741 # do not use variables named "l", "O", or "I" + E742 # do not define classes named "l", "O", or "I" + E743 # do not define functions named "l", "O", or "I" + E901 # SyntaxError: invalid syntax + E902 # TokenError: EOF in multi-line string + F401 # module imported but unused + F402 # import module from line N shadowed by loop variable + F403 # 'from foo_module import *' used; unable to detect undefined names + F404 # future import(s) name after other statements + F405 # foo_function may be undefined, or defined from star imports: bar_module + F406 # "from module import *" only allowed at module level + F407 # an undefined __future__ feature name was imported + F601 # dictionary key name repeated with different values + F602 # dictionary key variable name repeated with different values + F621 # too many expressions in an assignment with star-unpacking + F622 # two or more starred expressions in an assignment (a, *b, *c = d) + F631 # assertion test is a tuple, which are always True + F701 # a break statement outside of a while or for loop + F702 # a continue statement outside of a while or for loop + F703 # a continue statement in a finally block in a loop + F704 # a yield or yield from statement outside of a function + F705 # a return statement with arguments inside a generator + F706 # a return statement outside of a function/method + F707 # an except: block as not the last exception handler + F811 # redefinition of unused name from line N + F812 # list comprehension redefines 'foo' from line N + F821 # undefined name 'Foo' + F822 # undefined name name in __all__ + F823 # local variable name … referenced before assignment + F831 # duplicate argument name in function definition + F841 # local variable 'foo' is assigned to but never used + W191 # indentation contains tabs + W291 # trailing whitespace + W292 # no newline at end of file + W293 # blank line contains whitespace + # W504 # line break after binary operator + W601 # .has_key() is deprecated, use "in" + W602 # deprecated form of raising exception + W603 # "<>" is deprecated, use "!=" + W604 # backticks are deprecated, use "repr()" + # W605 # invalid escape sequence "x" + W606 # 'async' and 'await' are reserved keywords starting with Python 3.7 +) if ! command -v flake8 > /dev/null; then echo "Skipping Python linting since flake8 is not installed. Install by running \"pip3 install flake8\"" @@ -87,4 +90,4 @@ elif PYTHONWARNINGS="ignore" flake8 --version | grep -q "Python 2"; then exit 0 fi -PYTHONWARNINGS="ignore" git ls-files "*.py" | xargs flake8 --ignore=B,C,E,F,I,N,W --select=E101,E112,E113,E115,E116,E125,E129,E131,E133,E223,E224,E242,E266,E271,E272,E273,E274,E275,E304,E306,E401,E402,E502,E701,E702,E703,E714,E721,E742,E743,E901,E902,F401,F402,F403,F404,F405,F406,F407,F601,F602,F621,F622,F631,F701,F702,F703,F704,F705,F706,F707,F811,F812,F821,F822,F823,F831,F841,W191,W291,W292,W601,W602,W603,W604,W606 #,E741,W504,W605 +PYTHONWARNINGS="ignore" flake8 --ignore=B,C,E,F,I,N,W --select=$(IFS=","; echo "${enabled[*]}") "${@:-.}" \ No newline at end of file From 5e9fd964b74d4aeeb6c39c054cf46951f17a9035 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sun, 27 Jan 2019 16:11:07 +0100 Subject: [PATCH 13/23] Merge #15254: Trivial: fixup a few doxygen comments 70e7cee96028889ab709fa3c479225e584fcb77f Trivial: Doxygenize existing CBufferedFile and VectorReader comments (Ben Woosley) 9431e1b91598fc255234ede10c22208ad18685cd Trivial: fixup a few doxygen comments (Ben Woosley) Pull request description: These were not declared properly, so their results are not properly processed. E.g.: https://dev.visucore.com/bitcoin/doxygen/rpcdump_8cpp.html#a994c8748aaa60fbb78009ff8a0638dea https://dev.visucore.com/bitcoin/doxygen/coins_8cpp.html#aa03af24ef3570144b045f4fca7a0d603 https://dev.visucore.com/bitcoin/doxygen/wallet_2wallet_8cpp.html#a5c2a7725ff8796f03471f844ecded3d9 > A third alternative is to use a block of at least two C++ comment lines, where each line starts with an additional slash or an exclamation mark. http://www.doxygen.nl/manual/docblocks.html Tree-SHA512: c13fd48ac78f25e51b1281385747e8be4bd6e27e0a0f8704608aa5c66c16715c639f1cf27018b1bf05fc2eaed6c7b9be05a68365ffe1d88dd3f400d453b7bead --- src/coins.h | 12 ++++++------ src/net.h | 14 +++++++------- src/streams.h | 32 ++++++++++++++++---------------- src/wallet/wallet.h | 4 ++-- 4 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/coins.h b/src/coins.h index 02216469e871..f2da78f26090 100644 --- a/src/coins.h +++ b/src/coins.h @@ -309,17 +309,17 @@ class CCoinsViewCache : public CCoinsViewBacked }; //! Utility function to add all of a transaction's outputs to a cache. -// When check is false, this assumes that overwrites are only possible for coinbase transactions. -// When check is true, the underlying view may be queried to determine whether an addition is -// an overwrite. +//! When check is false, this assumes that overwrites are only possible for coinbase transactions. +//! When check is true, the underlying view may be queried to determine whether an addition is +//! an overwrite. // TODO: pass in a boolean to limit these possible overwrites to known // (pre-BIP34) cases. void AddCoins(CCoinsViewCache& cache, const CTransaction& tx, int nHeight, bool check = false); //! Utility function to find any unspent output with a given txid. -// This function can be quite expensive because in the event of a transaction -// which is not found in the cache, it can cause up to MAX_OUTPUTS_PER_BLOCK -// lookups to database, so it should be used with care. +//! This function can be quite expensive because in the event of a transaction +//! which is not found in the cache, it can cause up to MAX_OUTPUTS_PER_BLOCK +//! lookups to database, so it should be used with care. const Coin& AccessByTxid(const CCoinsViewCache& cache, const uint256& txid); #endif // BITCOIN_COINS_H diff --git a/src/net.h b/src/net.h index cb6d6d722f77..6176d818cbbb 100644 --- a/src/net.h +++ b/src/net.h @@ -438,17 +438,17 @@ friend class CNode; void SetMaxOutboundTimeframe(uint64_t timeframe); uint64_t GetMaxOutboundTimeframe(); - //!check if the outbound target is reached - // if param historicalBlockServingLimit is set true, the function will - // response true if the limit for serving historical blocks has been reached + //! check if the outbound target is reached + //! if param historicalBlockServingLimit is set true, the function will + //! response true if the limit for serving historical blocks has been reached bool OutboundTargetReached(bool historicalBlockServingLimit); - //!response the bytes left in the current max outbound cycle - // in case of no limit, it will always response 0 + //! response the bytes left in the current max outbound cycle + //! in case of no limit, it will always response 0 uint64_t GetOutboundTargetBytesLeft(); - //!response the time in second left in the current max outbound cycle - // in case of no limit, it will always response 0 + //! response the time in second left in the current max outbound cycle + //! in case of no limit, it will always response 0 uint64_t GetMaxOutboundTimeLeftInCycle(); uint64_t GetTotalBytesRecv(); diff --git a/src/streams.h b/src/streams.h index 34211df4dd30..9731fed24960 100644 --- a/src/streams.h +++ b/src/streams.h @@ -150,7 +150,7 @@ class VectorReader public: - /* + /** * @param[in] type Serialization Type * @param[in] version Serialization Version (including any flags) * @param[in] data Referenced byte vector to overwrite/append @@ -162,7 +162,7 @@ class VectorReader seek(pos); } - /* + /** * (other params same as above) * @param[in] args A list of items to deserialize starting at pos. */ @@ -732,15 +732,15 @@ class CBufferedFile const int nType; const int nVersion; - FILE *src; // source file - uint64_t nSrcPos; // how many bytes have been read from source - uint64_t nReadPos; // how many bytes have been read from this - uint64_t nReadLimit; // up to which position we're allowed to read - uint64_t nRewind; // how many bytes we guarantee to rewind - std::vector vchBuf; // the buffer + FILE *src; //!< source file + uint64_t nSrcPos; //!< how many bytes have been read from source + uint64_t nReadPos; //!< how many bytes have been read from this + uint64_t nReadLimit; //!< up to which position we're allowed to read + uint64_t nRewind; //!< how many bytes we guarantee to rewind + std::vector vchBuf; //!< the buffer protected: - // read data from the source to fill the buffer + //! read data from the source to fill the buffer bool Fill() { unsigned int pos = nSrcPos % vchBuf.size(); unsigned int readNow = vchBuf.size() - pos; @@ -786,12 +786,12 @@ class CBufferedFile } } - // check whether we're at the end of the source file + //! check whether we're at the end of the source file bool eof() const { return nReadPos == nSrcPos && feof(src); } - // read a number of bytes + //! read a number of bytes void read(char *pch, size_t nSize) { if (nSize + nReadPos > nReadLimit) throw std::ios_base::failure("Read attempted past buffer limit"); @@ -811,12 +811,12 @@ class CBufferedFile } } - // return the current reading position + //! return the current reading position uint64_t GetPos() const { return nReadPos; } - // rewind to a given reading position + //! rewind to a given reading position bool SetPos(uint64_t nPos) { size_t bufsize = vchBuf.size(); if (nPos + bufsize < nSrcPos) { @@ -845,8 +845,8 @@ class CBufferedFile return true; } - // prevent reading beyond a certain position - // no argument removes the limit + //! prevent reading beyond a certain position + //! no argument removes the limit bool SetLimit(uint64_t nPos = std::numeric_limits::max()) { if (nPos < nReadPos) return false; @@ -861,7 +861,7 @@ class CBufferedFile return (*this); } - // search for a given byte in the stream, and remain positioned on it + //! search for a given byte in the stream, and remain positioned on it void FindByte(char ch) { while (true) { if (nReadPos == nSrcPos) diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index b4a203591a68..b0f5bf6e049d 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -602,8 +602,8 @@ class CWalletKey int64_t nTimeCreated; int64_t nTimeExpires; std::string strComment; - //! todo: add something to note what created it (user, getnewaddress, change) - //! maybe should have a map property map + // todo: add something to note what created it (user, getnewaddress, change) + // maybe should have a map property map explicit CWalletKey(int64_t nExpires=0); From 86de06e86a4ec83fae00cc48cdf7d957f5e921ba Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 30 Jan 2019 16:17:58 +0100 Subject: [PATCH 14/23] Merge #15243: [doc] add notes on release notes 65bc38d1c1f666e2c2d773111921b115d4249563 [doc] add notes on release notes (John Newbery) Pull request description: Explains when and how release notes should be written. Tree-SHA512: 94085d5a30499f41e6d1821b9f157aea40b3cff61a8ba606fed1b239e794ffe6769f985f53400715d712d12aadaa8db8cfca08dd1700a1fe17df86e0e554eac2 --- doc/developer-notes.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/doc/developer-notes.md b/doc/developer-notes.md index d2b50b4a92a4..6aafcbc78c4a 100644 --- a/doc/developer-notes.md +++ b/doc/developer-notes.md @@ -931,6 +931,21 @@ Release notes should be added to a PR-specific release note file at All `release-notes*` files are merged into a single [/doc/release-notes.md](/doc/release-notes.md) file prior to the release. +Release notes +------------- + +Release notes should be written for any PR that: + +- introduces a notable new feature +- fixes a significant bug +- changes an API or configuration model +- makes any other visible change to the end-user experience. + +Release notes should be added to a PR-specific release note file at +`/doc/release-notes-.md` to avoid conflicts between multiple PRs. +All `release-notes*` files are merged into a single +[/doc/release-notes.md](/doc/release-notes.md) file prior to the release. + RPC interface guidelines -------------------------- From 9b233fbc4c3c7af4f1c8b1cf6aeaa8d5ab1ad939 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Wed, 30 Jan 2019 13:35:53 -0500 Subject: [PATCH 15/23] Merge #15279: wallet: Clarify rescanblockchain doc fa5e6ef55c wallet: Fixup rescanblockchain result doc (MarcoFalke) Pull request description: This was probably accidentally added to the wrong line when addressing the feedback here: https://github.com/bitcoin/bitcoin/pull/7061#discussion_r142199778 I already added the default values in #14877, but it could be clarified more that this really has no specific block height as default value, since the tip can change during a rescan. Tree-SHA512: 48a3c5143e2b7129ee8f396d2e77550cb393fbe45f5936aeebeb7a201d61560336a3ae47b26bb757a4dbbe217e06abfd67a5a673aef266b6c4d7a80d049a2b49 --- src/wallet/rpcwallet.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 97eb18634cfb..b63978ffb3a3 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4105,11 +4105,11 @@ static UniValue rescanblockchain(const JSONRPCRequest& request) "\nRescan the local blockchain for wallet related transactions.\n" "\nArguments:\n" "1. \"start_height\" (numeric, optional) block height where the rescan should start\n" - "2. \"stop_height\" (numeric, optional) the last block height that should be scanned\n" + "2. \"stop_height\" (numeric, optional) the last block height that should be scanned. If none is provided it will rescan up to the tip at return time of this call.\n" "\nResult:\n" "{\n" - " \"start_height\" (numeric) The block height where the rescan has started. If omitted, rescan started from the genesis block.\n" - " \"stop_height\" (numeric) The height of the last rescanned block. If omitted, rescan stopped at the chain tip.\n" + " \"start_height\" (numeric) The block height where the rescan has started.\n" + " \"stop_height\" (numeric) The height of the last rescanned block.\n" "}\n" "\nExamples:\n" + HelpExampleCli("rescanblockchain", "100000 120000") From 980b0a94694d6030f011c3ddfe75ac8848766594 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 30 Jan 2019 20:16:41 +0100 Subject: [PATCH 16/23] Merge #15163: Correct units for "-dbcache" and "-prune" 6f6514a08090b37b5e8c086015ee4881813ef867 Correct units for "-dbcache" and "-prune" (Hennadii Stepanov) Pull request description: Actually, all `dbcache`-related values in the code are measured in MiB (not in megabytes, MB) or in bytes (e.g., `nTotalCache`). See: https://github.com/bitcoin/bitcoin/blob/master/src/txdb.h https://github.com/bitcoin/bitcoin/blob/ba8c8b22272ad40fe2de465d7e745532bab48d3b/src/init.cpp#L1405-L1424 Also, "-prune" is fixed: 1. The GUI values in GB are translated to the node values in MiB correctly. 2. The maximum of the "prune" `QSpinBox` is not limited by default value of 99 (GB). Fix: #15106 Tree-SHA512: 151ec43b31b1074db8b345fedb1dcc10bde225899a5296bfc183f57e1553d13ac27db8db100226646769ad03c9fcab29d88763065a471757c6c41ac51108459d --- src/init.cpp | 12 ++++++------ src/qt/forms/optionsdialog.ui | 2 +- src/qt/guiconstants.h | 3 +++ src/qt/intro.cpp | 2 +- src/qt/optionsdialog.cpp | 9 +++++---- src/qt/optionsmodel.cpp | 7 ++++--- src/validation.h | 14 +++++++------- test/functional/feature_pruning.py | 2 +- 8 files changed, 28 insertions(+), 23 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index f5dec23c236d..ffd9ddd88546 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -468,7 +468,7 @@ void SetupServerArgs() gArgs.AddArg("-conf=", strprintf("Specify configuration file. Relative paths will be prefixed by datadir location. (default: %s)", BITCOIN_CONF_FILENAME), false, OptionsCategory::OPTIONS); gArgs.AddArg("-datadir=", "Specify data directory", false, OptionsCategory::OPTIONS); gArgs.AddArg("-dbbatchsize", strprintf("Maximum database write batch size in bytes (default: %u)", nDefaultDbBatchSize), true, OptionsCategory::OPTIONS); - gArgs.AddArg("-dbcache=", strprintf("Set database cache size in megabytes (%d to %d, default: %d)", nMinDbCache, nMaxDbCache, nDefaultDbCache), false, OptionsCategory::OPTIONS); + gArgs.AddArg("-dbcache=", strprintf("Set database cache size in MiB (%d to %d, default: %d)", nMinDbCache, nMaxDbCache, nDefaultDbCache), false, OptionsCategory::OPTIONS); gArgs.AddArg("-debuglogfile=", strprintf("Specify location of debug log file. Relative paths will be prefixed by a net-specific datadir location. (-nodebuglogfile to disable; default: %s)", DEFAULT_DEBUGLOGFILE), false, OptionsCategory::OPTIONS); gArgs.AddArg("-includeconf=", "Specify additional configuration file, relative to the -datadir path (only useable from configuration file, not command line)", false, OptionsCategory::OPTIONS); gArgs.AddArg("-loadblock=", "Imports blocks from external blk000??.dat file on startup", false, OptionsCategory::OPTIONS); @@ -1388,7 +1388,7 @@ bool AppInitParameterInteraction() return InitError(strprintf(_("Prune configured below the minimum of %d MiB. Please use a higher number."), MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024)); } } - LogPrintf("Prune configured to target %uMiB on disk for block and undo files.\n", nPruneTarget / 1024 / 1024); + LogPrintf("Prune configured to target %u MiB on disk for block and undo files.\n", nPruneTarget / 1024 / 1024); fPruneMode = true; } @@ -2038,16 +2038,16 @@ bool AppInitMain() int64_t nMempoolSizeMax = gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000; int64_t nEvoDbCache = 1024 * 1024 * 16; // TODO LogPrintf("Cache configuration:\n"); - LogPrintf("* Using %.1fMiB for block index database\n", nBlockTreeDBCache * (1.0 / 1024 / 1024)); + LogPrintf("* Using %.1f MiB for block index database\n", nBlockTreeDBCache * (1.0 / 1024 / 1024)); if (gArgs.GetBoolArg("-txindex", DEFAULT_TXINDEX)) { - LogPrintf("* Using %.1fMiB for transaction index database\n", nTxIndexCache * (1.0 / 1024 / 1024)); + LogPrintf("* Using %.1f MiB for transaction index database\n", nTxIndexCache * (1.0 / 1024 / 1024)); } for (BlockFilterType filter_type : g_enabled_filter_types) { LogPrintf("* Using %.1f MiB for %s block filter index database\n", filter_index_cache * (1.0 / 1024 / 1024), BlockFilterTypeName(filter_type)); } - LogPrintf("* Using %.1fMiB for chain state database\n", nCoinDBCache * (1.0 / 1024 / 1024)); - LogPrintf("* Using %.1fMiB for in-memory UTXO set (plus up to %.1fMiB of unused mempool space)\n", nCoinCacheUsage * (1.0 / 1024 / 1024), nMempoolSizeMax * (1.0 / 1024 / 1024)); + LogPrintf("* Using %.1f MiB for chain state database\n", nCoinDBCache * (1.0 / 1024 / 1024)); + LogPrintf("* Using %.1f MiB for in-memory UTXO set (plus up to %.1f MiB of unused mempool space)\n", nCoinCacheUsage * (1.0 / 1024 / 1024), nMempoolSizeMax * (1.0 / 1024 / 1024)); bool fLoaded = false; diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui index 896aa3131250..c797bdf4bf5d 100644 --- a/src/qt/forms/optionsdialog.ui +++ b/src/qt/forms/optionsdialog.ui @@ -230,7 +230,7 @@ - MB + MiB Qt::PlainText diff --git a/src/qt/guiconstants.h b/src/qt/guiconstants.h index 1c46508127d6..b2ca24ae8d39 100644 --- a/src/qt/guiconstants.h +++ b/src/qt/guiconstants.h @@ -48,4 +48,7 @@ static const int MAX_URI_LENGTH = 255; #define QAPP_APP_NAME_DEVNET "Dash-Qt-%s" #define QAPP_APP_NAME_REGTEST "Dash-Qt-regtest" +/* One gigabyte (GB) in bytes */ +static constexpr uint64_t GB_BYTES{1000000000}; + #endif // BITCOIN_QT_GUICONSTANTS_H diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index f2eca1c4158f..981e00bf5c8e 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -22,7 +23,6 @@ #include -static const uint64_t GB_BYTES = 1000000000LL; /* Total required space (in GB) depending on user choice (prune, not prune) */ static uint64_t requiredSpace; diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 2708f8e52443..9e4387a73da7 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -56,10 +57,6 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) : /* Main elements init */ ui->databaseCache->setMinimum(nMinDbCache); ui->databaseCache->setMaximum(nMaxDbCache); - static const uint64_t GiB = 1024 * 1024 * 1024; - static const uint64_t nMinDiskSpace = MIN_DISK_SPACE_FOR_BLOCK_FILES / GiB + - (MIN_DISK_SPACE_FOR_BLOCK_FILES % GiB) ? 1 : 0; - ui->pruneSize->setMinimum(nMinDiskSpace); ui->threadsScriptVerif->setMinimum(-GetNumCores()); ui->threadsScriptVerif->setMaximum(MAX_SCRIPTCHECK_THREADS); ui->pruneWarning->setVisible(false); @@ -226,6 +223,10 @@ void OptionsDialog::setModel(OptionsModel *_model) appearance->setModel(_model); updateDefaultProxyNets(); + + // Prune values are in GB to be consistent with intro.cpp + static constexpr uint64_t nMinDiskSpace = (MIN_DISK_SPACE_FOR_BLOCK_FILES / GB_BYTES) + (MIN_DISK_SPACE_FOR_BLOCK_FILES % GB_BYTES) ? 1 : 0; + ui->pruneSize->setRange(nMinDiskSpace, _model->node().getAssumedBlockchainSize()); } /* warn when one of the following settings changes by user action (placed here so init via mapper doesn't trigger them) */ diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index 143ac52de180..88c65cdf5a0c 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -179,9 +180,9 @@ void OptionsModel::Init(bool resetSettings) settings.setValue("bPrune", false); if (!settings.contains("nPruneSize")) settings.setValue("nPruneSize", 2); - // Convert prune size to MB: - const uint64_t nPruneSizeMB = settings.value("nPruneSize").toInt() * 1000; - if (!m_node.softSetArg("-prune", settings.value("bPrune").toBool() ? std::to_string(nPruneSizeMB) : "0")) { + // Convert prune size from GB to MiB: + const uint64_t nPruneSizeMiB = (settings.value("nPruneSize").toInt() * GB_BYTES) >> 20; + if (!m_node.softSetArg("-prune", settings.value("bPrune").toBool() ? std::to_string(nPruneSizeMiB) : "0")) { addOverriddenOption("-prune"); } diff --git a/src/validation.h b/src/validation.h index 3240266d6680..fa43ac1eab86 100644 --- a/src/validation.h +++ b/src/validation.h @@ -102,14 +102,14 @@ static const unsigned int MIN_BLOCKS_TO_KEEP = 288; static const signed int DEFAULT_CHECKBLOCKS = 6; static const unsigned int DEFAULT_CHECKLEVEL = 3; -// Require that user allocate at least 945MB for block & undo files (blk???.dat and rev???.dat) -// At 2MB per block, 288 blocks = 576MB. -// Add 15% for Undo data = 662MB -// Add 20% for Orphan block rate = 794MB -// We want the low water mark after pruning to be at least 794 MB and since we prune in +// Require that user allocate at least 945 MiB for block & undo files (blk???.dat and rev???.dat) +// At 2B MiB per block, 288 blocks = 576 MiB. +// Add 15% for Undo data = 662 MiB +// Add 20% for Orphan block rate = 794 MiB +// We want the low water mark after pruning to be at least 794 MiB and since we prune in // full block file chunks, we need the high water mark which triggers the prune to be -// one 128MB block file + added 15% undo data = 147MB greater for a total of 941MB -// Setting the target to > than 945MB will make it likely we can respect the target. +// one 128 MiB block file + added 15% undo data = 147 MiB greater for a total of 941 MiB +// Setting the target to > than 945 MiB will make it likely we can respect the target. static const uint64_t MIN_DISK_SPACE_FOR_BLOCK_FILES = 945 * 1024 * 1024; struct BlockHasher diff --git a/test/functional/feature_pruning.py b/test/functional/feature_pruning.py index 7fee86816ae2..9a10dcfa6f1d 100755 --- a/test/functional/feature_pruning.py +++ b/test/functional/feature_pruning.py @@ -315,7 +315,7 @@ def has_block(index): if has_block(3): raise AssertionError("blk00003.dat is still there, should be pruned by now") - # stop node, start back up with auto-prune at 550MB, make sure still runs + # stop node, start back up with auto-prune at 550 MiB, make sure still runs self.stop_node(node_number) self.start_node(node_number, extra_args=["-dip3params=2000:2000", "-dip8params=2000", "-disablegovernance", "-txindex=0", "-prune=550"]) From c2c6e65c5e457b8559397245df72b1c2d4d2ba3d Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Wed, 30 Jan 2019 15:11:50 -0500 Subject: [PATCH 17/23] Merge #15276: travis: Compile once on trusty fa5ce3f10e travis: Compile trusty with depends for now (MarcoFalke) fa83999d92 travis: Compile once on trusty (MarcoFalke) Pull request description: To avoid accidentally regressing again on #15172, we should compile at least once with gcc4.8 (the minimum required version) Note that this uses the trusty image, which will be removed in a few months from the docker hub, so in the future it had to be switched to the centos7 (or similar) image, which should come with gcc4.8 as well. Tree-SHA512: 9d1704464bde8dbaf3319ac35f72d32dce549818730d3b2fb63df817f84a88dd64aa3419b97a57c1120ffb254784503b7d2675b1291d4ed073cd2a2488aa717d --- .travis.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.travis.yml b/.travis.yml index 87ede99f6c04..3133864082f7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -256,6 +256,16 @@ after_success: DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1 ALLOW_HOST_PACKAGES=1" GOAL="install" BITCOIN_CONFIG="--enable-zmq --with-gui=qt5 --enable-glibc-back-compat --enable-reduce-exports --enable-debug CXXFLAGS=\"-g0 -O2\"" + - stage: test + name: 'x86_64 Linux [GOAL: install] [trusty] [depends for now]' + env: >- + HOST=x86_64-unknown-linux-gnu + DOCKER_NAME_TAG=ubuntu:14.04 + PACKAGES="python3-zmq qtbase5-dev qttools5-dev-tools libicu-dev libpng-dev libssl-dev libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-test-dev libboost-thread-dev libdb5.1++-dev libminiupnpc-dev libzmq3-dev libprotobuf-dev protobuf-compiler libqrencode-dev" + RUN_FUNCTIONAL_TESTS=false + GOAL="install" + BITCOIN_CONFIG="--enable-zmq --with-incompatible-bdb --with-gui=no" + - stage: test name: 'x86_64 Linux [GOAL: install] [xenial] [no depends, only system libs, sanitizers: thread (TSan), no wallet]' env: >- From baa76aa3318a038f1d80f6e92f94667f90ad5c10 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 31 Jan 2019 15:03:37 +0100 Subject: [PATCH 18/23] Merge #15225: GUI: Change the receive button to respond to keypool state changing 2bc4c3eaf96f5f8490fc79280422916c5d14cde3 Notify the GUI that the keypool has changed to set the receive button (Andrew Chow) 14bcdbe09cffaef9bcc51dd9de1645db3f0a93db Check for more than private keys disabled to show receive button (Andrew Chow) Pull request description: Currently the Receive button in the GUI is displayed enabled or disabled by the initial state of the wallet when the wallet is first loaded. The button is only enabled or disabled depending on whether the disable private keys flag is set when the wallet is loaded. However, future changes to the wallet means that this initial state and check may no longer be accurate. #14938 introduces empty wallets which do not have private keys. An empty wallet that is loaded should have the Receive button disabled, and then it should become enabled once `sethdseed` is used so that a keypool can be generated and new keys generated. Likewise, with #14075, a wallet can be loaded with no keypool initially, so the button should be disabled. Later, public keys can be imported into the keypool, at which time the button should become enabled. When the keypool runs out again (no new keys are generated as the keypool only consists of imports), the button should become disabled. This PR makes it so that the button becomes enabled and disabled as the keypool state changes. The check for whether to enable or disable the receive button has changed to checking whether it is possible to get new keys. It now checks for whether the wallet has an HD seed and, if not, whether the private keys are disabled. When an action happens which would make it possible for a new address to be retrieved or make it possible for a no more addresses to be retrieved, a signal is emitted which has the GUI recheck the conditions for the Receive button. These actions are setting a new HD seed, topping up the keypool, retrieving a key from the keypool, and returning a key to the keypool. Tree-SHA512: eff15a5337f4c64ecd7169414fb47053c04f6a0f0130341b6dd9799ac4d79f451e25284701c668971fca33f0909d5352a474a2c12349375bedfdb59b63077d50 --- src/interfaces/wallet.cpp | 4 ++++ src/interfaces/wallet.h | 4 ++++ src/qt/receivecoinsdialog.cpp | 9 +++++++-- src/qt/walletmodel.cpp | 17 +++++++++++++++++ src/qt/walletmodel.h | 5 +++++ src/wallet/wallet.cpp | 3 +++ src/wallet/wallet.h | 3 +++ 7 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/interfaces/wallet.cpp b/src/interfaces/wallet.cpp index 83d1e9d73d58..2cdab7c37cdc 100644 --- a/src/interfaces/wallet.cpp +++ b/src/interfaces/wallet.cpp @@ -541,6 +541,10 @@ class WalletImpl : public Wallet { return MakeHandler(m_wallet.NotifyWatchonlyChanged.connect(fn)); } + std::unique_ptr handleCanGetAddressesChanged(CanGetAddressesChangedFn fn) override + { + return MakeHandler(m_wallet.NotifyCanGetAddressesChanged.connect(fn)); + } std::shared_ptr m_shared_wallet; CWallet& m_wallet; diff --git a/src/interfaces/wallet.h b/src/interfaces/wallet.h index 3bad1da4b496..110dcc616849 100644 --- a/src/interfaces/wallet.h +++ b/src/interfaces/wallet.h @@ -300,6 +300,10 @@ class Wallet //! Register handler for watchonly changed messages. using WatchOnlyChangedFn = std::function; virtual std::unique_ptr handleWatchOnlyChanged(WatchOnlyChangedFn fn) = 0; + + //! Register handler for keypool changed messages. + using CanGetAddressesChangedFn = std::function; + virtual std::unique_ptr handleCanGetAddressesChanged(CanGetAddressesChangedFn fn) = 0; }; //! Tracking object returned by CreateTransaction and passed to CommitTransaction. diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index 755181455b35..c4c7e85d5622 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -87,8 +87,13 @@ void ReceiveCoinsDialog::setModel(WalletModel *_model) // Last 2 columns are set by the columnResizingFixer, when the table geometry is ready. columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(tableView, AMOUNT_MINIMUM_COLUMN_WIDTH, DATE_COLUMN_WIDTH, this); - // eventually disable the main receive button if private key operations are disabled - ui->receiveButton->setEnabled(!model->privateKeysDisabled()); + // Set the button to be enabled or disabled based on whether the wallet can give out new addresses. + ui->receiveButton->setEnabled(model->canGetAddresses()); + + // Enable/disable the receive button if the wallet is now able/unable to give out new addresses. + connect(model, &WalletModel::canGetAddressesChanged, [this] { + ui->receiveButton->setEnabled(model->canGetAddresses()); + }); } } diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index b23137415366..636596cf0be8 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -487,6 +487,11 @@ static void NotifyWatchonlyChanged(WalletModel *walletmodel, bool fHaveWatchonly Q_ARG(bool, fHaveWatchonly)); } +static void NotifyCanGetAddressesChanged(WalletModel* walletmodel) +{ + QMetaObject::invokeMethod(walletmodel, "canGetAddressesChanged"); +} + void WalletModel::subscribeToCoreSignals() { // Connect signals to wallet @@ -498,6 +503,7 @@ void WalletModel::subscribeToCoreSignals() m_handler_chainlock_received = m_wallet->handleChainLockReceived(std::bind(NotifyChainLockReceived, this, std::placeholders::_1)); m_handler_show_progress = m_wallet->handleShowProgress(std::bind(ShowProgress, this, std::placeholders::_1, std::placeholders::_2)); m_handler_watch_only_changed = m_wallet->handleWatchOnlyChanged(std::bind(NotifyWatchonlyChanged, this, std::placeholders::_1)); + m_handler_can_get_addrs_changed = m_wallet->handleCanGetAddressesChanged(boost::bind(NotifyCanGetAddressesChanged, this)); } void WalletModel::unsubscribeFromCoreSignals() @@ -511,6 +517,7 @@ void WalletModel::unsubscribeFromCoreSignals() m_handler_chainlock_received->disconnect(); m_handler_show_progress->disconnect(); m_handler_watch_only_changed->disconnect(); + m_handler_can_get_addrs_changed->disconnect(); } // WalletModel::UnlockContext implementation @@ -597,6 +604,16 @@ bool WalletModel::privateKeysDisabled() const return m_wallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS); } +bool WalletModel::canGetAddresses() const +{ + // The wallet can provide a fresh address if: + // * hdEnabled(): an HD seed is present; or + // * it is a legacy wallet, because: + // * !hdEnabled(): an HD seed is not present; and + // * !IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS): private keys have not been disabled (which results in hdEnabled() == true) + return m_wallet->hdEnabled() || (!m_wallet->hdEnabled() && !m_wallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)); +} + QString WalletModel::getWalletName() const { return QString::fromStdString(m_wallet->getWalletName()); diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index 87305e242b96..ab1460b6110a 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -196,6 +196,7 @@ class WalletModel : public QObject static bool isWalletEnabled(); bool privateKeysDisabled() const; + bool canGetAddresses() const; int getNumBlocks() const; int getNumISLocks() const; @@ -223,6 +224,7 @@ class WalletModel : public QObject std::unique_ptr m_handler_chainlock_received; std::unique_ptr m_handler_show_progress; std::unique_ptr m_handler_watch_only_changed; + std::unique_ptr m_handler_can_get_addrs_changed; interfaces::Node& m_node; bool fHaveWatchOnly; @@ -276,6 +278,9 @@ class WalletModel : public QObject // Signal that wallet is about to be removed void unload(); + // Notify that there are now keys in the keypool + void canGetAddressesChanged(); + public Q_SLOTS: /* Wallet status might have changed */ void updateStatus(); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index a36e8faa1275..a4ac6784e91c 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4345,6 +4345,7 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize) uiInterface.InitMessage(strMsg); } } + NotifyCanGetAddressesChanged(); return true; } @@ -4386,6 +4387,7 @@ bool CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool fRe m_pool_key_to_index.erase(keypool.vchPubKey.GetID()); WalletLogPrintf("keypool reserve %d\n", nIndex); } + NotifyCanGetAddressesChanged(); return true; } @@ -4414,6 +4416,7 @@ void CWallet::ReturnKey(int64_t nIndex, bool fInternal, const CPubKey& pubkey) setExternalKeyPool.insert(nIndex); } m_pool_key_to_index[pubkey.GetID()] = nIndex; + NotifyCanGetAddressesChanged(); } WalletLogPrintf("keypool return %d\n", nIndex); } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index b0f5bf6e049d..ba9bb6e21e68 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1235,6 +1235,9 @@ class CWallet final : public CCryptoKeyStore, public CValidationInterface /** Watch-only address added */ boost::signals2::signal NotifyWatchonlyChanged; + /** Keypool has new keys */ + boost::signals2::signal NotifyCanGetAddressesChanged; + /** IS-lock received */ boost::signals2::signal NotifyISLockReceived; From 9436caf89a2a977487f801ad976d68f550669f95 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Fri, 4 Jan 2019 12:30:36 +0100 Subject: [PATCH 19/23] Merge #12151: rpc: Remove cs_main lock from blockToJSON and blockheaderToJSON MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit b9f226b41f rpc: Remove cs_main lock from blockToJSON and blockHeaderToJSON (João Barbosa) 343b98cbcd rpc: Specify chain tip instead of chain in GetDifficulty (João Barbosa) 54dc13b6a2 rpc: Fix SoftForkMajorityDesc and SoftForkDesc signatures (João Barbosa) Pull request description: Motivated by https://github.com/bitcoin/bitcoin/pull/11913#discussion_r157798157, this pull makes `blockToJSON` and `blockheaderToJSON` free of `cs_main` locks. Locking `cs_main` was required to access `chainActive` in order to check if the block was in the chain and to retrieve the next block index. With the this approach, `CBlockIndex::GetAncestor()` is used in a way to check if the block belongs to the specified chain tip and, at the same time, get the next block index. Tree-SHA512: a6720ace0182c19033bbed1a404f729d793574db8ab16e0966ffe412145611e32c30aaab02975d225df6d439d7b9ef2070e732b16137a902b0293c8cddfeb85f --- src/rest.cpp | 17 +++++----- src/rpc/blockchain.cpp | 59 +++++++++++++++++------------------ src/rpc/blockchain.h | 4 +-- src/test/blockchain_tests.cpp | 7 ----- 4 files changed, 38 insertions(+), 49 deletions(-) diff --git a/src/rest.cpp b/src/rest.cpp index 6ad5ffe1c83d..579c9f31aceb 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -131,10 +131,12 @@ static bool rest_headers(HTTPRequest* req, if (!ParseHashStr(hashStr, hash)) return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); + const CBlockIndex* tip = nullptr; std::vector headers; headers.reserve(count); { LOCK(cs_main); + tip = chainActive.Tip(); const CBlockIndex* pindex = LookupBlockIndex(hash); while (pindex != nullptr && chainActive.Contains(pindex)) { headers.push_back(pindex); @@ -170,11 +172,8 @@ static bool rest_headers(HTTPRequest* req, } case RetFormat::JSON: { UniValue jsonHeaders(UniValue::VARR); - { - LOCK(cs_main); - for (const CBlockIndex *pindex : headers) { - jsonHeaders.push_back(blockheaderToJSON(pindex)); - } + for (const CBlockIndex *pindex : headers) { + jsonHeaders.push_back(blockheaderToJSON(tip, pindex)); } std::string strJSON = jsonHeaders.write() + "\n"; req->WriteHeader("Content-Type", "application/json"); @@ -202,8 +201,10 @@ static bool rest_block(HTTPRequest* req, CBlock block; CBlockIndex* pblockindex = nullptr; + CBlockIndex* tip = nullptr; { LOCK(cs_main); + tip = chainActive.Tip(); pblockindex = LookupBlockIndex(hash); if (!pblockindex) { return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); @@ -236,11 +237,7 @@ static bool rest_block(HTTPRequest* req, } case RetFormat::JSON: { - UniValue objBlock; - { - LOCK(cs_main); - objBlock = blockToJSON(block, pblockindex, showTxDetails); - } + UniValue objBlock = blockToJSON(block, tip, pblockindex, showTxDetails); std::string strJSON = objBlock.write() + "\n"; req->WriteHeader("Content-Type", "application/json"); req->WriteReply(HTTP_OK, strJSON); diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 8b188d329ed7..eb4d79479d85 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -71,10 +71,7 @@ extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& */ double GetDifficulty(const CBlockIndex* blockindex) { - if (blockindex == nullptr) - { - return 1.0; - } + assert(blockindex); int nShift = (blockindex->nBits >> 24) & 0xff; double dDiff = @@ -94,15 +91,22 @@ double GetDifficulty(const CBlockIndex* blockindex) return dDiff; } -UniValue blockheaderToJSON(const CBlockIndex* blockindex) +static int ComputeNextBlockAndDepth(const CBlockIndex* tip, const CBlockIndex* blockindex, const CBlockIndex*& next) +{ + next = tip->GetAncestor(blockindex->nHeight + 1); + if (next && next->pprev == blockindex) { + return tip->nHeight - blockindex->nHeight + 1; + } + next = nullptr; + return blockindex == tip ? 1 : -1; +} + +UniValue blockheaderToJSON(const CBlockIndex* tip, const CBlockIndex* blockindex) { - AssertLockHeld(cs_main); UniValue result(UniValue::VOBJ); result.pushKV("hash", blockindex->GetBlockHash().GetHex()); - int confirmations = -1; - // Only report confirmations if the block is on the main chain - if (chainActive.Contains(blockindex)) - confirmations = chainActive.Height() - blockindex->nHeight + 1; + const CBlockIndex* pnext; + int confirmations = ComputeNextBlockAndDepth(tip, blockindex, pnext); result.pushKV("confirmations", confirmations); result.pushKV("height", blockindex->nHeight); result.pushKV("version", blockindex->nVersion); @@ -118,7 +122,6 @@ UniValue blockheaderToJSON(const CBlockIndex* blockindex) if (blockindex->pprev) result.pushKV("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()); - CBlockIndex *pnext = chainActive.Next(blockindex); if (pnext) result.pushKV("nextblockhash", pnext->GetBlockHash().GetHex()); @@ -127,15 +130,12 @@ UniValue blockheaderToJSON(const CBlockIndex* blockindex) return result; } -UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails) +UniValue blockToJSON(const CBlock& block, const CBlockIndex* tip, const CBlockIndex* blockindex, bool txDetails) { - AssertLockHeld(cs_main); UniValue result(UniValue::VOBJ); result.pushKV("hash", blockindex->GetBlockHash().GetHex()); - int confirmations = -1; - // Only report confirmations if the block is on the main chain - if (chainActive.Contains(blockindex)) - confirmations = chainActive.Height() - blockindex->nHeight + 1; + const CBlockIndex* pnext; + int confirmations = ComputeNextBlockAndDepth(tip, blockindex, pnext); result.pushKV("confirmations", confirmations); result.pushKV("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)); result.pushKV("height", blockindex->nHeight); @@ -177,7 +177,6 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx if (blockindex->pprev) result.pushKV("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()); - CBlockIndex *pnext = chainActive.Next(blockindex); if (pnext) result.pushKV("nextblockhash", pnext->GetBlockHash().GetHex()); @@ -836,7 +835,7 @@ static UniValue getblockheader(const JSONRPCRequest& request) return strHex; } - return blockheaderToJSON(pblockindex); + return blockheaderToJSON(chainActive.Tip(), pblockindex); } static UniValue getblockheaders(const JSONRPCRequest& request) @@ -920,7 +919,7 @@ static UniValue getblockheaders(const JSONRPCRequest& request) for (; pblockindex; pblockindex = chainActive.Next(pblockindex)) { - arrHeaders.push_back(blockheaderToJSON(pblockindex)); + arrHeaders.push_back(blockheaderToJSON(chainActive.Tip(), pblockindex)); if (--nCount <= 0) break; } @@ -1107,7 +1106,7 @@ static UniValue getblock(const JSONRPCRequest& request) return strHex; } - return blockToJSON(block, pblockindex, verbosity >= 2); + return blockToJSON(block, chainActive.Tip(), pblockindex, verbosity >= 2); } static UniValue pruneblockchain(const JSONRPCRequest& request) @@ -1309,7 +1308,7 @@ static UniValue verifychain(const JSONRPCRequest& request) } /** Implementation of IsSuperMajority with better feedback */ -static UniValue SoftForkMajorityDesc(int version, CBlockIndex* pindex, const Consensus::Params& consensusParams) +static UniValue SoftForkMajorityDesc(int version, const CBlockIndex* pindex, const Consensus::Params& consensusParams) { UniValue rv(UniValue::VOBJ); bool activated = false; @@ -1329,7 +1328,7 @@ static UniValue SoftForkMajorityDesc(int version, CBlockIndex* pindex, const Con return rv; } -static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, const Consensus::Params& consensusParams) +static UniValue SoftForkDesc(const std::string &name, int version, const CBlockIndex* pindex, const Consensus::Params& consensusParams) { UniValue rv(UniValue::VOBJ); rv.pushKV("id", name); @@ -1438,20 +1437,21 @@ UniValue getblockchaininfo(const JSONRPCRequest& request) std::string strChainName = gArgs.IsArgSet("-devnet") ? gArgs.GetDevNetName() : Params().NetworkIDString(); + const CBlockIndex* tip = chainActive.Tip(); UniValue obj(UniValue::VOBJ); obj.pushKV("chain", strChainName); obj.pushKV("blocks", (int)chainActive.Height()); obj.pushKV("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1); - obj.pushKV("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex()); - obj.pushKV("difficulty", (double)GetDifficulty(chainActive.Tip())); - obj.pushKV("mediantime", (int64_t)chainActive.Tip()->GetMedianTimePast()); - obj.pushKV("verificationprogress", GuessVerificationProgress(Params().TxData(), chainActive.Tip())); + obj.pushKV("bestblockhash", tip->GetBlockHash().GetHex()); + obj.pushKV("difficulty", (double)GetDifficulty(tip)); + obj.pushKV("mediantime", (int64_t)tip->GetMedianTimePast()); + obj.pushKV("verificationprogress", GuessVerificationProgress(Params().TxData(), tip)); obj.pushKV("initialblockdownload", IsInitialBlockDownload()); - obj.pushKV("chainwork", chainActive.Tip()->nChainWork.GetHex()); + obj.pushKV("chainwork", tip->nChainWork.GetHex()); obj.pushKV("size_on_disk", CalculateCurrentUsage()); obj.pushKV("pruned", fPruneMode); if (fPruneMode) { - CBlockIndex* block = chainActive.Tip(); + const CBlockIndex* block = tip; assert(block); while (block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA)) { block = block->pprev; @@ -1468,7 +1468,6 @@ UniValue getblockchaininfo(const JSONRPCRequest& request) } const Consensus::Params& consensusParams = Params().GetConsensus(); - CBlockIndex* tip = chainActive.Tip(); UniValue softforks(UniValue::VARR); UniValue bip9_softforks(UniValue::VOBJ); // sorted by activation block diff --git a/src/rpc/blockchain.h b/src/rpc/blockchain.h index 8703bcaf612b..275fde32c5b4 100644 --- a/src/rpc/blockchain.h +++ b/src/rpc/blockchain.h @@ -27,7 +27,7 @@ double GetDifficulty(const CBlockIndex* blockindex); void RPCNotifyBlockChange(bool ibd, const CBlockIndex *); /** Block description to JSON */ -UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false); +UniValue blockToJSON(const CBlock& block, const CBlockIndex* tip, const CBlockIndex* blockindex, bool txDetails = false); /** Mempool information to JSON */ UniValue mempoolInfoToJSON(); @@ -36,7 +36,7 @@ UniValue mempoolInfoToJSON(); UniValue mempoolToJSON(bool fVerbose = false); /** Block header to JSON */ -UniValue blockheaderToJSON(const CBlockIndex* blockindex); +UniValue blockheaderToJSON(const CBlockIndex* tip, const CBlockIndex* blockindex); /** Used by getblockstats to get feerates at different percentiles by weight */ void CalculatePercentilesBySize(CAmount result[NUM_GETBLOCKSTATS_PERCENTILES], std::vector>& scores, int64_t total_size); diff --git a/src/test/blockchain_tests.cpp b/src/test/blockchain_tests.cpp index 05129b9e47e7..4a17410c1cd2 100644 --- a/src/test/blockchain_tests.cpp +++ b/src/test/blockchain_tests.cpp @@ -68,11 +68,4 @@ BOOST_AUTO_TEST_CASE(get_difficulty_for_very_high_target) TestDifficulty(0x12345678, 5913134931067755359633408.0); } -// Verify that difficulty is 1.0 for an empty chain. -BOOST_AUTO_TEST_CASE(get_difficulty_for_null_tip) -{ - double difficulty = GetDifficulty(nullptr); - RejectDifficultyMismatch(difficulty, 1.0); -} - BOOST_AUTO_TEST_SUITE_END() From c7aa119a82d5a8dcd659389a8c674babe4879cdb Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Tue, 24 Aug 2021 22:21:39 +0300 Subject: [PATCH 20/23] Fix 12153 --- src/rpc/blockchain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index eb4d79479d85..a7d32415e027 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -835,7 +835,7 @@ static UniValue getblockheader(const JSONRPCRequest& request) return strHex; } - return blockheaderToJSON(chainActive.Tip(), pblockindex); + return blockheaderToJSON(tip, pblockindex); } static UniValue getblockheaders(const JSONRPCRequest& request) From d1440209dd44378ab0d3e7737f6ccf573ce4f782 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Tue, 24 Aug 2021 22:27:12 +0300 Subject: [PATCH 21/23] Fix 15219 --- test/lint/lint-python.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/lint/lint-python.sh b/test/lint/lint-python.sh index 34fe80729711..deded534e0ce 100755 --- a/test/lint/lint-python.sh +++ b/test/lint/lint-python.sh @@ -90,4 +90,4 @@ elif PYTHONWARNINGS="ignore" flake8 --version | grep -q "Python 2"; then exit 0 fi -PYTHONWARNINGS="ignore" flake8 --ignore=B,C,E,F,I,N,W --select=$(IFS=","; echo "${enabled[*]}") "${@:-.}" \ No newline at end of file +PYTHONWARNINGS="ignore" git ls-files "*.py" | xargs flake8 --ignore=B,C,E,F,I,N,W --select=$(IFS=","; echo "${enabled[*]}") From ee02db8076dbebbcd94fa2df974e6810f3fd26d7 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Tue, 24 Aug 2021 22:27:12 +0300 Subject: [PATCH 22/23] 15020 new lines --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 3133864082f7..bef0672042d8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -222,6 +222,7 @@ after_success: RUN_FUNCTIONAL_TESTS=false GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" + - stage: test name: 'Win32 [GOAL: deploy] [no gui tests]' env: >- @@ -256,6 +257,7 @@ after_success: DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1 ALLOW_HOST_PACKAGES=1" GOAL="install" BITCOIN_CONFIG="--enable-zmq --with-gui=qt5 --enable-glibc-back-compat --enable-reduce-exports --enable-debug CXXFLAGS=\"-g0 -O2\"" + - stage: test name: 'x86_64 Linux [GOAL: install] [trusty] [depends for now]' env: >- @@ -276,6 +278,7 @@ after_success: RUN_FUNCTIONAL_TESTS=false # Disabled for now. TODO identify suppressions or exclude specific tests GOAL="install" BITCOIN_CONFIG="--enable-zmq --with-incompatible-bdb --with-gui=qt5 CPPFLAGS=-DDEBUG_LOCKORDER --with-sanitizers=thread --disable-hardening --disable-asm CC=clang CXX=clang++" + - stage: test name: 'x86_64 Linux [GOAL: install] [bionic] [no depends, only system libs, sanitizers: address/leak (ASan + LSan) + undefined (UBSan) + integer]' env: >- From 4632686119b3a89d296c2fc397c6057792d39727 Mon Sep 17 00:00:00 2001 From: Munkybooty Date: Thu, 26 Aug 2021 12:26:03 -0400 Subject: [PATCH 23/23] 15276 new line --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index bef0672042d8..3599da89750c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -288,6 +288,7 @@ after_success: RUN_BENCH=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --with-incompatible-bdb --with-gui=qt5 CPPFLAGS=-DDEBUG_LOCKORDER --with-sanitizers=integer,undefined CC=clang CXX=clang++" + - stage: test name: 'x86_64 Linux [GOAL: install] [bionic] [no wallet]' env: >-