diff --git a/.gitignore b/.gitignore index 204c463e74..d34b5eb02a 100644 --- a/.gitignore +++ b/.gitignore @@ -109,6 +109,7 @@ linux-coverage-build linux-build win32-build qa/pull-tester/tests_config.py +qa/pull-tester/tests_config.ini qa/cache/* !src/leveldb*/Makefile diff --git a/.travis.yml b/.travis.yml index 3a57c00eb2..9b2bb2043f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -73,7 +73,7 @@ script: - if [ $SECONDS -gt 1200 ]; then export DEPENDS_TIMEOUT="true"; false; fi # The "false" here ensures that the build is marked as failed even though the whole script returns 0 - test "$DEPENDS_TIMEOUT" != "true" && $DOCKER_RUN_IN_BUILDER ./ci/build_src.sh - test "$DEPENDS_TIMEOUT" != "true" && $DOCKER_RUN_IN_BUILDER ./ci/test_unittests.sh - - test "$DEPENDS_TIMEOUT" != "true" && $DOCKER_RUN_IN_BUILDER ./ci/test_integrationtests.sh -parallel=3 + - test "$DEPENDS_TIMEOUT" != "true" && $DOCKER_RUN_IN_BUILDER ./ci/test_integrationtests.sh --jobs=3 - test "$DEPENDS_TIMEOUT" != "true" && if [ "$DOCKER_BUILD" = "true" ]; then BUILD_DIR=build-ci/dashcore-$BUILD_TARGET ./docker/build-docker.sh; fi after_script: - echo $TRAVIS_COMMIT_RANGE diff --git a/Makefile.am b/Makefile.am index 81b90f2c46..ce09ef59ea 100644 --- a/Makefile.am +++ b/Makefile.am @@ -224,9 +224,6 @@ EXTRA_DIST = $(top_srcdir)/share/genbuild.sh qa/pull-tester/rpc-tests.py qa/rpc- CLEANFILES = $(OSX_DMG) $(BITCOIN_WIN_INSTALLER) -# This file is problematic for out-of-tree builds if it exists. -DISTCLEANFILES = qa/pull-tester/tests_config.pyc - .INTERMEDIATE: $(COVERAGE_INFO) DISTCHECK_CONFIGURE_FLAGS = --enable-man diff --git a/configure.ac b/configure.ac index 92f731c0c6..0e75c13802 100644 --- a/configure.ac +++ b/configure.ac @@ -1113,7 +1113,7 @@ AC_SUBST(ZMQ_LIBS) AC_SUBST(PROTOBUF_LIBS) AC_SUBST(QR_LIBS) AC_CONFIG_FILES([Makefile src/Makefile doc/man/Makefile share/setup.nsi share/qt/Info.plist src/test/buildenv.py]) -AC_CONFIG_FILES([qa/pull-tester/tests_config.py],[chmod +x qa/pull-tester/tests_config.py]) +AC_CONFIG_FILES([qa/pull-tester/tests_config.ini],[chmod +x qa/pull-tester/tests_config.ini]) AC_CONFIG_FILES([contrib/devtools/split-debug.sh],[chmod +x contrib/devtools/split-debug.sh]) AC_CONFIG_LINKS([qa/pull-tester/rpc-tests.py:qa/pull-tester/rpc-tests.py]) diff --git a/contrib/zmq/zmq_sub.py b/contrib/zmq/zmq_sub.py index fa15f1285c..035a39765a 100755 --- a/contrib/zmq/zmq_sub.py +++ b/contrib/zmq/zmq_sub.py @@ -1,34 +1,64 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. +""" + ZMQ example using python3's asyncio + + Dash should be started with the command line arguments: + dashd-testnet -daemon \ + -zmqpubhashblock=tcp://127.0.0.1:28332 \ + -zmqpubrawtx=tcp://127.0.0.1:28332 \ + -zmqpubhashtx=tcp://127.0.0.1:28332 \ + -zmqpubhashblock=tcp://127.0.0.1:28332 + + We use the asyncio library here. `self.handle()` installs itself as a + future at the end of the function. Since it never returns with the event + loop having an empty stack of futures, this creates an infinite loop. An + alternative is to wrap the contents of `handle` inside `while True`. + + A blocking example using python 2.7 can be obtained from the git history: + https://github.com/bitcoin/bitcoin/blob/37a7fe9e440b83e2364d5498931253937abe9294/contrib/zmq/zmq_sub.py +""" + import binascii +import asyncio import zmq +import zmq.asyncio +import signal import struct +import sys + +if not (sys.version_info.major >= 3 and sys.version_info.minor >= 5): + print("This example only works with Python 3.5 and greater") + exit(1) port = 28332 -zmqContext = zmq.Context() -zmqSubSocket = zmqContext.socket(zmq.SUB) -zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"hashblock") -zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"hashtx") -zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"hashtxlock") -zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"hashgovernancevote") -zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"hashgovernanceobject") -zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"hashinstantsenddoublespend") -zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"rawblock") -zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"rawtx") -zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"rawtxlock") -zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"rawgovernancevote") -zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"rawgovernanceobject") -zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"rawinstantsenddoublespend") -zmqSubSocket.connect("tcp://127.0.0.1:%i" % port) +class ZMQHandler(): + def __init__(self): + self.loop = zmq.asyncio.install() + self.zmqContext = zmq.asyncio.Context() -try: - while True: - msg = zmqSubSocket.recv_multipart() - topic = str(msg[0].decode("utf-8")) + self.zmqSubSocket = self.zmqContext.socket(zmq.SUB) + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashblock") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashtx") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashtxlock") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashgovernancevote") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashgovernanceobject") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashinstantsenddoublespend") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawblock") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawtx") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawtxlock") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawgovernancevote") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawgovernanceobject") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawinstantsenddoublespend") + self.zmqSubSocket.connect("tcp://127.0.0.1:%i" % port) + + async def handle(self) : + msg = await self.zmqSubSocket.recv_multipart() + topic = msg[0] body = msg[1] sequence = "Unknown" @@ -36,42 +66,53 @@ try: msgSequence = struct.unpack('= 3 and sys.version_info.minor >= 4): + print("This example only works with Python 3.4 and greater") + exit(1) + +port = 28332 + +class ZMQHandler(): + def __init__(self): + self.loop = zmq.asyncio.install() + self.zmqContext = zmq.asyncio.Context() + + self.zmqSubSocket = self.zmqContext.socket(zmq.SUB) + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashblock") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashtx") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashtxlock") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashgovernancevote") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashgovernanceobject") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashinstantsenddoublespend") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawblock") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawtx") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawtxlock") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawgovernancevote") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawgovernanceobject") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawinstantsenddoublespend") + self.zmqSubSocket.connect("tcp://127.0.0.1:%i" % port) + + @asyncio.coroutine + def handle(self) : + msg = yield from self.zmqSubSocket.recv_multipart() + topic = msg[0] + body = msg[1] + sequence = "Unknown"; + if len(msg[-1]) == 4: + msgSequence = struct.unpack(' 1 and run_parallel > 1: + if len(test_list) > 1 and jobs > 1: # Populate cache - subprocess.check_output([RPC_TESTS_DIR + 'create_cache.py'] + flags) + subprocess.check_output([tests_dir + 'create_cache.py'] + flags) #Run Tests - max_len_name = len(max(test_list, key=len)) + all_passed = True time_sum = 0 time0 = time.time() - job_queue = RPCTestHandler(run_parallel, test_list, flags) + + job_queue = RPCTestHandler(jobs, tests_dir, test_list, flags) + + max_len_name = len(max(test_list, key=len)) results = BOLD[1] + "%s | %s | %s\n\n" % ("TEST".ljust(max_len_name), "PASSED", "DURATION") + BOLD[0] - all_passed = True for _ in range(len(test_list)): (name, stdout, stderr, passed, duration) = job_queue.get_next() all_passed = all_passed and passed @@ -250,8 +256,10 @@ def runtests(): print('\n' + BOLD[1] + name + BOLD[0] + ":") print('' if passed else stdout + '\n', end='') print('' if stderr == '' else 'stderr:\n' + stderr + '\n', end='') - results += "%s | %s | %s s\n" % (name.ljust(max_len_name), str(passed).ljust(6), duration) print("Pass: %s%s%s, Duration: %s s\n" % (BOLD[1], passed, BOLD[0], duration)) + + results += "%s | %s | %s s\n" % (name.ljust(max_len_name), str(passed).ljust(6), duration) + results += BOLD[1] + "\n%s | %s | %s s (accumulated)" % ("ALL".ljust(max_len_name), str(all_passed).ljust(6), time_sum) + BOLD[0] print(results) print("\nRuntime: %s s" % (int(time.time() - time0))) @@ -264,15 +272,15 @@ def runtests(): sys.exit(not all_passed) - class RPCTestHandler: """ Trigger the testscrips passed in via the list. """ - def __init__(self, num_tests_parallel, test_list=None, flags=None): + def __init__(self, num_tests_parallel, tests_dir, test_list=None, flags=None): assert(num_tests_parallel >= 1) self.num_jobs = num_tests_parallel + self.tests_dir = tests_dir self.test_list = test_list self.flags = flags self.num_running = 0 @@ -292,7 +300,7 @@ class RPCTestHandler: log_stderr = tempfile.SpooledTemporaryFile(max_size=2**16) self.jobs.append((t, time.time(), - subprocess.Popen((RPC_TESTS_DIR + t).split() + self.flags + port_seed, + subprocess.Popen((self.tests_dir + t).split() + self.flags + port_seed, universal_newlines=True, stdout=log_stdout, stderr=log_stderr), @@ -357,10 +365,10 @@ class RPCCoverage(object): """ # This is shared from `qa/rpc-tests/test-framework/coverage.py` - REFERENCE_FILENAME = 'rpc_interface.txt' - COVERAGE_FILE_PREFIX = 'coverage.' + reference_filename = 'rpc_interface.txt' + coverage_file_prefix = 'coverage.' - coverage_ref_filename = os.path.join(self.dir, REFERENCE_FILENAME) + coverage_ref_filename = os.path.join(self.dir, reference_filename) coverage_filenames = set() all_cmds = set() covered_cmds = set() @@ -373,7 +381,7 @@ class RPCCoverage(object): for root, dirs, files in os.walk(self.dir): for filename in files: - if filename.startswith(COVERAGE_FILE_PREFIX): + if filename.startswith(coverage_file_prefix): coverage_filenames.add(os.path.join(root, filename)) for filename in coverage_filenames: @@ -384,4 +392,4 @@ class RPCCoverage(object): if __name__ == '__main__': - runtests() + main() diff --git a/qa/pull-tester/tests_config.ini.in b/qa/pull-tester/tests_config.ini.in new file mode 100644 index 0000000000..e3e457d0b1 --- /dev/null +++ b/qa/pull-tester/tests_config.ini.in @@ -0,0 +1,18 @@ +# Copyright (c) 2013-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# These environment variables are set by the build process and read by +# rpc-tests.py + +[environment] +SRCDIR=@abs_top_srcdir@ +BUILDDIR=@abs_top_builddir@ +EXEEXT=@EXEEXT@ + +[components] +# Which components are enabled. These are commented out by `configure` if they were disabled when running config. +@ENABLE_WALLET_TRUE@ENABLE_WALLET=true +@BUILD_BITCOIN_UTILS_TRUE@ENABLE_UTILS=true +@BUILD_BITCOIND_TRUE@ENABLE_BITCOIND=true +@ENABLE_ZMQ_TRUE@ENABLE_ZMQ=true diff --git a/qa/pull-tester/tests_config.py.in b/qa/pull-tester/tests_config.py.in deleted file mode 100644 index a0d0a3d98a..0000000000 --- a/qa/pull-tester/tests_config.py.in +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2013-2016 The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -SRCDIR="@abs_top_srcdir@" -BUILDDIR="@abs_top_builddir@" -EXEEXT="@EXEEXT@" - -# These will turn into comments if they were disabled when configuring. -@ENABLE_WALLET_TRUE@ENABLE_WALLET=1 -@BUILD_BITCOIN_UTILS_TRUE@ENABLE_UTILS=1 -@BUILD_BITCOIND_TRUE@ENABLE_BITCOIND=1 -@ENABLE_ZMQ_TRUE@ENABLE_ZMQ=1 diff --git a/qa/rpc-tests/bip68-112-113-p2p.py b/qa/rpc-tests/bip68-112-113-p2p.py index 2915029d0b..131ada5a4f 100755 --- a/qa/rpc-tests/bip68-112-113-p2p.py +++ b/qa/rpc-tests/bip68-112-113-p2p.py @@ -5,7 +5,7 @@ from test_framework.test_framework import ComparisonTestFramework from test_framework.util import * -from test_framework.mininode import ToHex, CTransaction, NetworkThread +from test_framework.mininode import ToHex, NetworkThread from test_framework.blocktools import create_coinbase, create_block from test_framework.comptool import TestInstance, TestManager from test_framework.script import * diff --git a/qa/rpc-tests/bip68-sequence.py b/qa/rpc-tests/bip68-sequence.py index 5e5fff8a78..d7718dfb09 100755 --- a/qa/rpc-tests/bip68-sequence.py +++ b/qa/rpc-tests/bip68-sequence.py @@ -9,8 +9,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -from test_framework.script import * -from test_framework.mininode import * from test_framework.blocktools import * SEQUENCE_LOCKTIME_DISABLE_FLAG = (1<<31) diff --git a/qa/rpc-tests/p2p-compactblocks.py b/qa/rpc-tests/p2p-compactblocks.py index da257b1580..d14ebc1ef6 100755 --- a/qa/rpc-tests/p2p-compactblocks.py +++ b/qa/rpc-tests/p2p-compactblocks.py @@ -7,7 +7,6 @@ from test_framework.mininode import * from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * from test_framework.blocktools import create_block, create_coinbase -from test_framework.siphash import siphash256 from test_framework.script import CScript, OP_TRUE ''' diff --git a/qa/rpc-tests/rpcnamedargs.py b/qa/rpc-tests/rpcnamedargs.py index da2d8f040f..f9a40955c0 100755 --- a/qa/rpc-tests/rpcnamedargs.py +++ b/qa/rpc-tests/rpcnamedargs.py @@ -3,17 +3,11 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -from decimal import Decimal - from test_framework.test_framework import BitcoinTestFramework -from test_framework.authproxy import JSONRPCException from test_framework.util import ( assert_equal, assert_raises_jsonrpc, - assert_is_hex_string, - assert_is_hash_string, start_nodes, - connect_nodes_bi, ) diff --git a/qa/rpc-tests/wallet-accounts.py b/qa/rpc-tests/wallet-accounts.py index cf2e3fc60b..3ba1caccbe 100755 --- a/qa/rpc-tests/wallet-accounts.py +++ b/qa/rpc-tests/wallet-accounts.py @@ -6,9 +6,7 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( start_nodes, - start_node, assert_equal, - connect_nodes_bi, ) diff --git a/src/init.cpp b/src/init.cpp index 1cda57b89e..829cf75e5f 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1174,7 +1174,7 @@ bool AppInitParameterInteraction() int64_t nMempoolSizeMin = GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT) * 1000 * 40; if (nMempoolSizeMax < 0 || nMempoolSizeMax < nMempoolSizeMin) return InitError(strprintf(_("-maxmempool must be at least %d MB"), std::ceil(nMempoolSizeMin / 1000000.0))); - // incremental relay fee sets the minimimum feerate increase necessary for BIP 125 replacement in the mempool + // incremental relay fee sets the minimum feerate increase necessary for BIP 125 replacement in the mempool // and the amount the mempool min fee increases above the feerate of txs evicted due to mempool limiting. if (IsArgSet("-incrementalrelayfee")) { diff --git a/src/netbase.cpp b/src/netbase.cpp index c48e4edd0c..03e336c3de 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -198,6 +198,14 @@ struct timeval MillisToTimeval(int64_t nTimeout) return timeout; } +enum class IntrRecvError { + OK, + Timeout, + Disconnected, + NetworkError, + Interrupted +}; + /** * Read bytes from socket. This will either read the full number of bytes requested * or return False on error or timeout. @@ -209,7 +217,7 @@ struct timeval MillisToTimeval(int64_t nTimeout) * * @note This function requires that hSocket is in non-blocking mode. */ -bool static InterruptibleRecv(char* data, size_t len, int timeout, SOCKET& hSocket) +static IntrRecvError InterruptibleRecv(char* data, size_t len, int timeout, SOCKET& hSocket) { int64_t curTime = GetTimeMillis(); int64_t endTime = curTime + timeout; @@ -222,12 +230,12 @@ bool static InterruptibleRecv(char* data, size_t len, int timeout, SOCKET& hSock len -= ret; data += ret; } else if (ret == 0) { // Unexpected disconnection - return false; + return IntrRecvError::Disconnected; } else { // Other error or blocking int nErr = WSAGetLastError(); if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || nErr == WSAEINVAL) { if (!IsSelectableSocket(hSocket)) { - return false; + return IntrRecvError::NetworkError; } struct timeval tval = MillisToTimeval(std::min(endTime - curTime, maxWait)); fd_set fdset; @@ -235,17 +243,17 @@ bool static InterruptibleRecv(char* data, size_t len, int timeout, SOCKET& hSock FD_SET(hSocket, &fdset); int nRet = select(hSocket + 1, &fdset, NULL, NULL, &tval); if (nRet == SOCKET_ERROR) { - return false; + return IntrRecvError::NetworkError; } } else { - return false; + return IntrRecvError::NetworkError; } } if (interruptSocks5Recv) - return false; + return IntrRecvError::Interrupted; curTime = GetTimeMillis(); } - return len == 0; + return len == 0 ? IntrRecvError::OK : IntrRecvError::Timeout; } struct ProxyCredentials @@ -272,6 +280,7 @@ std::string Socks5ErrorString(int err) /** Connect using SOCKS5 (as described in RFC1928) */ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials *auth, SOCKET& hSocket) { + IntrRecvError recvr; LogPrint("net", "SOCKS5 connecting %s\n", strDest); if (strDest.size() > 255) { CloseSocket(hSocket); @@ -294,7 +303,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials return error("Error sending to proxy"); } char pchRet1[2]; - if (!InterruptibleRecv(pchRet1, 2, SOCKS5_RECV_TIMEOUT, hSocket)) { + if ((recvr = InterruptibleRecv(pchRet1, 2, SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) { CloseSocket(hSocket); LogPrintf("Socks5() connect to %s:%d failed: InterruptibleRecv() timeout or other failure\n", strDest, port); return false; @@ -320,7 +329,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials } LogPrint("proxy", "SOCKS5 sending proxy authentication %s:%s\n", auth->username, auth->password); char pchRetA[2]; - if (!InterruptibleRecv(pchRetA, 2, SOCKS5_RECV_TIMEOUT, hSocket)) { + if ((recvr = InterruptibleRecv(pchRetA, 2, SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) { CloseSocket(hSocket); return error("Error reading proxy authentication response"); } @@ -349,9 +358,16 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials return error("Error sending to proxy"); } char pchRet2[4]; - if (!InterruptibleRecv(pchRet2, 4, SOCKS5_RECV_TIMEOUT, hSocket)) { + if ((recvr = InterruptibleRecv(pchRet2, 4, SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) { CloseSocket(hSocket); - return error("Error reading proxy response"); + if (recvr == IntrRecvError::Timeout) { + /* If a timeout happens here, this effectively means we timed out while connecting + * to the remote node. This is very common for Tor, so do not print an + * error message. */ + return false; + } else { + return error("Error while reading proxy response"); + } } if (pchRet2[0] != 0x05) { CloseSocket(hSocket); @@ -370,26 +386,26 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials char pchRet3[256]; switch (pchRet2[3]) { - case 0x01: ret = InterruptibleRecv(pchRet3, 4, SOCKS5_RECV_TIMEOUT, hSocket); break; - case 0x04: ret = InterruptibleRecv(pchRet3, 16, SOCKS5_RECV_TIMEOUT, hSocket); break; + case 0x01: recvr = InterruptibleRecv(pchRet3, 4, SOCKS5_RECV_TIMEOUT, hSocket); break; + case 0x04: recvr = InterruptibleRecv(pchRet3, 16, SOCKS5_RECV_TIMEOUT, hSocket); break; case 0x03: { - ret = InterruptibleRecv(pchRet3, 1, SOCKS5_RECV_TIMEOUT, hSocket); - if (!ret) { + recvr = InterruptibleRecv(pchRet3, 1, SOCKS5_RECV_TIMEOUT, hSocket); + if (recvr != IntrRecvError::OK) { CloseSocket(hSocket); return error("Error reading from proxy"); } int nRecv = pchRet3[0]; - ret = InterruptibleRecv(pchRet3, nRecv, SOCKS5_RECV_TIMEOUT, hSocket); + recvr = InterruptibleRecv(pchRet3, nRecv, SOCKS5_RECV_TIMEOUT, hSocket); break; } default: CloseSocket(hSocket); return error("Error: malformed proxy response"); } - if (!ret) { + if (recvr != IntrRecvError::OK) { CloseSocket(hSocket); return error("Error reading from proxy"); } - if (!InterruptibleRecv(pchRet3, 2, SOCKS5_RECV_TIMEOUT, hSocket)) { + if ((recvr = InterruptibleRecv(pchRet3, 2, SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) { CloseSocket(hSocket); return error("Error reading from proxy"); } diff --git a/src/qt/forms/intro.ui b/src/qt/forms/intro.ui index 19b90f705f..91d4553ce7 100644 --- a/src/qt/forms/intro.ui +++ b/src/qt/forms/intro.ui @@ -7,7 +7,7 @@ 0 0 674 - 363 + 415 @@ -55,9 +55,6 @@ - - %1 will download and store a copy of the Dash block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - true @@ -203,6 +200,36 @@ + + + + When you click OK, %1 will begin to download and process the full %4 block chain (%2GB) starting with the earliest transactions in %3 when %4 initially launched. + + + true + + + + + + + This initial synchronisation is very demanding, and may expose hardware problems with your computer that had previously gone unnoticed. Each time you run %1, it will continue downloading where it left off. + + + true + + + + + + + If you have chosen to limit block chain storage (pruning), the historical data must still be downloaded and processed, but will be deleted afterward to keep your disk usage low. + + + true + + + diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 31aab8ff2d..877e8e8e32 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -38,9 +38,7 @@ #include #include -#if BOOST_FILESYSTEM_VERSION >= 3 #include -#endif #include #include @@ -68,9 +66,7 @@ #include #endif -#if BOOST_FILESYSTEM_VERSION >= 3 static boost::filesystem::detail::utf8_codecvt_facet utf8; -#endif #if defined(Q_OS_MAC) extern double NSAppKitVersionNumber; @@ -952,7 +948,6 @@ void setClipboard(const QString& str) QApplication::clipboard()->setText(str, QClipboard::Selection); } -#if BOOST_FILESYSTEM_VERSION >= 3 boost::filesystem::path qstringToBoostPath(const QString &path) { return boost::filesystem::path(path.toStdString(), utf8); @@ -962,18 +957,6 @@ QString boostPathToQString(const boost::filesystem::path &path) { return QString::fromStdString(path.string(utf8)); } -#else -#warning Conversion between boost path and QString can use invalid character encoding with boost_filesystem v2 and older -boost::filesystem::path qstringToBoostPath(const QString &path) -{ - return boost::filesystem::path(path.toStdString()); -} - -QString boostPathToQString(const boost::filesystem::path &path) -{ - return QString::fromStdString(path.string()); -} -#endif QString formatDurationStr(int secs) { diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index d752072b48..117d4424c3 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -125,16 +125,34 @@ Intro::Intro(QWidget *parent) : ui->setupUi(this); ui->welcomeLabel->setText(ui->welcomeLabel->text().arg(tr(PACKAGE_NAME))); ui->storageLabel->setText(ui->storageLabel->text().arg(tr(PACKAGE_NAME))); + + ui->lblExplanation1->setText(ui->lblExplanation1->text() + .arg(tr(PACKAGE_NAME)) + .arg(BLOCK_CHAIN_SIZE) + .arg(2014) + .arg(tr("Dash")) + ); + ui->lblExplanation2->setText(ui->lblExplanation2->text().arg(tr(PACKAGE_NAME))); + uint64_t pruneTarget = std::max(0, GetArg("-prune", 0)); requiredSpace = BLOCK_CHAIN_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); if (prunedGBs <= requiredSpace) { requiredSpace = prunedGBs; + storageRequiresMsg = tr("Approximately %1 GB of data will be stored in this directory."); } + ui->lblExplanation3->setVisible(true); + } else { + ui->lblExplanation3->setVisible(false); } requiredSpace += CHAIN_STATE_SIZE; - ui->sizeWarningLabel->setText(ui->sizeWarningLabel->text().arg(tr(PACKAGE_NAME)).arg(requiredSpace)); + ui->sizeWarningLabel->setText( + tr("%1 will download and store a copy of the Bitcoin block chain.").arg(tr(PACKAGE_NAME)) + " " + + storageRequiresMsg.arg(requiredSpace) + " " + + tr("The wallet will also be stored in this directory.") + ); startThread(); } diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 643beb54e7..8242ffcaba 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -22,7 +22,7 @@ public: std::string paramName; //!< parameter name }; /** - * Specifiy a (method, idx, name) here if the argument is a non-string RPC + * Specify a (method, idx, name) here if the argument is a non-string RPC * argument and needs to be converted from JSON. * * @note Parameter indexes start from 0. diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 8799a7959f..c3605f834a 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -595,7 +595,7 @@ UniValue setmocktime(const JSONRPCRequest& request) // this could have an effect on mempool time-based eviction, as well as // IsCurrentForFeeEstimation() and IsInitialBlockDownload(). // TODO: figure out the right way to synchronize around mocktime, and - // ensure all callsites of GetTime() are accessing this safely. + // ensure all call sites of GetTime() are accessing this safely. LOCK(cs_main); RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VNUM)); diff --git a/src/test/testutil.cpp b/src/test/testutil.cpp index 304cffb798..e6d8622979 100644 --- a/src/test/testutil.cpp +++ b/src/test/testutil.cpp @@ -11,23 +11,5 @@ #include boost::filesystem::path GetTempPath() { -#if BOOST_FILESYSTEM_VERSION == 3 return boost::filesystem::temp_directory_path(); -#else - // TODO: remove when we don't support filesystem v2 anymore - boost::filesystem::path path; -#ifdef WIN32 - char pszPath[MAX_PATH] = ""; - - if (GetTempPathA(MAX_PATH, pszPath)) - path = boost::filesystem::path(pszPath); -#else - path = boost::filesystem::path("/tmp"); -#endif - if (path.empty() || !boost::filesystem::is_directory(path)) { - LogPrintf("GetTempPath(): failed to find temp path\n"); - return boost::filesystem::path(""); - } - return path; -#endif } diff --git a/src/utiltime.h b/src/utiltime.h index e37ee32813..cb2c0afb1e 100644 --- a/src/utiltime.h +++ b/src/utiltime.h @@ -11,7 +11,7 @@ /** * GetTimeMicros() and GetTimeMillis() both return the system time, but in - * different units. GetTime() returns the sytem time in seconds, but also + * different units. GetTime() returns the system time in seconds, but also * supports mocktime, where the time can be specified by the user, eg for * testing (eg with the setmocktime rpc, or -mocktime argument). * diff --git a/src/validation.cpp b/src/validation.cpp index e51e3034cd..d79218fcd2 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1444,7 +1444,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi // Helps prevent CPU exhaustion attacks. // Skip script verification when connecting blocks under the - // assumedvalid block. Assuming the assumedvalid block is valid this + // assumevalid block. Assuming the assumevalid block is valid this // is safe because block merkle hashes are still computed and checked, // Of course, if an assumed valid block is invalid due to false scriptSigs // this optimization would allow an invalid chain to be accepted. @@ -1932,7 +1932,7 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd pindexBestHeader->GetAncestor(pindex->nHeight) == pindex && pindexBestHeader->nChainWork >= UintToArith256(chainparams.GetConsensus().nMinimumChainWork)) { // This block is a member of the assumed verified chain and an ancestor of the best header. - // The equivalent time check discourages hashpower from extorting the network via DOS attack + // The equivalent time check discourages hash power from extorting the network via DOS attack // into accepting an invalid block through telling users they must manually set assumevalid. // Requiring a software change or burying the invalid block, regardless of the setting, makes // it hard to hide the implication of the demand. This also avoids having release candidates @@ -2831,12 +2831,12 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, bool fInitialDownload; { LOCK(cs_main); - { // TODO: Tempoarily ensure that mempool removals are notified before + { // TODO: Temporarily ensure that mempool removals are notified before // connected transactions. This shouldn't matter, but the abandoned // state of transactions in our wallet is currently cleared when we // receive another notification and there is a race condition where // notification of a connected conflict might cause an outside process - // to abandon a transaction and then have it inadvertantly cleared by + // to abandon a transaction and then have it inadvertently cleared by // the notification that the conflicted transaction was evicted. MemPoolConflictRemovalTracker mrt(mempool); CBlockIndex *pindexOldTip = chainActive.Tip(); @@ -2865,7 +2865,7 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, } // MemPoolConflictRemovalTracker destroyed and conflict evictions are notified - // Transactions in the connnected block are notified + // Transactions in the connected block are notified for (const auto& pair : connectTrace.blocksConnected) { assert(pair.second); const CBlock& block = *(pair.second); diff --git a/src/validationinterface.h b/src/validationinterface.h index 78dafba43a..f28144ed97 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -63,7 +63,7 @@ struct CMainSignals { boost::signals2::signal NotifyHeaderTip; /** Notifies listeners of updated block chain tip */ boost::signals2::signal UpdatedBlockTip; - /** A posInBlock value for SyncTransaction calls for tranactions not + /** A posInBlock value for SyncTransaction calls for transactions not * included in connected blocks such as transactions removed from mempool, * accepted to mempool or appearing in disconnected blocks.*/ static const int SYNC_TRANSACTION_NOT_IN_BLOCK = -1; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index d0982ba94a..fd0ec54858 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1219,7 +1219,7 @@ bool CWallet::LoadToWallet(const CWalletTx& wtxIn) * TODO: One exception to this is that the abandoned state is cleared under the * assumption that any further notification of a transaction that was considered * abandoned is an indication that it is not safe to be considered abandoned. - * Abandoned state should probably be more carefuly tracked via different + * Abandoned state should probably be more carefully tracked via different * posInBlock signals or by checking mempool presence when necessary. */ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlockIndex* pIndex, int posInBlock, bool fUpdate) @@ -5221,11 +5221,7 @@ bool CWallet::BackupWallet(const std::string& strDest) pathDest /= strWalletFile; try { -#if BOOST_VERSION >= 104000 boost::filesystem::copy_file(pathSrc, pathDest, boost::filesystem::copy_option::overwrite_if_exists); -#else - boost::filesystem::copy_file(pathSrc, pathDest); -#endif LogPrintf("copied %s to %s\n", strWalletFile, pathDest.string()); return true; } catch (const boost::filesystem::filesystem_error& e) {