diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 0000000000..ff84c01a39 --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,65 @@ +version: '{branch}.{build}' +skip_tags: true +image: Visual Studio 2017 +configuration: Release +platform: x64 +environment: + APPVEYOR_SAVE_CACHE_ON_ERROR: true + CLCACHE_SERVER: 1 + PACKAGES: boost-filesystem boost-signals2 boost-test libevent openssl zeromq berkeleydb secp256k1 leveldb + PYTHONIOENCODING: utf-8 +cache: +- C:\tools\vcpkg\installed +- C:\Users\appveyor\clcache +init: +- cmd: set PATH=C:\Python36-x64;C:\Python36-x64\Scripts;%PATH% +install: +- cmd: pip install git+https://github.com/frerich/clcache.git +# Disable zmq test for now since python zmq library on Windows would cause Access violation sometimes. +# - cmd: pip install zmq +- ps: $packages = $env:PACKAGES -Split ' ' +- ps: for ($i=0; $i -lt $packages.length; $i++) { + $env:ALL_PACKAGES += $packages[$i] + ":" + $env:PLATFORM + "-windows-static " + } +- cmd: git -C C:\Tools\vcpkg pull # This is a temporary fix, can be removed after appveyor update its image to include Microsoft/vcpkg#4046 +- cmd: C:\Tools\vcpkg\bootstrap-vcpkg.bat +- cmd: vcpkg remove --recurse --outdated +- cmd: vcpkg install %ALL_PACKAGES% +- cmd: del /s /q C:\Tools\vcpkg\installed\%PLATFORM%-windows-static\debug # Remove unused debug library +before_build: +- ps: clcache -M 536870912 +- cmd: python build_msvc\msvc-autogen.py +- ps: $files = (Get-ChildItem -Recurse | where {$_.extension -eq ".vcxproj"}).FullName +- ps: for (${i} = 0; ${i} -lt ${files}.length; ${i}++) { + ${content} = (Get-Content ${files}[${i}]); + ${content} = ${content}.Replace("", "None"); + ${content} = ${content}.Replace("true", "false"); + ${content} = ${content}.Replace("NDEBUG;", ""); + Set-Content ${files}[${i}] ${content}; + } +- ps: Start-Process clcache-server +- ps: fsutil behavior set disablelastaccess 0 # Enable Access time feature on Windows (for clcache) +build_script: +- cmd: msbuild /p:TrackFileAccess=false /p:CLToolExe=clcache.exe build_msvc\bitcoin.sln /m /v:q /nowarn:C4244;C4267;C4715 /nologo +after_build: +- ps: fsutil behavior set disablelastaccess 0 # Disable Access time feature on Windows (better performance) +- ps: clcache -z +before_test: +- ps: ${conf_ini} = (Get-Content([IO.Path]::Combine(${env:APPVEYOR_BUILD_FOLDER}, "test", "config.ini.in"))) +- ps: ${conf_ini} = ${conf_ini}.Replace("@abs_top_srcdir@", ${env:APPVEYOR_BUILD_FOLDER}) +- ps: ${conf_ini} = ${conf_ini}.Replace("@abs_top_builddir@", ${env:APPVEYOR_BUILD_FOLDER}) +- ps: ${conf_ini} = ${conf_ini}.Replace("@EXEEXT@", ".exe") +- ps: ${conf_ini} = ${conf_ini}.Replace("@ENABLE_WALLET_TRUE@", "") +- ps: ${conf_ini} = ${conf_ini}.Replace("@BUILD_BITCOIN_CLI_TRUE@", "") +- ps: ${conf_ini} = ${conf_ini}.Replace("@BUILD_BITCOIND_TRUE@", "") +- ps: ${conf_ini} = ${conf_ini}.Replace("@ENABLE_ZMQ_TRUE@", "") +- ps: ${utf8} = New-Object System.Text.UTF8Encoding ${false} +- ps: '[IO.File]::WriteAllLines([IO.Path]::Combine(${env:APPVEYOR_BUILD_FOLDER}, "test", "config.ini"), ${conf_ini}, ${utf8})' +- ps: move "build_msvc\${env:PLATFORM}\${env:CONFIGURATION}\*.exe" src +test_script: +- cmd: src\test_bitcoin.exe +- ps: src\bench_bitcoin.exe -evals=1 -scaling=0 +- ps: python test\util\bitcoin-util-test.py +- cmd: python test\util\rpcauth-test.py +- cmd: python test\functional\test_runner.py --force --quiet --combinedlogslen=4000 --exclude wallet_multiwallet +deploy: off diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000..00d5478c4e --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,31 @@ +Pull requests without a rationale and clear improvement may be closed +immediately. + +Please provide clear motivation for your patch and explain how it improves +Bitcoin Core user experience or Bitcoin Core developer experience +significantly. + +* Any test improvements or new tests that improve coverage are always welcome. +* All other changes should have accompanying unit tests (see `src/test/`) or + functional tests (see `test/`). Contributors should note which tests cover + modified code. If no tests exist for a region of modified code, new tests + should accompany the change. +* Bug fixes are most welcome when they come with steps to reproduce or an + explanation of the potential issue as well as reasoning for the way the bug + was fixed. +* Features are welcome, but might be rejected due to design or scope issues. + If a feature is based on a lot of dependencies, contributors should first + consider building the system outside of Bitcoin Core, if possible. +* Refactoring changes are only accepted if they are required for a feature or + bug fix or otherwise improve developer experience significantly. For example, + most "code style" refactoring changes require a thorough explanation why they + are useful, what downsides they have and why they *significantly* improve + developer experience or avoid serious programming bugs. Note that code style + is often a subjective matter. Unless they are explicitly mentioned to be + preferred in the [developer notes](/doc/developer-notes.md), stylistic code + changes are usually rejected. + +Bitcoin Core has a thorough review process and even the most trivial change +needs to pass a lot of eyes and requires non-zero or even substantial time +effort to review. There is a huge lack of active reviewers on the project, so +patches often sit for a long time. diff --git a/Makefile.am b/Makefile.am index 4795321989..24cbed6291 100644 --- a/Makefile.am +++ b/Makefile.am @@ -168,7 +168,7 @@ $(BITCOIN_CLI_BIN): FORCE $(MAKE) -C src $(@F) if USE_LCOV -LCOV_FILTER_PATTERN=-p "/usr/include/" -p "src/leveldb/" -p "src/bench/" -p "src/univalue" -p "src/crypto/ctaes" -p "src/secp256k1" +LCOV_FILTER_PATTERN=-p "/usr/include/" -p "/usr/lib/" -p "src/leveldb/" -p "src/bench/" -p "src/univalue" -p "src/crypto/ctaes" -p "src/secp256k1" baseline.info: $(LCOV) -c -i -d $(abs_builddir)/src -o $@ @@ -294,5 +294,5 @@ clean-docs: clean-local: clean-docs rm -rf coverage_percent.txt test_bitcoin.coverage/ total.coverage/ test/tmp/ cache/ $(OSX_APP) - rm -rf test/functional/__pycache__ test/functional/test_framework/__pycache__ test/cache + rm -rf test/functional/__pycache__ test/functional/test_framework/__pycache__ test/cache share/rpcauth/__pycache__ diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 85b1a999d1..0000000000 --- a/appveyor.yml +++ /dev/null @@ -1,40 +0,0 @@ -version: '{branch}.{build}' -skip_tags: true -image: Visual Studio 2017 -configuration: Release -platform: x64 -environment: - APPVEYOR_SAVE_CACHE_ON_ERROR: true -cache: C:\tools\vcpkg\installed\ -init: -- cmd: set PATH=C:\Python36-x64;%PATH% -before_build: -- ps: >- - $packages = @( - "boost-filesystem", - "boost-signals2", - "boost-interprocess", - "boost-test", - "libevent", - "openssl", - "zeromq", - "berkeleydb", - "secp256k1", - "leveldb" - ) - - for ($i=0; $i -lt $packages.length; $i++) { - $all_packages += $packages[$i] + ":" + $env:PLATFORM + "-windows-static " - } - - git -C C:\Tools\vcpkg pull # This is a temporary fix, can be removed after appveyor update its image to include Microsoft/vcpkg#4046 - - Invoke-Expression -Command "vcpkg install $all_packages" -- cmd: python build_msvc\msvc-autogen.py -build: - project: build_msvc\bitcoin.sln - parallel: true - verbosity: minimal -test_script: -- cmd: build_msvc\%PLATFORM%\Release\test_bitcoin.exe -deploy: off diff --git a/build_msvc/libbitcoinconsensus/libbitcoinconsensus.vcxproj b/build_msvc/libbitcoinconsensus/libbitcoinconsensus.vcxproj index e6f4885e5e..0be7e7e430 100644 --- a/build_msvc/libbitcoinconsensus/libbitcoinconsensus.vcxproj +++ b/build_msvc/libbitcoinconsensus/libbitcoinconsensus.vcxproj @@ -127,7 +127,7 @@ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) false ..\..\src; - false + Sync false MultiThreadedDebug @@ -144,7 +144,7 @@ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) false ..\..\src; - false + Sync false MultiThreadedDebug @@ -163,7 +163,7 @@ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) false ..\..\src; - false + Sync false MultiThreaded @@ -184,7 +184,7 @@ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) false ..\..\src; - false + Sync false MultiThreaded diff --git a/configure.ac b/configure.ac index a0cacce69a..945b211e91 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 0) -define(_CLIENT_VERSION_MINOR, 16) +define(_CLIENT_VERSION_MINOR, 17) define(_CLIENT_VERSION_REVISION, 99) define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_IS_RELEASE, false) @@ -131,6 +131,12 @@ AC_ARG_ENABLE(gui-tests, [use_gui_tests=$enableval], [use_gui_tests=$use_tests]) +AC_ARG_WITH([rapidcheck], + [AS_HELP_STRING([--with-rapidcheck], + [enable RapidCheck property based tests (default is yes if librapidcheck is found)])], + [use_rapidcheck=$withval], + [use_rapidcheck=auto]) + AC_ARG_ENABLE(bench, AS_HELP_STRING([--disable-bench],[do not compile benchmarks (default is not to compile)]), [use_bench=$enableval], @@ -401,6 +407,18 @@ AC_ARG_WITH([utils], [build_bitcoin_utils=$withval], [build_bitcoin_utils=yes]) +AC_ARG_ENABLE([util-cli], + [AS_HELP_STRING([--enable-util-cli], + [build feathercoin-cli])], + [build_bitcoin_cli=$enableval], + [build_bitcoin_cli=$build_bitcoin_utils]) + +AC_ARG_ENABLE([util-tx], + [AS_HELP_STRING([--enable-util-tx], + [build feathercoin-tx])], + [build_bitcoin_tx=$enableval], + [build_bitcoin_tx=$build_bitcoin_utils]) + AC_ARG_WITH([libs], [AS_HELP_STRING([--with-libs], [build libraries (default=yes)])], @@ -736,6 +754,10 @@ fi AC_CHECK_HEADERS([endian.h sys/endian.h byteswap.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h]) +AC_CHECK_DECLS([getifaddrs, freeifaddrs],,, + [#include + #include ] +) AC_CHECK_DECLS([strnlen]) # Check for daemon(3), unrelated to --with-daemon (although used by it) @@ -885,7 +907,7 @@ BITCOIN_QT_INIT dnl sets $bitcoin_enable_qt, $bitcoin_enable_qt_test, $bitcoin_enable_qt_dbus BITCOIN_QT_CONFIGURE([$use_pkgconfig]) -if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench = xnonononono; then +if test x$build_bitcoin_cli$build_bitcoin_tx$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench = xnononononono; then use_boost=no else use_boost=yes @@ -1073,7 +1095,7 @@ if test x$use_pkgconfig = xyes; then if test x$use_qr != xno; then BITCOIN_QT_CHECK([PKG_CHECK_MODULES([QR], [libqrencode], [have_qrencode=yes], [have_qrencode=no])]) fi - if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests != xnononono; then + if test x$build_bitcoin_cli$build_bitcoin_tx$build_bitcoind$bitcoin_enable_qt$use_tests != xnonononono; then PKG_CHECK_MODULES([EVENT], [libevent],, [AC_MSG_ERROR(libevent not found.)]) if test x$TARGET_OS != xwindows; then PKG_CHECK_MODULES([EVENT_PTHREADS], [libevent_pthreads],, [AC_MSG_ERROR(libevent_pthreads not found.)]) @@ -1098,7 +1120,7 @@ else AC_CHECK_HEADER([openssl/ssl.h],, AC_MSG_ERROR(libssl headers missing),) AC_CHECK_LIB([ssl], [main],SSL_LIBS=-lssl, AC_MSG_ERROR(libssl missing)) - if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests != xnononono; then + if test x$build_bitcoin_cli$build_bitcoin_tx$build_bitcoind$bitcoin_enable_qt$use_tests != xnonononono; then AC_CHECK_HEADER([event2/event.h],, AC_MSG_ERROR(libevent headers missing),) AC_CHECK_LIB([event],[main],EVENT_LIBS=-levent,AC_MSG_ERROR(libevent missing)) if test x$TARGET_OS != xwindows; then @@ -1143,11 +1165,27 @@ AC_CHECK_DECLS([EVP_MD_CTX_new],,,[AC_INCLUDES_DEFAULT ]) CXXFLAGS="${save_CXXFLAGS}" +dnl RapidCheck Property Based Testing + +enable_property_tests=no +if test "x$use_rapidcheck" = xauto; then + AC_CHECK_HEADERS([rapidcheck.h], [enable_property_tests=yes]) +elif test "x$use_rapidcheck" != xno; then + enable_property_tests=yes +fi + +RAPIDCHECK_LIBS= +if test "x$enable_property_tests" = xyes; then + RAPIDCHECK_LIBS=-lrapidcheck +fi +AC_SUBST(RAPIDCHECK_LIBS) +AM_CONDITIONAL([ENABLE_PROPERTY_TESTS], [test x$enable_property_tests = xyes]) + dnl univalue check need_bundled_univalue=yes -if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench = xnonononono; then +if test x$build_bitcoin_cli$build_bitcoin_tx$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench = xnononononono; then need_bundled_univalue=no else @@ -1197,9 +1235,13 @@ AC_MSG_CHECKING([whether to build feathercoind]) AM_CONDITIONAL([BUILD_BITCOIND], [test x$build_bitcoind = xyes]) AC_MSG_RESULT($build_bitcoind) -AC_MSG_CHECKING([whether to build utils (feathercoin-cli feathercoin-tx)]) -AM_CONDITIONAL([BUILD_BITCOIN_UTILS], [test x$build_bitcoin_utils = xyes]) -AC_MSG_RESULT($build_bitcoin_utils) +AC_MSG_CHECKING([whether to build feathercoin-cli]) +AM_CONDITIONAL([BUILD_BITCOIN_CLI], [test x$build_bitcoin_cli = xyes]) +AC_MSG_RESULT($build_bitcoin_cli) + +AC_MSG_CHECKING([whether to build feathercoin-tx]) +AM_CONDITIONAL([BUILD_BITCOIN_TX], [test x$build_bitcoin_tx = xyes]) +AC_MSG_RESULT($build_bitcoin_tx) AC_MSG_CHECKING([whether to build libraries]) AM_CONDITIONAL([BUILD_BITCOIN_LIBS], [test x$build_bitcoin_libs = xyes]) @@ -1325,7 +1367,7 @@ else AC_MSG_RESULT([no]) fi -if test x$build_bitcoin_utils$build_bitcoin_libs$build_bitcoind$bitcoin_enable_qt$use_bench$use_tests = xnononononono; then +if test x$build_bitcoin_cli$build_bitcoin_tx$build_bitcoin_libs$build_bitcoind$bitcoin_enable_qt$use_bench$use_tests = xnonononononono; then AC_MSG_ERROR([No targets! Please specify at least one of: --with-utils --with-libs --with-daemon --with-gui --enable-bench or --enable-tests]) fi diff --git a/contrib/debian/copyright b/contrib/debian/copyright index 21cca7d9ac..e5b9cbaa40 100644 --- a/contrib/debian/copyright +++ b/contrib/debian/copyright @@ -96,7 +96,7 @@ Comment: Site: https://bitcointalk.org/?topic=1756.0 Files: src/qt/res/icons/proxy.png src/qt/res/src/proxy.svg Copyright: Cristian Mircea Messel -Licese: public-domain +License: public-domain License: Expat diff --git a/contrib/devtools/optimize-pngs.py b/contrib/devtools/optimize-pngs.py index 8b1f41f7e1..e9481dbbcf 100755 --- a/contrib/devtools/optimize-pngs.py +++ b/contrib/devtools/optimize-pngs.py @@ -27,7 +27,7 @@ def content_hash(filename): pngcrush = 'pngcrush' git = 'git' folders = ["src/qt/res/movies", "src/qt/res/icons", "share/pixmaps"] -basePath = subprocess.check_output([git, 'rev-parse', '--show-toplevel'], universal_newlines=True).rstrip('\n') +basePath = subprocess.check_output([git, 'rev-parse', '--show-toplevel'], universal_newlines=True, encoding='utf8').rstrip('\n') totalSaveBytes = 0 noHashChange = True @@ -50,7 +50,7 @@ def content_hash(filename): sys.exit(0) #verify - if "Not a PNG file" in subprocess.check_output([pngcrush, "-n", "-v", file_path], stderr=subprocess.STDOUT, universal_newlines=True): + if "Not a PNG file" in subprocess.check_output([pngcrush, "-n", "-v", file_path], stderr=subprocess.STDOUT, universal_newlines=True, encoding='utf8'): print("PNG file "+file+" is corrupted after crushing, check out pngcursh version") sys.exit(1) diff --git a/contrib/gitian-build.py b/contrib/gitian-build.py index 0e53c3dfd5..faf8b014aa 100755 --- a/contrib/gitian-build.py +++ b/contrib/gitian-build.py @@ -65,14 +65,14 @@ def build(): print('\nCompiling ' + args.version + ' Windows') subprocess.check_call(['bin/gbuild', '-j', args.jobs, '-m', args.memory, '--commit', 'bitcoin='+args.commit, '--url', 'bitcoin='+args.url, '../bitcoin/contrib/gitian-descriptors/gitian-win.yml']) subprocess.check_call(['bin/gsign', '-p', args.sign_prog, '--signer', args.signer, '--release', args.version+'-win-unsigned', '--destination', '../gitian.sigs/', '../bitcoin/contrib/gitian-descriptors/gitian-win.yml']) - subprocess.check_call('mv build/out/bitcoin-*-win-unsigned.tar.gz inputs/bitcoin-win-unsigned.tar.gz', shell=True) + subprocess.check_call('mv build/out/bitcoin-*-win-unsigned.tar.gz inputs/', shell=True) subprocess.check_call('mv build/out/bitcoin-*.zip build/out/bitcoin-*.exe ../bitcoin-binaries/'+args.version, shell=True) if args.macos: print('\nCompiling ' + args.version + ' MacOS') subprocess.check_call(['bin/gbuild', '-j', args.jobs, '-m', args.memory, '--commit', 'bitcoin='+args.commit, '--url', 'bitcoin='+args.url, '../bitcoin/contrib/gitian-descriptors/gitian-osx.yml']) subprocess.check_call(['bin/gsign', '-p', args.sign_prog, '--signer', args.signer, '--release', args.version+'-osx-unsigned', '--destination', '../gitian.sigs/', '../bitcoin/contrib/gitian-descriptors/gitian-osx.yml']) - subprocess.check_call('mv build/out/bitcoin-*-osx-unsigned.tar.gz inputs/bitcoin-osx-unsigned.tar.gz', shell=True) + subprocess.check_call('mv build/out/bitcoin-*-osx-unsigned.tar.gz inputs/', shell=True) subprocess.check_call('mv build/out/bitcoin-*.tar.gz build/out/bitcoin-*.dmg ../bitcoin-binaries/'+args.version, shell=True) os.chdir(workdir) @@ -92,6 +92,7 @@ def sign(): if args.windows: print('\nSigning ' + args.version + ' Windows') + subprocess.check_call('cp inputs/bitcoin-' + args.version + '-win-unsigned.tar.gz inputs/bitcoin-win-unsigned.tar.gz', shell=True) subprocess.check_call(['bin/gbuild', '-i', '--commit', 'signature='+args.commit, '../bitcoin/contrib/gitian-descriptors/gitian-win-signer.yml']) subprocess.check_call(['bin/gsign', '-p', args.sign_prog, '--signer', args.signer, '--release', args.version+'-win-signed', '--destination', '../gitian.sigs/', '../bitcoin/contrib/gitian-descriptors/gitian-win-signer.yml']) subprocess.check_call('mv build/out/bitcoin-*win64-setup.exe ../bitcoin-binaries/'+args.version, shell=True) @@ -99,6 +100,7 @@ def sign(): if args.macos: print('\nSigning ' + args.version + ' MacOS') + subprocess.check_call('cp inputs/bitcoin-' + args.version + '-osx-unsigned.tar.gz inputs/bitcoin-osx-unsigned.tar.gz', shell=True) subprocess.check_call(['bin/gbuild', '-i', '--commit', 'signature='+args.commit, '../bitcoin/contrib/gitian-descriptors/gitian-osx-signer.yml']) subprocess.check_call(['bin/gsign', '-p', args.sign_prog, '--signer', args.signer, '--release', args.version+'-osx-signed', '--destination', '../gitian.sigs/', '../bitcoin/contrib/gitian-descriptors/gitian-osx-signer.yml']) subprocess.check_call('mv build/out/bitcoin-osx-signed.dmg ../bitcoin-binaries/'+args.version+'/bitcoin-'+args.version+'-osx.dmg', shell=True) @@ -170,7 +172,7 @@ def main(): args.sign_prog = 'true' if args.detach_sign else 'gpg --detach-sign' - # Set enviroment variable USE_LXC or USE_DOCKER, let gitian-builder know that we use lxc or docker + # Set environment variable USE_LXC or USE_DOCKER, let gitian-builder know that we use lxc or docker if args.docker: os.environ['USE_DOCKER'] = '1' elif not args.kvm: @@ -209,7 +211,7 @@ def main(): subprocess.check_call(['git', 'fetch', args.url, 'refs/pull/'+args.version+'/merge']) os.chdir('../gitian-builder/inputs/bitcoin') subprocess.check_call(['git', 'fetch', args.url, 'refs/pull/'+args.version+'/merge']) - args.commit = subprocess.check_output(['git', 'show', '-s', '--format=%H', 'FETCH_HEAD'], universal_newlines=True).strip() + args.commit = subprocess.check_output(['git', 'show', '-s', '--format=%H', 'FETCH_HEAD'], universal_newlines=True, encoding='utf8').strip() args.version = 'pull-' + args.version print(args.commit) subprocess.check_call(['git', 'fetch']) diff --git a/contrib/verify-commits/verify-commits.py b/contrib/verify-commits/verify-commits.py index a9e4977715..544f4dc48d 100755 --- a/contrib/verify-commits/verify-commits.py +++ b/contrib/verify-commits/verify-commits.py @@ -91,7 +91,7 @@ def main(): no_sha1 = True prev_commit = "" initial_commit = current_commit - branch = subprocess.check_output([GIT, 'show', '-s', '--format=%H', initial_commit], universal_newlines=True).splitlines()[0] + branch = subprocess.check_output([GIT, 'show', '-s', '--format=%H', initial_commit], universal_newlines=True, encoding='utf8').splitlines()[0] # Iterate through commits while True: @@ -112,7 +112,7 @@ def main(): if prev_commit != "": print("No parent of {} was signed with a trusted key!".format(prev_commit), file=sys.stderr) print("Parents are:", file=sys.stderr) - parents = subprocess.check_output([GIT, 'show', '-s', '--format=format:%P', prev_commit], universal_newlines=True).splitlines()[0].split(' ') + parents = subprocess.check_output([GIT, 'show', '-s', '--format=format:%P', prev_commit], universal_newlines=True, encoding='utf8').splitlines()[0].split(' ') for parent in parents: subprocess.call([GIT, 'show', '-s', parent], stdout=sys.stderr) else: @@ -122,25 +122,25 @@ def main(): # Check the Tree-SHA512 if (verify_tree or prev_commit == "") and current_commit not in incorrect_sha512_allowed: tree_hash = tree_sha512sum(current_commit) - if ("Tree-SHA512: {}".format(tree_hash)) not in subprocess.check_output([GIT, 'show', '-s', '--format=format:%B', current_commit], universal_newlines=True).splitlines(): + if ("Tree-SHA512: {}".format(tree_hash)) not in subprocess.check_output([GIT, 'show', '-s', '--format=format:%B', current_commit], universal_newlines=True, encoding='utf8').splitlines(): print("Tree-SHA512 did not match for commit " + current_commit, file=sys.stderr) sys.exit(1) # Merge commits should only have two parents - parents = subprocess.check_output([GIT, 'show', '-s', '--format=format:%P', current_commit], universal_newlines=True).splitlines()[0].split(' ') + parents = subprocess.check_output([GIT, 'show', '-s', '--format=format:%P', current_commit], universal_newlines=True, encoding='utf8').splitlines()[0].split(' ') if len(parents) > 2: print("Commit {} is an octopus merge".format(current_commit), file=sys.stderr) sys.exit(1) # Check that the merge commit is clean - commit_time = int(subprocess.check_output([GIT, 'show', '-s', '--format=format:%ct', current_commit], universal_newlines=True).splitlines()[0]) + commit_time = int(subprocess.check_output([GIT, 'show', '-s', '--format=format:%ct', current_commit], universal_newlines=True, encoding='utf8').splitlines()[0]) check_merge = commit_time > time.time() - args.clean_merge * 24 * 60 * 60 # Only check commits in clean_merge days allow_unclean = current_commit in unclean_merge_allowed if len(parents) == 2 and check_merge and not allow_unclean: - current_tree = subprocess.check_output([GIT, 'show', '--format=%T', current_commit], universal_newlines=True).splitlines()[0] + current_tree = subprocess.check_output([GIT, 'show', '--format=%T', current_commit], universal_newlines=True, encoding='utf8').splitlines()[0] subprocess.call([GIT, 'checkout', '--force', '--quiet', parents[0]]) subprocess.call([GIT, 'merge', '--no-ff', '--quiet', parents[1]], stdout=subprocess.DEVNULL) - recreated_tree = subprocess.check_output([GIT, 'show', '--format=format:%T', 'HEAD'], universal_newlines=True).splitlines()[0] + recreated_tree = subprocess.check_output([GIT, 'show', '--format=format:%T', 'HEAD'], universal_newlines=True, encoding='utf8').splitlines()[0] if current_tree != recreated_tree: print("Merge commit {} is not clean".format(current_commit), file=sys.stderr) subprocess.call([GIT, 'diff', current_commit]) diff --git a/depends/Makefile b/depends/Makefile index 3686aaf1f8..50cc77ddeb 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -5,6 +5,7 @@ WORK_PATH = $(BASEDIR)/work BASE_CACHE ?= $(BASEDIR)/built SDK_PATH ?= $(BASEDIR)/SDKs NO_QT ?= +RAPIDCHECK ?= NO_WALLET ?= NO_UPNP ?= FALLBACK_DOWNLOAD_PATH ?= https://bitcoincore.org/depends-sources @@ -14,7 +15,7 @@ HOST ?= $(BUILD) PATCHES_PATH = $(BASEDIR)/patches BASEDIR = $(CURDIR) HASH_LENGTH:=11 -DOWNLOAD_CONNECT_TIMEOUT:=10 +DOWNLOAD_CONNECT_TIMEOUT:=30 DOWNLOAD_RETRIES:=3 HOST_ID_SALT ?= salt BUILD_ID_SALT ?= salt @@ -93,6 +94,8 @@ qt_packages_$(NO_QT) = $(qt_packages) $(qt_$(host_os)_packages) $(qt_$(host_arch wallet_packages_$(NO_WALLET) = $(wallet_packages) upnp_packages_$(NO_UPNP) = $(upnp_packages) +rapidcheck_packages_$(RAPIDCHECK) = $(rapidcheck_packages) + packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(qt_packages_) $(wallet_packages_) $(upnp_packages_) native_packages += $($(host_arch)_$(host_os)_native_packages) $($(host_os)_native_packages) @@ -100,6 +103,10 @@ ifneq ($(qt_packages_),) native_packages += $(qt_native_packages) endif +ifeq ($(rapidcheck_packages_),) +packages += $(rapidcheck_packages) +endif + all_packages = $(packages) $(native_packages) meta_depends = Makefile funcs.mk builders/default.mk hosts/default.mk hosts/$(host_os).mk builders/$(build_os).mk diff --git a/depends/README.md b/depends/README.md index fd343f7010..693bc36197 100644 --- a/depends/README.md +++ b/depends/README.md @@ -30,29 +30,38 @@ Common `host-platform-triplets` for cross compilation are: No other options are needed, the paths are automatically configured. -Install the required dependencies: Ubuntu & Debian --------------------------------------------------- +### Install the required dependencies: Ubuntu & Debian -For macOS cross compilation: +#### For macOS cross compilation sudo apt-get install curl librsvg2-bin libtiff-tools bsdmainutils cmake imagemagick libcap-dev libz-dev libbz2-dev python-setuptools -For Win32/Win64 cross compilation: +#### For Win32/Win64 cross compilation - see [build-windows.md](../doc/build-windows.md#cross-compilation-for-ubuntu-and-windows-subsystem-for-linux) -For linux (including i386, ARM) cross compilation: +#### For linux (including i386, ARM) cross compilation - sudo apt-get install curl g++-aarch64-linux-gnu g++-4.8-aarch64-linux-gnu gcc-4.8-aarch64-linux-gnu binutils-aarch64-linux-gnu g++-arm-linux-gnueabihf g++-4.8-arm-linux-gnueabihf gcc-4.8-arm-linux-gnueabihf binutils-arm-linux-gnueabihf g++-4.8-multilib gcc-4.8-multilib binutils-gold bsdmainutils +Common linux dependencies: + + sudo apt-get install make automake cmake curl g++-multilib libtool binutils-gold bsdmainutils pkg-config python3 + +For linux ARM cross compilation: + + sudo apt-get install g++-arm-linux-gnueabihf binutils-arm-linux-gnueabihf + +For linux AARCH64 cross compilation: + + sudo apt-get install g++-aarch64-linux-gnu binutils-aarch64-linux-gnu For linux RISC-V 64-bit cross compilation (there are no packages for 32-bit): - sudo apt-get install curl g++-riscv64-linux-gnu binutils-riscv64-linux-gnu + sudo apt-get install g++-riscv64-linux-gnu binutils-riscv64-linux-gnu RISC-V known issue: gcc-7.3.0 and gcc-7.3.1 result in a broken `test_bitcoin` executable (see https://github.com/bitcoin/bitcoin/pull/13543), this is apparently fixed in gcc-8.1.0. -Dependency Options: +### Dependency Options The following can be set when running make: make FOO=bar SOURCES_PATH: downloaded sources will be placed here @@ -63,13 +72,14 @@ The following can be set when running make: make FOO=bar NO_WALLET: Don't download/build/cache libs needed to enable the wallet NO_UPNP: Don't download/build/cache packages needed for enabling upnp DEBUG: disable some optimizations and enable more runtime checking + RAPIDCHECK: build rapidcheck (experimental) HOST_ID_SALT: Optional salt to use when generating host package ids BUILD_ID_SALT: Optional salt to use when generating build package ids If some packages are not built, for example `make NO_WALLET=1`, the appropriate options will be passed to bitcoin's configure. In this case, `--disable-wallet`. -Additional targets: +### Additional targets download: run 'make download' to fetch all sources without building them download-osx: run 'make download-osx' to fetch all sources needed for macOS builds diff --git a/depends/packages/freetype.mk b/depends/packages/freetype.mk index 76b025c463..41e02e2030 100644 --- a/depends/packages/freetype.mk +++ b/depends/packages/freetype.mk @@ -5,7 +5,7 @@ $(package)_file_name=$(package)-$($(package)_version).tar.bz2 $(package)_sha256_hash=3a3bb2c4e15ffb433f2032f50a5b5a92558206822e22bfe8cbe339af4aa82f88 define $(package)_set_vars - $(package)_config_opts=--without-zlib --without-png --disable-static + $(package)_config_opts=--without-zlib --without-png --without-harfbuzz --without-bzip2 --disable-static $(package)_config_opts_linux=--with-pic endef diff --git a/depends/packages/libICE.mk b/depends/packages/libICE.mk deleted file mode 100644 index fc60323b1c..0000000000 --- a/depends/packages/libICE.mk +++ /dev/null @@ -1,23 +0,0 @@ -package=libICE -$(package)_version=1.0.9 -$(package)_download_path=http://xorg.freedesktop.org/releases/individual/lib/ -$(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=8f7032f2c1c64352b5423f6b48a8ebdc339cc63064af34d66a6c9aa79759e202 -$(package)_dependencies=xtrans xproto - -define $(package)_set_vars - $(package)_config_opts=--disable-static --disable-docs --disable-specs --without-xsltproc - $(package)_config_opts_linux=--with-pic -endef - -define $(package)_config_cmds - $($(package)_autoconf) -endef - -define $(package)_build_cmds - $(MAKE) -endef - -define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) install -endef diff --git a/depends/packages/libSM.mk b/depends/packages/libSM.mk deleted file mode 100644 index 0f9307ca76..0000000000 --- a/depends/packages/libSM.mk +++ /dev/null @@ -1,23 +0,0 @@ -package=libSM -$(package)_version=1.2.2 -$(package)_download_path=http://xorg.freedesktop.org/releases/individual/lib/ -$(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=0baca8c9f5d934450a70896c4ad38d06475521255ca63b717a6510fdb6e287bd -$(package)_dependencies=xtrans xproto libICE - -define $(package)_set_vars - $(package)_config_opts=--without-libuuid --without-xsltproc --disable-docs --disable-static - $(package)_config_opts_linux=--with-pic -endef - -define $(package)_config_cmds - $($(package)_autoconf) -endef - -define $(package)_build_cmds - $(MAKE) -endef - -define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) install -endef diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index 5fe6f98da2..38329d16d7 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -5,6 +5,8 @@ qt_packages = qrencode protobuf zlib qt_linux_packages:=qt expat dbus libxcb xcb_proto libXau xproto freetype fontconfig libX11 xextproto libXext xtrans +rapidcheck_packages = rapidcheck + qt_darwin_packages=qt qt_mingw32_packages=qt diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 5286f89c30..dc1d17cd57 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -64,6 +64,7 @@ $(package)_config_opts += -prefix $(host_prefix) $(package)_config_opts += -qt-libpng $(package)_config_opts += -qt-libjpeg $(package)_config_opts += -qt-pcre +$(package)_config_opts += -qt-harfbuzz $(package)_config_opts += -system-zlib $(package)_config_opts += -static $(package)_config_opts += -silent @@ -120,6 +121,7 @@ define $(package)_extract_cmds endef define $(package)_preprocess_cmds + sed -i.old "s|FT_Get_Font_Format|FT_Get_X11_Font_Format|" qtbase/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp && \ sed -i.old "s|updateqm.commands = \$$$$\$$$$LRELEASE|updateqm.commands = $($(package)_extract_dir)/qttools/bin/lrelease|" qttranslations/translations/translations.pro && \ sed -i.old "/updateqm.depends =/d" qttranslations/translations/translations.pro && \ sed -i.old "s/src_plugins.depends = src_sql src_network/src_plugins.depends = src_network/" qtbase/src/src.pro && \ diff --git a/depends/packages/rapidcheck.mk b/depends/packages/rapidcheck.mk new file mode 100644 index 0000000000..19cf1cae2e --- /dev/null +++ b/depends/packages/rapidcheck.mk @@ -0,0 +1,18 @@ +package=rapidcheck +$(package)_version=10fc0cb +$(package)_download_path=https://github.com/MarcoFalke/rapidcheck/archive +$(package)_file_name=$(package)-$($(package)_version).tar.gz +$(package)_sha256_hash=9640926223c00af45bce4c7df8b756b5458a89b2ba74cfe3e404467f13ce26df + +define $(package)_config_cmds + cmake -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=true . +endef + +define $(package)_build_cmds + $(MAKE) && \ + mkdir -p $($(package)_staging_dir)$(host_prefix)/include && \ + cp -a include/* $($(package)_staging_dir)$(host_prefix)/include/ && \ + cp -a extras/boost_test/include/rapidcheck/* $($(package)_staging_dir)$(host_prefix)/include/rapidcheck/ && \ + mkdir -p $($(package)_staging_dir)$(host_prefix)/lib && \ + cp -a librapidcheck.a $($(package)_staging_dir)$(host_prefix)/lib/ +endef diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index d5fd1f39ab..c9068e83a5 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -1,8 +1,8 @@ package=zeromq -$(package)_version=4.2.3 +$(package)_version=4.2.5 $(package)_download_path=https://github.com/zeromq/libzmq/releases/download/v$($(package)_version)/ $(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=8f1e2b2aade4dbfde98d82366d61baef2f62e812530160d2e6d0a5bb24e40bc0 +$(package)_sha256_hash=cc9090ba35713d59bb2f7d7965f877036c49c5558ea0c290b0dcc6f2a17e489f $(package)_patches=0001-fix-build-with-older-mingw64.patch 0002-disable-pthread_set_name_np.patch define $(package)_set_vars diff --git a/depends/patches/zeromq/0001-fix-build-with-older-mingw64.patch b/depends/patches/zeromq/0001-fix-build-with-older-mingw64.patch index a6c508fb8a..b911ac5672 100644 --- a/depends/patches/zeromq/0001-fix-build-with-older-mingw64.patch +++ b/depends/patches/zeromq/0001-fix-build-with-older-mingw64.patch @@ -1,6 +1,6 @@ -From 1a159c128c69a42d90819375c06a39994f3fbfc1 Mon Sep 17 00:00:00 2001 -From: Cory Fields -Date: Tue, 28 Nov 2017 20:33:25 -0500 +From f6866b0f166ad168618aae64c7fbee8775d3eb23 Mon Sep 17 00:00:00 2001 +From: mruddy <6440430+mruddy@users.noreply.github.com> +Date: Sat, 30 Jun 2018 09:44:58 -0400 Subject: [PATCH] fix build with older mingw64 --- @@ -8,10 +8,10 @@ Subject: [PATCH] fix build with older mingw64 1 file changed, 7 insertions(+) diff --git a/src/windows.hpp b/src/windows.hpp -index 99e889d..e69038e 100644 +index 6c3839fd..2c32ec79 100644 --- a/src/windows.hpp +++ b/src/windows.hpp -@@ -55,6 +55,13 @@ +@@ -58,6 +58,13 @@ #include #include #include @@ -23,8 +23,8 @@ index 99e889d..e69038e 100644 +#include +#endif #include - + #if !defined __MINGW32__ --- -2.7.4 +-- +2.17.1 diff --git a/depends/patches/zeromq/0002-disable-pthread_set_name_np.patch b/depends/patches/zeromq/0002-disable-pthread_set_name_np.patch index d220b54f3e..022e311977 100644 --- a/depends/patches/zeromq/0002-disable-pthread_set_name_np.patch +++ b/depends/patches/zeromq/0002-disable-pthread_set_name_np.patch @@ -1,6 +1,6 @@ -From 6e6b47d5ab381c3df3b30bb0b0a6cf210dfb1eba Mon Sep 17 00:00:00 2001 -From: Cory Fields -Date: Mon, 5 Mar 2018 14:22:05 -0500 +From c9bbdd6581d07acfe8971e4bcebe278a3676cf03 Mon Sep 17 00:00:00 2001 +From: mruddy <6440430+mruddy@users.noreply.github.com> +Date: Sat, 30 Jun 2018 09:57:18 -0400 Subject: [PATCH] disable pthread_set_name_np pthread_set_name_np adds a Glibc requirement on >= 2.12. @@ -9,21 +9,21 @@ pthread_set_name_np adds a Glibc requirement on >= 2.12. 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/thread.cpp b/src/thread.cpp -index 4fc59c3e..c3fdfd46 100644 +index a1086b0c..9943f354 100644 --- a/src/thread.cpp +++ b/src/thread.cpp -@@ -220,7 +220,7 @@ void zmq::thread_t::setThreadName(const char *name_) +@@ -307,7 +307,7 @@ void zmq::thread_t::setThreadName (const char *name_) */ if (!name_) return; - +#if 0 #if defined(ZMQ_HAVE_PTHREAD_SETNAME_1) - int rc = pthread_setname_np(name_); - if(rc) return; -@@ -233,6 +233,8 @@ void zmq::thread_t::setThreadName(const char *name_) + int rc = pthread_setname_np (name_); + if (rc) +@@ -323,6 +323,8 @@ void zmq::thread_t::setThreadName (const char *name_) #elif defined(ZMQ_HAVE_PTHREAD_SET_NAME) - pthread_set_name_np(descriptor, name_); + pthread_set_name_np (descriptor, name_); #endif +#endif + return; @@ -31,5 +31,5 @@ index 4fc59c3e..c3fdfd46 100644 #endif -- -2.11.1 +2.17.1 diff --git a/doc/build-osx.md b/doc/build-osx.md index 448918e8cb..56869098fc 100644 --- a/doc/build-osx.md +++ b/doc/build-osx.md @@ -53,7 +53,7 @@ Build Bitcoin Core You can disable the GUI build by passing `--without-gui` to configure. ./autogen.sh - ./configure + ./configure --disable-shared --enable-static make 3. It is recommended to build and run the unit tests: @@ -64,6 +64,17 @@ Build Bitcoin Core make deploy +Disable-wallet mode +-------------------- +When the intention is to run only a P2P node without a wallet, Bitcoin Core may be compiled in +disable-wallet mode with: + + ./configure --disable-wallet + +In this case there is no dependency on Berkeley DB 4.8. + +Mining is also possible in disable-wallet mode using the `getblocktemplate` RPC call. + Running ------- diff --git a/doc/build-unix.md b/doc/build-unix.md index a01ff59fa6..d7987e3218 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -19,7 +19,7 @@ To Build ```bash ./autogen.sh -./configure +./configure --disable-shared --enable-static make make install # optional ``` @@ -47,7 +47,7 @@ Optional dependencies: protobuf | Payments in GUI | Data interchange format used for payment protocol (only needed when GUI enabled) libqrencode | QR codes in GUI | Optional for generating QR codes (only needed when GUI enabled) univalue | Utility | JSON parsing and encoding (bundled version will be used unless --with-system-univalue passed to configure) - libzmq3 | ZMQ notification | Optional, allows generating ZMQ notifications (requires ZMQ version >= 4.x) + libzmq3 | ZMQ notification | Optional, allows generating ZMQ notifications (requires ZMQ version >= 4.0.0) For the versions used, see [dependencies.md](dependencies.md) @@ -70,7 +70,11 @@ tuned to conserve memory with additional CXXFLAGS: Build requirements: - sudo apt-get install build-essential libtool autotools-dev automake pkg-config libssl-dev libevent-dev bsdmainutils python3 libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-test-dev libboost-thread-dev + sudo apt-get install build-essential libtool autotools-dev automake pkg-config bsdmainutils python3 + +Now, you can either build from self-compiled [depends](/depends/README.md) or install the required dependencies: + + sudo apt-get install libssl-dev libevent-dev libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-test-dev libboost-thread-dev BerkeleyDB is required for the wallet. @@ -93,11 +97,11 @@ Optional (see --with-miniupnpc and --enable-upnp-default): sudo apt-get install libminiupnpc-dev -ZMQ dependencies (provides ZMQ API 4.x): +ZMQ dependencies (provides ZMQ API): sudo apt-get install libzmq3-dev -#### Dependencies for the GUI +GUI dependencies: If you want to build bitcoin-qt, make sure that the required packages for Qt development are installed. Qt 5 is necessary to build the GUI. @@ -234,8 +238,7 @@ disable-wallet mode with: In this case there is no dependency on Berkeley DB 4.8. -Mining is also possible in disable-wallet mode, but only using the `getblocktemplate` RPC -call not `getwork`. +Mining is also possible in disable-wallet mode using the `getblocktemplate` RPC call. Additional Configure Flags -------------------------- @@ -252,7 +255,7 @@ This example lists the steps necessary to setup and build a command line only, n git clone https://github.com/bitcoin/bitcoin.git cd bitcoin/ ./autogen.sh - ./configure --disable-wallet --without-gui --without-miniupnpc + ./configure --disable-wallet --without-gui --without-miniupnpc --disable-shared --enable-static make check Note: @@ -279,9 +282,9 @@ To build executables for ARM: cd depends make HOST=arm-linux-gnueabihf NO_QT=1 cd .. + ./autogen.sh ./configure --prefix=$PWD/depends/arm-linux-gnueabihf --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++ make For further documentation on the depends system see [README.md](../depends/README.md) in the depends directory. - diff --git a/doc/build-windows.md b/doc/build-windows.md index 12adadacdc..24849fd155 100644 --- a/doc/build-windows.md +++ b/doc/build-windows.md @@ -122,7 +122,7 @@ Then build using: make HOST=i686-w64-mingw32 cd .. ./autogen.sh # not required when building from tarball - CONFIG_SITE=$PWD/depends/i686-w64-mingw32/share/config.site ./configure --prefix=/ + CONFIG_SITE=$PWD/depends/i686-w64-mingw32/share/config.site ./configure --prefix=/ --disable-shared --enable-static make ## Depends system @@ -133,7 +133,7 @@ Installation ------------- After building using the Windows subsystem it can be useful to copy the compiled -executables to a directory on the windows drive in the same directory structure +executables to a directory on the Windows drive in the same directory structure as they appear in the release `.zip` archive. This can be done in the following way. This will install to `c:\workspace\bitcoin`, for example: diff --git a/doc/dependencies.md b/doc/dependencies.md index 3fc7aecba8..d777aaf66f 100644 --- a/doc/dependencies.md +++ b/doc/dependencies.md @@ -26,5 +26,5 @@ These are the dependencies currently used by Bitcoin Core. You can find instruct | Qt | [5.9.6](https://download.qt.io/official_releases/qt/) | 5.x | No | | | | XCB | | | | | [Yes](https://github.com/bitcoin/bitcoin/blob/master/depends/packages/qt.mk#L87) (Linux only) | | xkbcommon | | | | | [Yes](https://github.com/bitcoin/bitcoin/blob/master/depends/packages/qt.mk#L86) (Linux only) | -| ZeroMQ | [4.2.3](https://github.com/zeromq/libzmq/releases) | | No | | | +| ZeroMQ | [4.2.5](https://github.com/zeromq/libzmq/releases) | 4.0.0 | No | | | | zlib | [1.2.11](https://zlib.net/) | | | | No | diff --git a/doc/descriptors.md b/doc/descriptors.md new file mode 100644 index 0000000000..c23ac06e8f --- /dev/null +++ b/doc/descriptors.md @@ -0,0 +1,124 @@ +# Support for Output Descriptors in Bitcoin Core + +Since Bitcoin Core v0.17, there is support for Output Descriptors in the +`scantxoutset` RPC call. This is a simple language which can be used to +describe collections of output scripts. + +This document describes the language. For the specifics on usage for scanning +the UTXO set, see the `scantxoutset` RPC help. + +## Features + +Output descriptors currently support: +- Pay-to-pubkey scripts (P2PK), through the `pk` function. +- Pay-to-pubkey-hash scripts (P2PKH), through the `pkh` function. +- Pay-to-witness-pubkey-hash scripts (P2WPKH), through the `wpkh` function. +- Pay-to-script-hash scripts (P2SH), through the `sh` function. +- Pay-to-witness-script-hash scripts (P2WSH), through the `wsh` function. +- Multisig scripts, through the `multi` function. +- Any type of supported address through the `addr` function. +- Raw hex scripts through the `raw` function. +- Public keys (compressed and uncompressed) in hex notation, or BIP32 extended pubkeys with derivation paths. + +## Examples + +- `pk(0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798)` represents a P2PK output. +- `pkh(02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5)` represents a P2PKH output. +- `wpkh(02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9)` represents a P2WPKH output. +- `sh(wpkh(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556))` represents a P2SH-P2WPKH output. +- `combo(0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798)` represents a P2PK, P2PKH, P2WPKH, and P2SH-P2WPKH output. +- `sh(wsh(pkh(02e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13)))` represents a (overly complicated) P2SH-P2WSH-P2PKH output. +- `multi(1,022f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4,025cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc)` represents a bare *1-of-2* multisig. +- `sh(multi(2,022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01,03acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe))` represents a P2SH *2-of-2* multisig. +- `wsh(multi(2,03a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7,03774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cb,03d01115d548e7561b15c38f004d734633687cf4419620095bc5b0f47070afe85a))` represents a P2WSH *2-of-3* multisig. +- `sh(wsh(multi(1,03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8,03499fdf9e895e719cfd64e67f07d38e3226aa7b63678949e6e49b241a60e823e4,02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e)))` represents a P2SH-P2WSH *1-of-3* multisig. +- `pk(xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8)` refers to a single P2PK output, using the public key part from the specified xpub. +- `pkh(xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw/1'/2)` refers to a single P2PKH output, using child key *1'/2* of the specified xpub. +- `wsh(multi(1,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/1/0/*,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/1/0/*))` refers to a chain of *1-of-2* P2WSH multisig outputs, using public keys taken from two HD chains with corresponding derivation paths. + +## Reference + +Descriptors consist of several types of expressions. The top level expression is always a `SCRIPT`. + +`SCRIPT` expressions: +- `sh(SCRIPT)` (top level only): P2SH embed the argument. +- `wsh(SCRIPT)` (not inside another 'wsh'): P2WSH embed the argument. +- `pk(KEY)` (anywhere): P2PK output for the given public key. +- `pkh(KEY)` (anywhere): P2PKH output for the given public key (use `addr` if you only know the pubkey hash). +- `wpkh(KEY)` (not inside `wsh`): P2WPKH output for the given compressed pubkey. +- `combo(KEY)` (top level only): an alias for the collection of `pk(KEY)` and `pkh(KEY)`. If the key is compressed, it also includes `wpkh(KEY)` and `sh(wpkh(KEY))`. +- `multi(k,KEY_1,KEY_2,...,KEY_n)` (anywhere): k-of-n multisig script. +- `addr(ADDR)` (top level only): the script which ADDR expands to. +- `raw(HEX)` (top level only): the script whose hex encoding is HEX. + +`KEY` expressions: +- Hex encoded public keys (66 characters starting with `02` or `03`, or 130 characters starting with `04`). + - Inside `wpkh` and `wsh`, only compressed public keys are permitted. +- [WIF](https://en.bitcoin.it/wiki/Wallet_import_format) encoded private keys may be specified instead of the corresponding public key, with the same meaning. +-`xpub` encoded extended public key or `xprv` encoded private key (as defined in [BIP 32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)). + - Followed by zero or more `/NUM` unhardened and `/NUM'` hardened BIP32 derivation steps. + - Optionally followed by a single `/*` or `/*'` final step to denote all (direct) unhardened or hardened children. + - The usage of hardened derivation steps requires providing the private key. + - Instead of a `'`, the suffix `h` can be used to denote hardened derivation. + +`ADDR` expressions are any type of supported address: +- P2PKH addresses (base58, of the form `1...`). Note that P2PKH addresses in descriptors cannot be used for P2PK outputs (use the `pk` function instead). +- P2SH addresses (base58, of the form `3...`, defined in [BIP 13](https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki)). +- Segwit addresses (bech32, of the form `bc1...`, defined in [BIP 173](https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki)). + +## Explanation + +### Single-key scripts + +Many single-key constructions are used in practice, generally including +P2PK, P2PKH, P2WPKH, and P2SH-P2WPKH. Many more combinations are +imaginable, though they may not be optimal: P2SH-P2PK, P2SH-P2PKH, +P2WSH-P2PK, P2WSH-P2PKH, P2SH-P2WSH-P2PK, P2SH-P2WSH-P2PKH. + +To describe these, we model these as functions. The functions `pk` +(P2PK), `pkh` (P2PKH) and `wpkh` (P2WPKH) take as input a public key in +hexadecimal notation (which will be extended later), and return the +corresponding *scriptPubKey*. The functions `sh` (P2SH) and `wsh` (P2WSH) +take as input a script, and return the script describing P2SH and P2WSH +outputs with the input as embedded script. The names of the functions do +not contain "p2" for brevity. + +### Multisig + +Several pieces of software use multi-signature (multisig) scripts based +on Bitcoin's OP_CHECKMULTISIG opcode. To support these, we introduce the +`multi(k,key_1,key_2,...,key_n)` function. It represents a *k-of-n* +multisig policy, where any *k* out of the *n* provided public keys must +sign. + +### BIP32 derived keys and chains + +Most modern wallet software and hardware uses keys that are derived using +BIP32 ("HD keys"). We support these directly by permitting strings +consisting of an extended public key (commonly referred to as an *xpub*) +plus derivation path anywhere a public key is expected. The derivation +path consists of a sequence of 0 or more integers (in the range +*0..231-1*) each optionally followed by `'` or `h`, and +separated by `/` characters. The string may optionally end with the +literal `/*` or `/*'` (or `/*h`) to refer to all unhardened or hardened +child keys instead. + +Whenever a public key is described using a hardened derivation step, the +script cannot be computed without access to the corresponding private +key. + +### Including private keys + +Often it is useful to communicate a description of scripts along with the +necessary private keys. For this reason, anywhere a public key or xpub is +supported, a private key in WIF format or xprv may be provided instead. +This is useful when private keys are necessary for hardened derivation +steps, or for dumping wallet descriptors including private key material. + +### Compatibility with old wallets + +In order to easily represent the sets of scripts currently supported by +existing Bitcoin Core wallets, a convenience function `combo` is +provided, which takes as input a public key, and constructs the P2PK, +P2PKH, P2WPKH, and P2SH-P2WPH scripts for that key. In case the key is +uncompressed, it only constructs P2PK and P2PKH. diff --git a/doc/developer-notes.md b/doc/developer-notes.md index da8384c537..c86648c5b8 100644 --- a/doc/developer-notes.md +++ b/doc/developer-notes.md @@ -439,6 +439,11 @@ General C++ - *Rationale*: This avoids memory and resource leaks, and ensures exception safety +- Use `MakeUnique()` to construct objects owned by `unique_ptr`s + + - *Rationale*: `MakeUnique` is concise and ensures exception safety in complex expressions. + `MakeUnique` is a temporary project local implementation of `std::make_unique` (C++14). + C++ data structures -------------------- @@ -512,7 +517,7 @@ Strings and formatting - *Rationale*: These functions do overflow checking, and avoid pesky locale issues. - Avoid using locale dependent functions if possible. You can use the provided - [`lint-locale-dependence.sh`](/contrib/devtools/lint-locale-dependence.sh) + [`lint-locale-dependence.sh`](/test/lint/lint-locale-dependence.sh) to check for accidental use of locale dependent functions. - *Rationale*: Unnecessary locale dependence can cause bugs that are very tricky to isolate and fix. @@ -700,10 +705,10 @@ Current subtrees include: - Upstream at https://github.com/google/leveldb ; Maintained by Google, but open important PRs to Core to avoid delay. - **Note**: Follow the instructions in [Upgrading LevelDB](#upgrading-leveldb) when - merging upstream changes to the leveldb subtree. + merging upstream changes to the LevelDB subtree. - src/libsecp256k1 - - Upstream at https://github.com/bitcoin-core/secp256k1/ ; actively maintaned by Core contributors. + - Upstream at https://github.com/bitcoin-core/secp256k1/ ; actively maintained by Core contributors. - src/crypto/ctaes - Upstream at https://github.com/bitcoin-core/ctaes ; actively maintained by Core contributors. diff --git a/doc/init.md b/doc/init.md index 239b74e4e1..5778b09d05 100644 --- a/doc/init.md +++ b/doc/init.md @@ -22,7 +22,7 @@ Configuration At a bare minimum, bitcoind requires that the rpcpassword setting be set when running as a daemon. If the configuration file does not exist or this -setting is not set, bitcoind will shutdown promptly after startup. +setting is not set, bitcoind will shut down promptly after startup. This password does not have to be remembered or typed as it is mostly used as a fixed token that bitcoind and client programs read from the configuration diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am index 08ff4d6ac1..9b36319e64 100644 --- a/doc/man/Makefile.am +++ b/doc/man/Makefile.am @@ -8,6 +8,10 @@ if ENABLE_QT dist_man1_MANS+=bitcoin-qt.1 endif -if BUILD_BITCOIN_UTILS - dist_man1_MANS+=bitcoin-cli.1 bitcoin-tx.1 +if BUILD_BITCOIN_CLI + dist_man1_MANS+=bitcoin-cli.1 +endif + +if BUILD_BITCOIN_TX + dist_man1_MANS+=bitcoin-tx.1 endif diff --git a/doc/release-notes-13152.md b/doc/release-notes-13152.md new file mode 100644 index 0000000000..72526f5355 --- /dev/null +++ b/doc/release-notes-13152.md @@ -0,0 +1,4 @@ +New RPC methods +------------ + +- `getnodeaddresses` returns peer addresses known to this node. It may be used to connect to nodes over TCP without using the DNS seeds. \ No newline at end of file diff --git a/doc/release-notes-14282.md b/doc/release-notes-14282.md new file mode 100644 index 0000000000..e6d8e0b70c --- /dev/null +++ b/doc/release-notes-14282.md @@ -0,0 +1,6 @@ +Low-level RPC changes +---------------------- + +`-usehd` was removed in version 0.16. From that version onwards, all new +wallets created are hierarchical deterministic wallets. Version 0.18 makes +specifying `-usehd` invalid config. diff --git a/doc/release-notes.md b/doc/release-notes.md index a24a13408b..2044a50098 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -59,209 +59,18 @@ support versions of macOS older than 10.10. Notable changes =============== -Changed command-line options ----------------------------- - -- `-includeconf=` can be used to include additional configuration files. - Only works inside the `bitcoin.conf` file, not inside included files or from - command-line. Multiple files may be included. Can be disabled from command- - line via `-noincludeconf`. Note that multi-argument commands like - `-includeconf` will override preceding `-noincludeconf`, i.e. - - noincludeconf=1 - includeconf=relative.conf - - as bitcoin.conf will still include `relative.conf`. - -GUI changes ------------ - -- Block storage can be limited under Preferences, in the Main tab. Undoing this setting requires downloading the full blockchain again. This mode is incompatible with -txindex and -rescan. - -RPC changes ------------- - -### Low-level changes - -- The `createrawtransaction` RPC will now accept an array or dictionary (kept for compatibility) for the `outputs` parameter. This means the order of transaction outputs can be specified by the client. -- The `fundrawtransaction` RPC will reject the previously deprecated `reserveChangeKey` option. -- `sendmany` now shuffles outputs to improve privacy, so any previously expected behavior with regards to output ordering can no longer be relied upon. -- The new RPC `testmempoolaccept` can be used to test acceptance of a transaction to the mempool without adding it. -- JSON transaction decomposition now includes a `weight` field which provides - the transaction's exact weight. This is included in REST /rest/tx/ and - /rest/block/ endpoints when in json mode. This is also included in `getblock` - (with verbosity=2), `listsinceblock`, `listtransactions`, and - `getrawtransaction` RPC commands. -- New `fees` field introduced in `getrawmempool`, `getmempoolancestors`, `getmempooldescendants` and - `getmempoolentry` when verbosity is set to `true` with sub-fields `ancestor`, `base`, `modified` - and `descendant` denominated in BTC. This new field deprecates previous fee fields, such as - `fee`, `modifiedfee`, `ancestorfee` and `descendantfee`. -- The new RPC `getzmqnotifications` returns information about active ZMQ - notifications. - -External wallet files ---------------------- - -The `-wallet=` option now accepts full paths instead of requiring wallets -to be located in the -walletdir directory. - -Newly created wallet format +Command line option changes --------------------------- -If `-wallet=` is specified with a path that does not exist, it will now -create a wallet directory at the specified location (containing a wallet.dat -data file, a db.log file, and database/log.?????????? files) instead of just -creating a data file at the path and storing log files in the parent -directory. This should make backing up wallets more straightforward than -before because the specified wallet path can just be directly archived without -having to look in the parent directory for transaction log files. - -For backwards compatibility, wallet paths that are names of existing data files -in the `-walletdir` directory will continue to be accepted and interpreted the -same as before. - -Dynamic loading and creation of wallets ---------------------------------------- - -Previously, wallets could only be loaded or created at startup, by specifying `-wallet` parameters on the command line or in the bitcoin.conf file. It is now possible to load, create and unload wallets dynamically at runtime: - -- Existing wallets can be loaded by calling the `loadwallet` RPC. The wallet can be specified as file/directory basename (which must be located in the `walletdir` directory), or as an absolute path to a file/directory. -- New wallets can be created (and loaded) by calling the `createwallet` RPC. The provided name must not match a wallet file in the `walletdir` directory or the name of a wallet that is currently loaded. -- Loaded wallets can be unloaded by calling the `unloadwallet` RPC. - -This feature is currently only available through the RPC interface. - -Coin selection --------------- -- A new `-avoidpartialspends` flag has been added (default=false). If enabled, the wallet will try to spend UTXO's that point at the same destination - together. This is a privacy increase, as there will no longer be cases where a wallet will inadvertently spend only parts of the coins sent to - the same address (note that if someone were to send coins to that address after it was used, those coins will still be included in future - coin selections). - -Configuration sections for testnet and regtest ----------------------------------------------- - -It is now possible for a single configuration file to set different -options for different networks. This is done by using sections or by -prefixing the option with the network, such as: - - main.uacomment=bitcoin - test.uacomment=bitcoin-testnet - regtest.uacomment=regtest - [main] - mempoolsize=300 - [test] - mempoolsize=100 - [regtest] - mempoolsize=20 - -The `addnode=`, `connect=`, `port=`, `bind=`, `rpcport=`, `rpcbind=` -and `wallet=` options will only apply to mainnet when specified in the -configuration file, unless a network is specified. +The `-enablebip61` command line option (introduced in Bitcoin Core 0.17.0) is +used to toggle sending of BIP 61 reject messages. Reject messages have no use +case on the P2P network and are only logged for debugging by most network +nodes. The option will now by default be off for improved privacy and security +as well as reduced upload usage. The option can explicitly be turned on for +local-network debugging purposes. -'label' and 'account' APIs for wallet -------------------------------------- - -A new 'label' API has been introduced for the wallet. This is intended as a -replacement for the deprecated 'account' API. The 'account' can continue to -be used in V0.17 by starting bitcoind with the '-deprecatedrpc=accounts' -argument, and will be fully removed in V0.18. - -The label RPC methods mirror the account functionality, with the following functional differences: - -- Labels can be set on any address, not just receiving addresses. This functionality was previously only available through the GUI. -- Labels can be deleted by reassigning all addresses using the `setlabel` RPC method. -- There isn't support for sending transactions _from_ a label, or for determining which label a transaction was sent from. -- Labels do not have a balance. - -Here are the changes to RPC methods: - -| Deprecated Method | New Method | Notes | -| :---------------------- | :-------------------- | :-----------| -| `getaccount` | `getaddressinfo` | `getaddressinfo` returns a json object with address information instead of just the name of the account as a string. | -| `getaccountaddress` | n/a | There is no replacement for `getaccountaddress` since labels do not have an associated receive address. | -| `getaddressesbyaccount` | `getaddressesbylabel` | `getaddressesbylabel` returns a json object with the addresses as keys, instead of a list of strings. | -| `getreceivedbyaccount` | `getreceivedbylabel` | _no change in behavior_ | -| `listaccounts` | `listlabels` | `listlabels` does not return a balance or accept `minconf` and `watchonly` arguments. | -| `listreceivedbyaccount` | `listreceivedbylabel` | Both methods return new `label` fields, along with `account` fields for backward compatibility. | -| `move` | n/a | _no replacement_ | -| `sendfrom` | n/a | _no replacement_ | -| `setaccount` | `setlabel` | Both methods now:
  • allow assigning labels to any address, instead of raising an error if the address is not receiving address.
  • delete the previous label associated with an address when the final address using that label is reassigned to a different label, instead of making an implicit `getaccountaddress` call to ensure the previous label still has a receiving address. | - -| Changed Method | Notes | -| :--------------------- | :------ | -| `addmultisigaddress` | Renamed `account` named parameter to `label`. Still accepts `account` for backward compatibility if running with '-deprecatedrpc=accounts'. | -| `getnewaddress` | Renamed `account` named parameter to `label`. Still accepts `account` for backward compatibility. if running with '-deprecatedrpc=accounts' | -| `listunspent` | Returns new `label` fields. `account` field will be returned for backward compatibility if running with '-deprecatedrpc=accounts' | -| `sendmany` | The `account` named parameter has been renamed to `dummy`. If provided, the `dummy` parameter must be set to the empty string, unless running with the `-deprecatedrpc=accounts` argument (in which case functionality is unchanged). | -| `listtransactions` | The `account` named parameter has been renamed to `dummy`. If provided, the `dummy` parameter must be set to the string `*`, unless running with the `-deprecatedrpc=accounts` argument (in which case functionality is unchanged). | -| `getbalance` | `account`, `minconf` and `include_watchonly` parameters are deprecated, and can only be used if running with '-deprecatedrpc=accounts' | - -Low-level RPC changes ---------------------- - -- When bitcoin is not started with any `-wallet=` options, the name of - the default wallet returned by `getwalletinfo` and `listwallets` RPCs is - now the empty string `""` instead of `"wallet.dat"`. If bitcoin is started - with any `-wallet=` options, there is no change in behavior, and the - name of any wallet is just its `` string. -- Passing an empty string (`""`) as the `address_type` parameter to - `getnewaddress`, `getrawchangeaddress`, `addmultisigaddress`, - `fundrawtransaction` RPCs is now an error. Previously, this would fall back - to using the default address type. It is still possible to pass null or leave - the parameter unset to use the default address type. - -- Bare multisig outputs to our keys are no longer automatically treated as - incoming payments. As this feature was only available for multisig outputs for - which you had all private keys in your wallet, there was generally no use for - them compared to single-key schemes. Furthermore, no address format for such - outputs is defined, and wallet software can't easily send to it. These outputs - will no longer show up in `listtransactions`, `listunspent`, or contribute to - your balance, unless they are explicitly watched (using `importaddress` or - `importmulti` with hex script argument). `signrawtransaction*` also still - works for them. - -- The `getwalletinfo` RPC method now returns an `hdseedid` value, which is always the same as the incorrectly-named `hdmasterkeyid` value. `hdmasterkeyid` will be removed in V0.18. -- The `getaddressinfo` RPC method now returns an `hdseedid` value, which is always the same as the incorrectly-named `hdmasterkeyid` value. `hdmasterkeyid` will be removed in V0.18. - -Other API changes ------------------ - -- The `inactivehdmaster` property in the `dumpwallet` output has been corrected to `inactivehdseed` - -### Logging - -- The log timestamp format is now ISO 8601 (e.g. "2018-02-28T12:34:56Z"). - -- When running bitcoind with `-debug` but without `-daemon`, logging to stdout - is now the default behavior. Setting `-printtoconsole=1` no longer implicitly - disables logging to debug.log. Instead, logging to file can be explicitly disabled - by setting `-debuglogfile=0`. - -Transaction index changes -------------------------- - -The transaction index is now built separately from the main node procedure, -meaning the `-txindex` flag can be toggled without a full reindex. If bitcoind -is run with `-txindex` on a node that is already partially or fully synced -without one, the transaction index will be built in the background and become -available once caught up. When switching from running `-txindex` to running -without the flag, the transaction index database will *not* be deleted -automatically, meaning it could be turned back on at a later time without a full -resync. - -Miner block size removed ------------------------- - -The `-blockmaxsize` option for miners to limit their blocks' sizes was -deprecated in V0.15.1, and has now been removed. Miners should use the -`-blockmaxweight` option if they want to limit the weight of their blocks' -weights. - -Python Support --------------- - -Support for Python 2 has been discontinued for all test files and tools. +Example item +------------ Credits ======= diff --git a/doc/release-notes/release-notes-0.16.3.md b/doc/release-notes/release-notes-0.16.3.md new file mode 100644 index 0000000000..2e52d309c2 --- /dev/null +++ b/doc/release-notes/release-notes-0.16.3.md @@ -0,0 +1,88 @@ +Bitcoin Core version 0.16.3 is now available from: + + + +This is a new minor version release, with various bugfixes. + +Please report bugs using the issue tracker at GitHub: + + + +To receive security and update notifications, please subscribe to: + + + +How to Upgrade +============== + +If you are running an older version, shut it down. Wait until it has completely +shut down (which might take a few minutes for older versions), then run the +installer (on Windows) or just copy over `/Applications/Bitcoin-Qt` (on Mac) +or `bitcoind`/`bitcoin-qt` (on Linux). + +The first time you run version 0.15.0 or newer, your chainstate database will be converted to a +new format, which will take anywhere from a few minutes to half an hour, +depending on the speed of your machine. + +Note that the block database format also changed in version 0.8.0 and there is no +automatic upgrade code from before version 0.8 to version 0.15.0 or higher. Upgrading +directly from 0.7.x and earlier without re-downloading the blockchain is not supported. +However, as usual, old wallet versions are still supported. + +Downgrading warning +------------------- + +Wallets created in 0.16 and later are not compatible with versions prior to 0.16 +and will not work if you try to use newly created wallets in older versions. Existing +wallets that were created with older versions are not affected by this. + +Compatibility +============== + +Bitcoin Core is extensively tested on multiple operating systems using +the Linux kernel, macOS 10.8+, and Windows Vista and later. Windows XP is not supported. + +Bitcoin Core should also work on most other Unix-like systems but is not +frequently tested on them. + +Notable changes +=============== + +Denial-of-Service vulnerability +------------------------------- + +A denial-of-service vulnerability (CVE-2018-17144) exploitable by miners has +been discovered in Bitcoin Core versions 0.14.0 up to 0.16.2. It is recommended +to upgrade any of the vulnerable versions to 0.16.3 as soon as possible. + +0.16.3 change log +------------------ + +### Consensus +- #14249 `696b936` Fix crash bug with duplicate inputs within a transaction (TheBlueMatt, sdaftuar) + +### RPC and other APIs +- #13547 `212ef1f` Make `signrawtransaction*` give an error when amount is needed but missing (ajtowns) + +### Miscellaneous +- #13655 `1cdbea7` bitcoinconsensus: invalid flags error should be set to `bitcoinconsensus_err` (afk11) + +### Documentation +- #13844 `11b9dbb` correct the help output for -prune (hebasto) + +Credits +======= + +Thanks to everyone who directly contributed to this release: + +- Anthony Towns +- Hennadii Stepanov +- Matt Corallo +- Suhas Daftuar +- Thomas Kerin +- Wladimir J. van der Laan + +And to those that reported security issues: + +- (anonymous reporter) + diff --git a/doc/release-notes/release-notes-0.17.0.md b/doc/release-notes/release-notes-0.17.0.md new file mode 100644 index 0000000000..418d7ba5f9 --- /dev/null +++ b/doc/release-notes/release-notes-0.17.0.md @@ -0,0 +1,1105 @@ +Bitcoin Core version 0.17.0 is now available from: + + + +This is a new major version release, including new features, various bugfixes +and performance improvements, as well as updated translations. + +Please report bugs using the issue tracker at GitHub: + + + +To receive security and update notifications, please subscribe to: + + + +How to Upgrade +============== + +If you are running an older version, shut it down. Wait until it has completely +shut down (which might take a few minutes for older versions), then run the +installer (on Windows) or just copy over `/Applications/Bitcoin-Qt` (on Mac) +or `bitcoind`/`bitcoin-qt` (on Linux). + +If your node has a txindex, the txindex db will be migrated the first time you run 0.17.0 or newer, which may take up to a few hours. Your node will not be functional until this migration completes. + +The first time you run version 0.15.0 or newer, your chainstate database will be converted to a +new format, which will take anywhere from a few minutes to half an hour, +depending on the speed of your machine. + +Note that the block database format also changed in version 0.8.0 and there is no +automatic upgrade code from before version 0.8 to version 0.15.0. Upgrading +directly from 0.7.x and earlier without redownloading the blockchain is not supported. +However, as usual, old wallet versions are still supported. + +Downgrading warning +------------------- + +The chainstate database for this release is not compatible with previous +releases, so if you run 0.15 and then decide to switch back to any +older version, you will need to run the old release with the `-reindex-chainstate` +option to rebuild the chainstate data structures in the old format. + +If your node has pruning enabled, this will entail re-downloading and +processing the entire blockchain. + +Compatibility +============== + +Bitcoin Core is extensively tested on multiple operating systems using +the Linux kernel, macOS 10.10+, and Windows 7 and newer (Windows XP is not supported). + +Bitcoin Core should also work on most other Unix-like systems but is not +frequently tested on them. + +From 0.17.0 onwards macOS <10.10 is no longer supported. 0.17.0 is built using Qt 5.9.x, which doesn't +support versions of macOS older than 10.10. + +Known issues +============ + +- Upgrading from 0.13.0 or older currently results in memory blow-up during the roll-back of blocks to the SegWit activation point. In these cases, a full `-reindex` is necessary. + +- The GUI suffers from visual glitches in the new MacOS dark mode. This has to do with our Qt theme handling and is not a new problem in 0.17.0, but is expected to be resolved in 0.17.1. + +Notable changes +=============== + +Changed configuration options +----------------------------- + +- `-includeconf=` can be used to include additional configuration files. + Only works inside the `bitcoin.conf` file, not inside included files or from + command-line. Multiple files may be included. Can be disabled from command- + line via `-noincludeconf`. Note that multi-argument commands like + `-includeconf` will override preceding `-noincludeconf`, i.e. + ``` + noincludeconf=1 + includeconf=relative.conf + ``` + + as bitcoin.conf will still include `relative.conf`. + +GUI changes +----------- + +- Block storage can be limited under Preferences, in the Main tab. Undoing this setting requires downloading the full blockchain again. This mode is incompatible with -txindex and -rescan. + +External wallet files +--------------------- + +The `-wallet=` option now accepts full paths instead of requiring wallets +to be located in the -walletdir directory. + +Newly created wallet format +--------------------------- + +If `-wallet=` is specified with a path that does not exist, it will now +create a wallet directory at the specified location (containing a wallet.dat +data file, a db.log file, and database/log.?????????? files) instead of just +creating a data file at the path and storing log files in the parent +directory. This should make backing up wallets more straightforward than +before because the specified wallet path can just be directly archived without +having to look in the parent directory for transaction log files. + +For backwards compatibility, wallet paths that are names of existing data files +in the `-walletdir` directory will continue to be accepted and interpreted the +same as before. + +Dynamic loading and creation of wallets +--------------------------------------- + +Previously, wallets could only be loaded or created at startup, by specifying `-wallet` parameters on the command line or in the bitcoin.conf file. It is now possible to load, create and unload wallets dynamically at runtime: + +- Existing wallets can be loaded by calling the `loadwallet` RPC. The wallet can be specified as file/directory basename (which must be located in the `walletdir` directory), or as an absolute path to a file/directory. +- New wallets can be created (and loaded) by calling the `createwallet` RPC. The provided name must not match a wallet file in the `walletdir` directory or the name of a wallet that is currently loaded. +- Loaded wallets can be unloaded by calling the `unloadwallet` RPC. + +This feature is currently only available through the RPC interface. + +Coin selection +-------------- + +### Partial spend avoidance + +When an address is paid multiple times the coins from those separate payments can be spent separately which hurts privacy due to linking otherwise separate addresses. A new `-avoidpartialspends` flag has been added (default=false). If enabled, the wallet will always spend existing UTXO to the same address together even if it results in higher fees. If someone were to send coins to an address after it was used, those coins will still be included in future coin selections. + +Configuration sections for testnet and regtest +---------------------------------------------- + +It is now possible for a single configuration file to set different +options for different networks. This is done by using sections or by +prefixing the option with the network, such as: + + main.uacomment=bitcoin + test.uacomment=bitcoin-testnet + regtest.uacomment=regtest + [main] + mempoolsize=300 + [test] + mempoolsize=100 + [regtest] + mempoolsize=20 + +If the following options are not in a section, they will only apply to mainnet: +`addnode=`, `connect=`, `port=`, `bind=`, `rpcport=`, `rpcbind=` and `wallet=`. +The options to choose a network (`regtest=` and `testnet=`) must be specified +outside of sections. + +'label' and 'account' APIs for wallet +------------------------------------- + +A new 'label' API has been introduced for the wallet. This is intended as a +replacement for the deprecated 'account' API. The 'account' can continue to +be used in V0.17 by starting bitcoind with the '-deprecatedrpc=accounts' +argument, and will be fully removed in V0.18. + +The label RPC methods mirror the account functionality, with the following functional differences: + +- Labels can be set on any address, not just receiving addresses. This functionality was previously only available through the GUI. +- Labels can be deleted by reassigning all addresses using the `setlabel` RPC method. +- There isn't support for sending transactions _from_ a label, or for determining which label a transaction was sent from. +- Labels do not have a balance. + +Here are the changes to RPC methods: + +| Deprecated Method | New Method | Notes | +| :---------------------- | :-------------------- | :-----------| +| `getaccount` | `getaddressinfo` | `getaddressinfo` returns a json object with address information instead of just the name of the account as a string. | +| `getaccountaddress` | n/a | There is no replacement for `getaccountaddress` since labels do not have an associated receive address. | +| `getaddressesbyaccount` | `getaddressesbylabel` | `getaddressesbylabel` returns a json object with the addresses as keys, instead of a list of strings. | +| `getreceivedbyaccount` | `getreceivedbylabel` | _no change in behavior_ | +| `listaccounts` | `listlabels` | `listlabels` does not return a balance or accept `minconf` and `watchonly` arguments. | +| `listreceivedbyaccount` | `listreceivedbylabel` | Both methods return new `label` fields, along with `account` fields for backward compatibility. | +| `move` | n/a | _no replacement_ | +| `sendfrom` | n/a | _no replacement_ | +| `setaccount` | `setlabel` | Both methods now:
    • allow assigning labels to any address, instead of raising an error if the address is not receiving address.
    • delete the previous label associated with an address when the final address using that label is reassigned to a different label, instead of making an implicit `getaccountaddress` call to ensure the previous label still has a receiving address. | + +| Changed Method | Notes | +| :--------------------- | :------ | +| `addmultisigaddress` | Renamed `account` named parameter to `label`. Still accepts `account` for backward compatibility if running with '-deprecatedrpc=accounts'. | +| `getnewaddress` | Renamed `account` named parameter to `label`. Still accepts `account` for backward compatibility. if running with '-deprecatedrpc=accounts' | +| `listunspent` | Returns new `label` fields. `account` field will be returned for backward compatibility if running with '-deprecatedrpc=accounts' | +| `sendmany` | The `account` named parameter has been renamed to `dummy`. If provided, the `dummy` parameter must be set to the empty string, unless running with the `-deprecatedrpc=accounts` argument (in which case functionality is unchanged). | +| `listtransactions` | The `account` named parameter has been renamed to `dummy`. If provided, the `dummy` parameter must be set to the string `*`, unless running with the `-deprecatedrpc=accounts` argument (in which case functionality is unchanged). | +| `getbalance` | `account`, `minconf` and `include_watchonly` parameters are deprecated, and can only be used if running with '-deprecatedrpc=accounts' | + +BIP 174 Partially Signed Bitcoin Transactions support +----------------------------------------------------- + +[BIP 174 PSBT](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) is an interchange format for Bitcoin transactions that are not fully signed +yet, together with relevant metadata to help entities work towards signing it. +It is intended to simplify workflows where multiple parties need to cooperate to +produce a transaction. Examples include hardware wallets, multisig setups, and +[CoinJoin](https://bitcointalk.org/?topic=279249) transactions. + +### Overall workflow + +Overall, the construction of a fully signed Bitcoin transaction goes through the +following steps: + +- A **Creator** proposes a particular transaction to be created. He constructs + a PSBT that contains certain inputs and outputs, but no additional metadata. +- For each input, an **Updater** adds information about the UTXOs being spent by + the transaction to the PSBT. +- A potentially other Updater adds information about the scripts and public keys + involved in each of the inputs (and possibly outputs) of the PSBT. +- **Signers** inspect the transaction and its metadata to decide whether they + agree with the transaction. They can use amount information from the UTXOs + to assess the values and fees involved. If they agree, they produce a + partial signature for the inputs for which they have relevant key(s). +- A **Finalizer** is run for each input to convert the partial signatures and + possibly script information into a final `scriptSig` and/or `scriptWitness`. +- An **Extractor** produces a valid Bitcoin transaction (in network format) + from a PSBT for which all inputs are finalized. + +Generally, each of the above (excluding Creator and Extractor) will simply +add more and more data to a particular PSBT. In a naive workflow, they all have +to operate sequentially, passing the PSBT from one to the next, until the +Extractor can convert it to a real transaction. In order to permit parallel +operation, **Combiners** can be employed which merge metadata from different +PSBTs for the same unsigned transaction. + +The names above in bold are the names of the roles defined in BIP174. They're +useful in understanding the underlying steps, but in practice, software and +hardware implementations will typically implement multiple roles simultaneously. + +### RPCs + +- **`converttopsbt` (Creator)** is a utility RPC that converts an + unsigned raw transaction to PSBT format. It ignores existing signatures. +- **`createpsbt` (Creator)** is a utility RPC that takes a list of inputs and + outputs and converts them to a PSBT with no additional information. It is + equivalent to calling `createrawtransaction` followed by `converttopsbt`. +- **`walletcreatefundedpsbt` (Creator, Updater)** is a wallet RPC that creates a + PSBT with the specified inputs and outputs, adds additional inputs and change + to it to balance it out, and adds relevant metadata. In particular, for inputs + that the wallet knows about (counting towards its normal or watch-only + balance), UTXO information will be added. For outputs and inputs with UTXO + information present, key and script information will be added which the wallet + knows about. It is equivalent to running `createrawtransaction`, followed by + `fundrawtransaction`, and `converttopsbt`. +- **`walletprocesspsbt` (Updater, Signer, Finalizer)** is a wallet RPC that takes as + input a PSBT, adds UTXO, key, and script data to inputs and outputs that miss + it, and optionally signs inputs. Where possible it also finalizes the partial + signatures. +- **`finalizepsbt` (Finalizer, Extractor)** is a utility RPC that finalizes any + partial signatures, and if all inputs are finalized, converts the result to a + fully signed transaction which can be broadcast with `sendrawtransaction`. +- **`combinepsbt` (Combiner)** is a utility RPC that implements a Combiner. It + can be used at any point in the workflow to merge information added to + different versions of the same PSBT. In particular it is useful to combine the + output of multiple Updaters or Signers. +- **`decodepsbt`** is a diagnostic utility RPC which will show all information in + a PSBT in human-readable form, as well as compute its eventual fee if known. + +Upgrading non-HD wallets to HD wallets +-------------------------------------- + +Since Bitcoin Core 0.13.0, creating new BIP 32 Hierarchical Deterministic wallets has been supported by Bitcoin Core but old non-HD wallets could not be upgraded to HD. Now non-HD wallets can be upgraded to HD using the `-upgradewallet` command line option. This upgrade will result in the all keys in the keypool being marked as used and a new keypool generated. **A new backup must be made when this upgrade is performed.** + +Additionally, `-upgradewallet` can be used to upgraded from a non-split HD chain (all keys generated with `m/0'/0'/i'`) to a split HD chain (receiving keys generated with `'m/0'/0'/i'` and change keys generated with `m'/0'/1'/i'`). When this upgrade occurs, all keys already in the keypool will remain in the keypool to be used until all keys from before the upgrade are exhausted. This is to avoid issues with backups and downgrades when some keys may come from the change key keypool. Users can begin using the new split HD chain keypools by using the `newkeypool` RPC to mark all keys in the keypool as used and begin using a new keypool generated from the split HD chain. + +HD Master key rotation +---------------------- + +A new RPC, `sethdseed`, has been introduced which allows users to set a new HD seed or set their own HD seed. This allows for a new HD seed to be used. **A new backup must be made when a new HD seed is set.** + +Low-level RPC changes +--------------------- + +- The new RPC `scantxoutset` can be used to scan the UTXO set for entries + that match certain output descriptors. Refer to the [output descriptors + reference documentation](/doc/descriptors.md) for more details. This call + is similar to `listunspent` but does not use a wallet, meaning that the + wallet can be disabled at compile or run time. This call is experimental, + as such, is subject to changes or removal in future releases. + +- The `createrawtransaction` RPC will now accept an array or dictionary (kept for compatibility) for the `outputs` parameter. This means the order of transaction outputs can be specified by the client. +- The `fundrawtransaction` RPC will reject the previously deprecated `reserveChangeKey` option. +- `sendmany` now shuffles outputs to improve privacy, so any previously expected behavior with regards to output ordering can no longer be relied upon. +- The new RPC `testmempoolaccept` can be used to test acceptance of a transaction to the mempool without adding it. +- JSON transaction decomposition now includes a `weight` field which provides + the transaction's exact weight. This is included in REST /rest/tx/ and + /rest/block/ endpoints when in json mode. This is also included in `getblock` + (with verbosity=2), `listsinceblock`, `listtransactions`, and + `getrawtransaction` RPC commands. +- New `fees` field introduced in `getrawmempool`, `getmempoolancestors`, `getmempooldescendants` and + `getmempoolentry` when verbosity is set to `true` with sub-fields `ancestor`, `base`, `modified` + and `descendant` denominated in BTC. This new field deprecates previous fee fields, such as + `fee`, `modifiedfee`, `ancestorfee` and `descendantfee`. +- The new RPC `getzmqnotifications` returns information about active ZMQ + notifications. +- When bitcoin is not started with any `-wallet=` options, the name of + the default wallet returned by `getwalletinfo` and `listwallets` RPCs is + now the empty string `""` instead of `"wallet.dat"`. If bitcoin is started + with any `-wallet=` options, there is no change in behavior, and the + name of any wallet is just its `` string. +- Passing an empty string (`""`) as the `address_type` parameter to + `getnewaddress`, `getrawchangeaddress`, `addmultisigaddress`, + `fundrawtransaction` RPCs is now an error. Previously, this would fall back + to using the default address type. It is still possible to pass null or leave + the parameter unset to use the default address type. + +- Bare multisig outputs to our keys are no longer automatically treated as + incoming payments. As this feature was only available for multisig outputs for + which you had all private keys in your wallet, there was generally no use for + them compared to single-key schemes. Furthermore, no address format for such + outputs is defined, and wallet software can't easily send to it. These outputs + will no longer show up in `listtransactions`, `listunspent`, or contribute to + your balance, unless they are explicitly watched (using `importaddress` or + `importmulti` with hex script argument). `signrawtransaction*` also still + works for them. + +- The `getwalletinfo` RPC method now returns an `hdseedid` value, which is always the same as the incorrectly-named `hdmasterkeyid` value. `hdmasterkeyid` will be removed in V0.18. +- The `getaddressinfo` RPC method now returns an `hdseedid` value, which is always the same as the incorrectly-named `hdmasterkeyid` value. `hdmasterkeyid` will be removed in V0.18. + +- Parts of the `validateaddress` RPC method have been deprecated and moved to + `getaddressinfo`. Clients must transition to using `getaddressinfo` to access + this information before upgrading to v0.18. The following deprecated fields + have moved to `getaddressinfo` and will only be shown with + `-deprecatedrpc=validateaddress`: `ismine`, `iswatchonly`, `script`, `hex`, + `pubkeys`, `sigsrequired`, `pubkey`, `addresses`, `embedded`, `iscompressed`, + `account`, `timestamp`, `hdkeypath`, `hdmasterkeyid`. +- `signrawtransaction` is deprecated and will be fully removed in v0.18. To use + `signrawtransaction` in v0.17, restart bitcoind with + `-deprecatedrpc=signrawtransaction`. Projects should transition to using + `signrawtransactionwithkey` and `signrawtransactionwithwallet` before + upgrading to v0.18. + +Other API changes +----------------- + +- The `inactivehdmaster` property in the `dumpwallet` output has been corrected to `inactivehdseed` + +### Logging + +- The log timestamp format is now ISO 8601 (e.g. "2018-02-28T12:34:56Z"). + +- When running bitcoind with `-debug` but without `-daemon`, logging to stdout + is now the default behavior. Setting `-printtoconsole=1` no longer implicitly + disables logging to debug.log. Instead, logging to file can be explicitly disabled + by setting `-debuglogfile=0`. + +Transaction index changes +------------------------- + +The transaction index is now built separately from the main node procedure, +meaning the `-txindex` flag can be toggled without a full reindex. If bitcoind +is run with `-txindex` on a node that is already partially or fully synced +without one, the transaction index will be built in the background and become +available once caught up. When switching from running `-txindex` to running +without the flag, the transaction index database will *not* be deleted +automatically, meaning it could be turned back on at a later time without a full +resync. + +Miner block size removed +------------------------ + +The `-blockmaxsize` option for miners to limit their blocks' sizes was +deprecated in V0.15.1, and has now been removed. Miners should use the +`-blockmaxweight` option if they want to limit the weight of their blocks. + +Python Support +-------------- + +Support for Python 2 has been discontinued for all test files and tools. + +0.17.0 change log +================= + +### Consensus +- #12204 `3fa24bb` Fix overly eager BIP30 bypass (morcos) + +### Policy +- #12568 `ed6ae80` Allow dustrelayfee to be set to zero (luke-jr) +- #13120 `ca2a233` Treat segwit as always active (MarcoFalke) +- #13096 `062738c` Fix `MAX_STANDARD_TX_WEIGHT` check (jl2012) + +### Mining +- #12693 `df529dc` Remove unused variable in SortForBlock (drewx2) +- #12448 `84efa9a` Interrupt block generation on shutdown request (promag) + +### Block and transaction handling +- #12225 `67447ba` Mempool cleanups (sdaftuar) +- #12356 `fd65937` Fix 'mempool min fee not met' debug output (Empact) +- #12287 `bf3353d` Optimise lock behaviour for GuessVerificationProgress() (jonasschnelli) +- #11889 `47a7666` Drop extra script variable in ProduceSignature (ryanofsky) +- #11880 `d59b8d6` Stop special-casing phashBlock handling in validation for TBV (TheBlueMatt) +- #12431 `947c25e` Only call NotifyBlockTip when chainActive changes (jamesob) +- #12653 `534b8fa` Allow to optional specify the directory for the blocks storage (jonasschnelli) +- #12172 `3b62a91` Bugfix: RPC: savemempool: Don't save until LoadMempool() is finished (jtimon) +- #12167 `88430cb` Make segwit failure due to `CLEANSTACK` violation return a `SCRIPT_ERR_CLEANSTACK` error code (maaku) +- #12561 `24133b1` Check for block corruption in ConnectBlock() (sdaftuar) +- #11617 `1b5723e` Avoid lock: Call FlushStateToDisk(…) regardless of fCheckForPruning (practicalswift) +- #11739 `0a8b7b4` Enforce `SCRIPT_VERIFY_P2SH` and `SCRIPT_VERIFY_WITNESS` from genesis (sdaftuar) +- #12885 `a49381d` Reduce implementation code inside CScript (sipa) +- #13032 `34dd1a6` Output values for "min relay fee not met" error (kristapsk) +- #13033 `a07e8ca` Build txindex in parallel with validation (jimpo) +- #13080 `66cc47b` Add compile time checking for ::mempool.cs runtime locking assertions (practicalswift) +- #13185 `08c1caf` Bugfix: the end of a reorged chain is invalid when connect fails (sipa) +- #11689 `0264836` Fix missing locking in CTxMemPool::check(…) and CTxMemPool::setSanityCheck(…) (practicalswift) +- #13011 `3c2a41a` Cache witness hash in CTransaction (MarcoFalke) +- #13191 `0de7cc8` Specialized double-SHA256 with 64 byte inputs with SSE4.1 and AVX2 (sipa) +- #13243 `ea263e1` Make reusable base class for auxiliary indices (jimpo) +- #13393 `a607d23` Enable double-SHA256-for-64-byte code on 32-bit x86 (sipa) +- #13428 `caabdea` validation: check the specified number of blocks (off-by-one) (kallewoof) +- #13438 `450055b` Improve coverage of SHA256 SelfTest code (sipa) +- #13431 `954f4a9` validation: count blocks correctly for check level < 3 (kallewoof) +- #13386 `3a3eabe` SHA256 implementations based on Intel SHA Extensions (sipa) +- #11658 `9a1ad2c` During IBD, when doing pruning, prune 10% extra to avoid pruning again soon after (luke-jr) +- #13794 `8ce55df` chainparams: Update with data from assumed valid chain (MarcoFalke) +- #13527 `e7ea858` Remove promiscuousmempoolflags (MarcoFalke) + +### P2P protocol and network code +- #12342 `eaeaa2d` Extend #11583 ("Do not make it trivial for inbound peers to generate log entries") to include "version handshake timeout" message (clemtaylor) +- #12218 `9a32114` Move misbehaving logging to net logging category (laanwj) +- #10387 `5c2aff8` Eventually connect to `NODE_NETWORK_LIMITED` peers (jonasschnelli) +- #9037 `a36834f` Add test-before-evict discipline to addrman (EthanHeilman) +- #12622 `e1d6e2a` Correct addrman logging (laanwj) +- #11962 `0a01843` add seed.bitcoin.sprovoost.nl to DNS seeds (Sjors) +- #12569 `23e7fe8` Increase signal-to-noise ratio in debug.log by adjusting log level when logging failed non-manual connect():s (practicalswift) +- #12855 `c199869` Minor accumulated cleanups (tjps) +- #13153 `ef46c99` Add missing newlines to debug logging (laanwj) +- #13162 `a174702` Don't incorrectly log that REJECT messages are unknown (jnewbery) +- #13151 `7f4db9a` Serve blocks directly from disk when possible (laanwj) +- #13134 `70d3541` Add option `-enablebip61` to configure sending of BIP61 notifications (laanwj) +- #13532 `7209fec` Log warning when deprecated network name 'tor' is used (wodry) +- #13615 `172f984` Remove unused interrupt from SendMessages (fanquake) +- #13417 `1e90862` Tighten scope in `net_processing` (skeees) +- #13298 `f8d470e` Bucketing INV delays (1 bucket) for incoming connections to hide tx time (naumenkogs) +- #13672 `0d8d6be` Modified `in_addr6` cast in CConman class to work with msvc (sipsorcery) +- #11637 `c575260` Remove dead service bits code (MarcoFalke) +- #13212 `a6f00ce` Fixed a race condition when disabling the network (lmanners) +- #13656 `1211b15` Remove the boost/algorithm/string/predicate.hpp dependency (251Labs) +- #13423 `f58674a` Thread safety annotations in `net_processing` (skeees) +- #13776 `7d36237` Add missing verification of IPv6 address in CNetAddr::GetIn6Addr(…) (practicalswift) +- #13907 `48bf8ff` Introduce a maximum size for locators (gmaxwell) +- #13951 `8a9ffec` Hardcoded seeds update pre-0.17 branch (laanwj) + +### Wallet +- #12330 `2a30e67` Reduce scope of `cs_main` and `cs_wallet` locks in listtransactions (promag) +- #12298 `a1ffddb` Refactor HaveKeys to early return on false result (promag) +- #12282 `663911e` Disallow abandon of conflicted txes (MarcoFalke) +- #12333 `d405bee` Make CWallet::ListCoins atomic (promag) +- #12296 `8e6f9f4` Only fee-bump non-conflicted/non-confirmed txes (MarcoFalke) +- #11866 `6bb9c13` Do not un-mark fInMempool on wallet txn if ATMP fails (TheBlueMatt) +- #11882 `987a809` Disable default fallbackfee on mainnet (jonasschnelli) +- #9991 `4ca7c1e` listreceivedbyaddress Filter Address (NicolasDorier) +- #11687 `98bc27f` External wallet files (ryanofsky) +- #12658 `af88094` Sanitize some wallet serialization (sipa) +- #9680 `6acd870` Unify CWalletTx construction (ryanofsky) +- #10637 `e057589` Coin Selection with Murch's algorithm (achow101, Xekyo) +- #12408 `c39dd2e` Change output type globals to members (MarcoFalke) +- #12694 `9552dfb` Actually disable BnB when there are preset inputs (achow101) +- #11536 `cead84b` Rename account to label where appropriate (ryanofsky) +- #12709 `02b7e83` shuffle sendmany recipients ordering (instagibbs) +- #12699 `c948dc8` Shuffle transaction inputs before signing (instagibbs) +- #10762 `6d53663` Remove Wallet dependencies from init.cpp (jnewbery) +- #12857 `821980c` Avoid travis lint-include-guards error (ken2812221) +- #12702 `dab0d68` importprivkey: hint about importmulti (kallewoof) +- #12836 `9abdb7c` Make WalletInitInterface and DummyWalletInit private, fix nullptr deref (promag) +- #12785 `215158a` Initialize `m_last_block_processed` to nullptr (practicalswift) +- #12932 `8d651ae` Remove redundant lambda function arg in handleTransactionChanged (laanwj) +- #12749 `a84b056` feebumper: discard change outputs below discard rate (instagibbs) +- #12892 `9b3370d` introduce 'label' API for wallet (jnewbery) +- #12925 `6d3de17` Logprint the start of a rescan (jonasschnelli) +- #12888 `39439e5` debug log number of unknown wallet records on load (instagibbs) +- #12977 `434150a` Refactor `g_wallet_init_interface` to const reference (promag) +- #13017 `65d7083` Add wallets management functions (promag) +- #12953 `d1d54ae` Deprecate accounts (jnewbery) +- #12909 `476cb35` Make fee settings to be non-static members (MarcoFalke) +- #13002 `487dcbe` Do not treat bare multisig outputs as IsMine unless watched (sipa) +- #13028 `783bb64` Make vpwallets usage thread safe (promag) +- #12507 `2afdc29` Interrupt rescan on shutdown request (promag) +- #12729 `979150b` Get rid of ambiguous OutputType::NONE value (ryanofsky) +- #13079 `5778d44` Fix rescanblockchain rpc to properly report progress (Empact) +- #12560 `e03c0db` Upgrade path for non-HD wallets to HD (achow101) +- #13161 `7cc1bd3` Reset BerkeleyDB handle after connection fails (real-or-random) +- #13081 `0dec5b5` Add compile time checking for `cs_wallet` runtime locking assertions (practicalswift) +- #13127 `19a3a9e` Add Clang thread safety annotations for variables guarded by `cs_db` (practicalswift) +- #10740 `4cfe17c` `loadwallet` RPC - load wallet at runtime (jnewbery) +- #12924 `6738813` Fix hdmaster-key / seed-key confusion (scripted diff) (jnewbery) +- #13297 `d82c5d1` Fix incorrect comment for DeriveNewSeed (jnewbery) +- #13063 `6378eef` Use shared pointer to retain wallet instance (promag) +- #13142 `56fe3dc` Separate IsMine from solvability (sipa) +- #13194 `fd96d54` Remove template matching and pseudo opcodes (sipa) +- #13252 `c4cc8d9` Refactor ReserveKeyFromKeyPool for safety (Empact) +- #13058 `343d4e4` `createwallet` RPC - create new wallet at runtime (jnewbery) +- #13351 `2140f6c` Prevent segfault when sending to unspendable witness (MarcoFalke) +- #13060 `3f0f394` Remove getlabeladdress RPC (jnewbery) +- #13111 `000abbb` Add unloadwallet RPC (promag) +- #13160 `868cf43` Unlock spent outputs (promag) +- #13498 `f54f373` Fixups from account API deprecation (jnewbery) +- #13491 `61a044a` Improve handling of INVALID in IsMine (sipa) +- #13425 `028b0d9` Moving final scriptSig construction from CombineSignatures to ProduceSignature (PSBT signer logic) (achow101) +- #13564 `88a15eb` loadwallet shouldn't create new wallets (jnewbery) +- #12944 `619cd29` ScanforWalletTransactions should mark input txns as dirty (instagibbs) +- #13630 `d6b2235` Drop unused pindexRet arg to CMerkleTx::GetDepthInMainChain (Empact) +- #13566 `ad552a5` Fix get balance (jnewbery) +- #13500 `4a3e8c5` Decouple wallet version from client version (achow101) +- #13712 `aba2e66` Fix non-determinism in ParseHDKeypath(…). Avoid using an uninitialized variable in path calculation (practicalswift) +- #9662 `6b6e854` Add createwallet "disableprivatekeys" option: a sane mode for watchonly-wallets (jonasschnelli) +- #13683 `e8c7434` Introduce assertion to document the assumption that cache and cache_used are always set in tandem (practicalswift) +- #12257 `5f7575e` Use destination groups instead of coins in coin select (kallewoof) +- #13773 `89a116d` Fix accidental use of the comma operator (practicalswift) +- #13805 `c88529a` Correctly limit output group size (sdaftuar) +- #12992 `26f59f5` Add wallet name to log messages (PierreRochard) +- #13667 `b81a8a5` Fix backupwallet for multiwallets (domob1812) +- #13657 `51c693d` assert to ensure accuracy of CMerkleTx::GetBlocksToMaturity (Empact) +- #13812 `9d86aad` sum ancestors rather than taking max in output groups (kallewoof) +- #13876 `8eb9870` Catch `filesystem_error` and raise `InitError` (MarcoFalke) +- #13808 `13d51a2` shuffle coins before grouping, where warranted (kallewoof) +- #13666 `2115cba` Always create signatures with Low R values (achow101) +- #13917 `0333914` Additional safety checks in PSBT signer (sipa) +- #13968 `65e7a8b` couple of walletcreatefundedpsbt fixes (instagibbs) +- #14055 `2307a6e` fix walletcreatefundedpsbt deriv paths, add test (instagibbs) + +### RPC and other APIs +- #12336 `3843780` Remove deprecated rpc options (jnewbery) +- #12193 `5dc00f6` Consistently use UniValue.pushKV instead of push_back(Pair()) (karel-3d) (MarcoFalke) +- #12409 `0cc45ed` Reject deprecated reserveChangeKey in fundrawtransaction (MarcoFalke) +- #10583 `8a98dfe` Split part of validateaddress into getaddressinfo (achow101) +- #10579 `ffc6e48` Split signrawtransaction into wallet and non-wallet RPC command (achow101) +- #12494 `e4ffcac` Declare CMutableTransaction a struct in rawtransaction.h (Empact) +- #12503 `0e26591` createmultisig no longer takes addresses (instagibbs) +- #12083 `228b086` Improve getchaintxstats test coverage (promag) +- #12479 `cd5e438` Add child transactions to getrawmempool verbose output (conscott) +- #11872 `702e8b7` createrawtransaction: Accept sorted outputs (MarcoFalke) +- #12700 `ebdf84c` Document RPC method aliasing (ryanofsky) +- #12727 `8ee5c7b` Remove unreachable help conditions in rpcwallet.cpp (lutangar) +- #12778 `b648974` Add username and ip logging for RPC method requests (GabrielDav) +- #12717 `ac898b6` rest: Handle utxo retrieval when ignoring the mempool (romanz) +- #12787 `cd99e5b` Adjust ifdef to avoid unreachable code (practicalswift) +- #11742 `18815b4` Add testmempoolaccept (MarcoFalke) +- #12942 `fefb817` Drop redundant testing of signrawtransaction prevtxs args (Empact) +- #11200 `5f2a399` Allow for aborting rescans in the GUI (achow101) +- #12791 `3a8a4dc` Expose a transaction's weight via RPC (TheBlueMatt) +- #12436 `6e67754` Adds a functional test to validate the transaction version number in the RPC output (251Labs) +- #12240 `6f8b345` Introduced a new `fees` structure that aggregates all sub-field fee types denominated in BTC (mryandao) +- #12321 `eac067a` p2wsh and p2sh-p2wsh address in decodescript (fivepiece) +- #13090 `17266a1` Remove Safe mode (achow101, laanwj) +- #12639 `7eb7076` Reduce `cs_main` lock in listunspent (promag) +- #10267 `7b966d9` New -includeconf argument for including external configuration files (kallewoof) +- #10757 `b9551d3` Introduce getblockstats to plot things (jtimon) +- #13288 `a589f53` Remove the need to include rpc/blockchain.cpp in order to put `GetDifficulty` under test (Empact) +- #13394 `e1f8dce` cli: Ignore libevent warnings (theuni) +- #13439 `3f398d7` Avoid "duplicate" return value for invalid submitblock (TheBlueMatt) +- #13570 `a247594` Add new "getzmqnotifications" method (domob1812) +- #13072 `b25a4c2` Update createmultisig RPC to support segwit (ajtowns) +- #12196 `8fceae0` Add scantxoutset RPC method (jonasschnelli) +- #13557 `b654723` BIP 174 PSBT Serializations and RPCs (achow101) +- #13697 `f030410` Support output descriptors in scantxoutset (sipa) +- #13927 `bced8ea` Use pushKV in some new PSBT RPCs (domob1812) +- #13918 `a9c56b6` Replace median fee rate with feerate percentiles in getblockstats (marcinja) +- #13721 `9f23c16` Bugfixes for BIP 174 combining and deserialization (achow101) +- #13960 `517010e` Fix PSBT deserialization of 0-input transactions (achow101) + +### GUI +- #12416 `c997f88` Fix Windows build errors introduced in #10498 (practicalswift) +- #11733 `e782099` Remove redundant locks (practicalswift) +- #12426 `bfa3911` Initialize members in WalletModel (MarcoFalke) +- #12489 `e117cfe` Bugfix: respect user defined configuration file (-conf) in QT settings (jonasschnelli) +- #12421 `be263fa` navigate to transaction history page after send (Sjors) +- #12580 `ce56fdd` Show a transaction's virtual size in its details dialog (dooglus) +- #12501 `c8ea91a` Improved "custom fee" explanation in tooltip (randolf) +- #12616 `cff95a6` Set modal overlay hide button as default (promag) +- #12620 `8a43bdc` Remove TransactionTableModel::TxIDRole (promag) +- #12080 `56cc022` Add support to search the address book (promag) +- #12621 `2bac3e4` Avoid querying unnecessary model data when filtering transactions (promag) +- #12721 `e476826` remove "new" button during receive-mode in addressbook (jonasschnelli) +- #12723 `310dc61` Qt5: Warning users about invalid-BIP21 URI bitcoin:// (krab) +- #12610 `25cf18f` Multiwallet for the GUI (jonasschnelli) +- #12779 `f4353da` Remove unused method setupAmountWidget(…) (practicalswift) +- #12795 `68484d6` do not truncate .dat extension for wallets in gui (instagibbs) +- #12870 `1d54004` make clean removes `src/qt/moc_` files (Sjors) +- #13055 `bdda14d` Don't log to console by default (laanwj) +- #13141 `57c57df` fixes broken link on readme (marcoagner) +- #12928 `ef006d9` Initialize non-static class members that were previously neither initialized where defined nor in constructor (practicalswift) +- #13158 `81c533c` Improve sendcoinsdialog readability (marcoagner) +- #11491 `40c34a0` Add proxy icon in statusbar (mess110) +- #13264 `2a7c53b` Satoshi unit (GreatSock) +- #13097 `e545503` Support wallets loaded dynamically (promag) +- #13284 `f8be434` fix visual "overflow" of amount input (brandonrninefive) +- #13275 `a315b79` use `[default wallet]` as name for wallet with no name (jonasschnelli) +- #13273 `3fd0c23` Qt/Bugfix: fix handling default wallet with no name (jonasschnelli) +- #13341 `25d2df2` Stop translating command line options (laanwj) +- #13043 `6e249e4` OptionsDialog: add prune setting (Sjors) +- #13506 `6579d80` load wallet in UI after possible init aborts (jonasschnelli) +- #13458 `dc53f7f` Drop qt4 support (laanwj) +- #13528 `b877c39` Move BitcoinGUI initializers to class, fix initializer order warning (laanwj) +- #13536 `baf3a3a` coincontrol: Remove unused qt4 workaround (MarcoFalke) +- #13537 `10ffca7` Peer table: Visualize inbound/outbound state for every row (wodry) +- #13791 `2c14c1f` Reject dialogs if key escape is pressed (promag) + +### Build system +- #12371 `c9ca4f6` Add gitian PGP key: akx20000 (ghost) +- #11966 `f4f4f51` clientversion: Use full commit hash for commit-based version descriptions (luke-jr) +- #12417 `ae0fbf0` Upgrade `mac_alias` to 2.0.7 (droark) +- #12444 `1f055ef` gitian: Bump descriptors for (0.)17 (theuni) +- #12402 `59e032b` expat 2.2.5, ccache 3.4.1, miniupnpc 2.0.20180203 (fanquake) +- #12029 `daa84b3` Add a makefile target for Doxygen documentation (Ov3rlo4d) +- #12466 `6645eaf` Only use `D_DARWIN_C_SOURCE` when building miniupnpc on darwin (fanquake) +- #11986 `765a3eb` zeromq 4.2.3 (fanquake) +- #12373 `f13d756` Add build support for profiling (murrayn) +- #12631 `a312e20` gitian: Alphabetize signing keys & add kallewoof key (kallewoof) +- #12607 `29fad97` Remove ccache (fanquake) +- #12625 `c4219ff` biplist 1.0.3 (fanquake) +- #12666 `05042d3` configure: UniValue 1.0.4 is required for pushKV(, bool) (luke-jr) +- #12678 `6324c68` Fix a few compilation issues with Clang 7 and -Werror (vasild) +- #12692 `de6bdfd` Add configure options for various -fsanitize flags (eklitzke) +- #12901 `7e23972` Show enabled sanitizers in configure output (practicalswift) +- #12899 `3076993` macOS: Prevent Xcode 9.3 build warnings (AkioNak) +- #12715 `8fd6243` Add 'make clean' rule (hkjn) +- #13133 `a024a18` Remove python2 from configure.ac (ken2812221) +- #13005 `cb088b1` Make --enable-debug to pick better options (practicalswift) +- #13254 `092b366` Remove improper `qt/moc_*` cleaning glob from the general Makefile (Empact) +- #13306 `f5a7733` split warnings out of CXXFLAGS (theuni) +- #13385 `7c7508c` Guard against accidental introduction of new Boost dependencies (practicalswift) +- #13041 `5779dc4` Add linter checking for accidental introduction of locale dependence (practicalswift) +- #13408 `70a03c6` crypto: cleanup sha256 build (theuni) +- #13435 `cf7ca60` When build fails due to lib missing, indicate which one (Empact) +- #13445 `8eb76f3` Reset default -g -O2 flags when enable debug (ken2812221) +- #13465 `81069a7` Avoid concurrency issue when make multiple target (ken2812221) +- #13454 `45c00f8` Make sure `LC_ALL=C` is set in all shell scripts (practicalswift) +- #13480 `31145a3` Avoid copies in range-for loops and add a warning to detect them (theuni) +- #13486 `66e1a08` Move rpc/util.cpp from libbitcoin-util to libbitcoin-server (ken2812221) +- #13580 `40334c7` Detect if char equals `int8_t` (ken2812221) +- #12788 `287e4ed` Tune wildcards for LIBSECP256K1 target (kallewoof) +- #13611 `b55f0c3` bugfix: Use `__cpuid_count` for gnu C to avoid gitian build fail (ken2812221) +- #12971 `a6d14b1` Upgrade Qt to 5.9.6 (TheCharlatan) +- #13543 `6c6a300` Add RISC-V support (laanwj) +- #13177 `dcb154e` GCC-7 and glibc-2.27 back compat code (ken2812221) +- #13659 `90b1c7e` add missing leveldb defines (theuni) +- #13368 `c0f1569` Update gitian-build.sh for docker (achow101) +- #13171 `19d8ca5` Change gitian-descriptors to use bionic instead (ken2812221) +- #13604 `75bea05` Add depends 32-bit arm support for bitcoin-qt (TheCharlatan) +- #13623 `9cdb19f` Migrate gitian-build.sh to python (ken2812221) +- #13689 `8c36432` disable Werror when building zmq (greenaddress) +- #13617 `cf7f9ae` release: Require macos 10.10+ (fanquake) +- #13750 `c883653` use MacOS friendly sed syntax in qt.mk (Sjors) +- #13095 `415f2bf` update `ax_boost_chrono`/`unit_test_framework` (fanquake) +- #13732 `e8ffec6` Fix Qt's rcc determinism (Fuzzbawls) +- #13782 `8284f1d` Fix osslsigncode compile issue in gitian-build (ken2812221) +- #13696 `2ab7208` Add aarch64 qt depends support for cross compiling bitcoin-qt (TheCharlatan) +- #13705 `b413ba0` Add format string linter (practicalswift) +- #14000 `48c8459` fix qt determinism (theuni) +- #14018 `3e4829a` Bugfix: NSIS: Exclude `Makefile*` from docs (luke-jr) +- #12906 `048ac83` Avoid `interface` keyword to fix windows gitian build (ryanofsky) +- #13314 `a9b6957` Fix FreeBSD build by including utilstrencodings.h (laanwj) + +### Tests and QA +- #12252 `8d57319` Require all tests to follow naming convention (ajtowns) +- #12295 `935eb8d` Enable flake8 warnings for all currently non-violated rules (practicalswift) +- #11858 `b4d8549` Prepare tests for Windows (MarcoFalke) +- #11771 `2dbc4a4` Change invalidtxrequest to use BitcoinTestFramework (jnewbery) +- #12200 `d09968f` Bind functional test nodes to 127.0.0.1 (Sjors) +- #12425 `26dc2da` Add some script tests (richardkiss) +- #12455 `23481fa` Fix bip68 sequence test to reflect updated rpc error message (Empact) +- #12477 `acd1e61` Plug memory leaks and stack-use-after-scope (MarcoFalke) +- #12443 `07090c5` Move common args to bitcoin.conf (MarcoFalke) +- #12570 `39dcac2` Add test cases for HexStr (`std::reverse_iterator` and corner cases) (kostaz) +- #12582 `6012f1c` Fix ListCoins test failure due to unset `g_wallet_allow_fallback_fee` (ryanofsky) +- #12516 `7f99964` Avoid unintentional unsigned integer wraparounds in tests (practicalswift) +- #12512 `955fd23` Don't test against the mempool min fee information in mempool_limit.py (Empact) +- #12600 `29088b1` Add a test for large tx output scripts with segwit input (richardkiss) +- #12627 `791c3ea` Fix some tests to work on native windows (MarcoFalke) +- #12405 `0f58d7f` travis: Full clone for git subtree check (MarcoFalke) +- #11772 `0630974` Change invalidblockrequest to use BitcoinTestFramework (jnewbery) +- #12681 `1846296` Fix ComputeTimeSmart test failure with `-DDEBUG_LOCKORDER` (ryanofsky) +- #12682 `9f04c8e` travis: Clone depth 1 unless `$check_doc` (MarcoFalke) +- #12710 `00d1680` Append scripts to new `test_list` array to fix bad assignment (jeffrade) +- #12720 `872c921` Avoiding 'file' function name from python2 (jeffrade) +- #12728 `4ba3d4f` rename TestNode to TestP2PConn in tests (jnewbery) +- #12746 `2405ce1` Remove unused argument `max_invalid` from `check_estimates(…)` (practicalswift) +- #12718 `185d484` Require exact match in `assert_start_raises_init_eror` (jnewbery, MarcoFalke) +- #12076 `6d36f59` Use node.datadir instead of tmpdir in test framework (MarcoFalke) +- #12772 `b43aba8` ci: Bump travis timeout for make check to 50m (jnewbery) +- #12806 `18606eb` Fix function names in `feature_blocksdir` (MarcoFalke) +- #12811 `0d8fc8d` Make summary row bold-red if any test failed and show failed tests at end of table (laanwj) +- #12790 `490644d` Use blockmaxweight where tests previously had blockmaxsize (conscott) +- #11773 `f0f9732` Change `feature_block.py` to use BitcoinTestFramework (jnewbery) +- #12839 `40f4baf` Remove travis checkout depth (laanwj) +- #11817 `2a09a78` Change `feature_csv_activation.py` to use BitcoinTestFramework (jnewbery) +- #12284 `fa5825d` Remove assigned but never used local variables. Enable Travis checking for unused local variables (practicalswift) +- #12719 `9beded5` Add note about test suite naming convention in developer-notes.md (practicalswift) +- #12861 `c564424` Stop `feature_block.py` from blowing up memory (jnewbery) +- #12851 `648252e` travis: Run verify-commits only on cron jobs (MarcoFalke) +- #12853 `2106c4c` Match full plain text by default (MarcoFalke) +- #11818 `9a2db3b` I accidentally (deliberately) killed it (the ComparisonTestFramework) (jnewbery) +- #12766 `69310a3` Tidy up REST interface functional tests (romanz) +- #12849 `83c7533` Add logging in loops in `p2p_sendhears.py` (ccdle12) +- #12895 `d6f10b2` Add note about test suite name uniqueness requirement to developer notes (practicalswift) +- #12856 `27278df` Add Metaclass for BitcoinTestFramework (WillAyd) +- #12918 `6fc5a05` Assert on correct variable (kallewoof) +- #11878 `a04440f` Add Travis check for duplicate includes (practicalswift) +- #12917 `cf8073f` Windows fixups for functional tests (MarcoFalke) +- #12926 `dd1ca9e` Run unit tests in parallel (sipa) +- #12920 `b1fdfc1` Fix sign for expected values (kallewoof) +- #12947 `979f598` Wallet hd functional test speedup and clarification (instagibbs) +- #12993 `0d69921` Remove compatibility code not needed now when we're on Python 3 (practicalswift) +- #12996 `6a278e0` Remove redundant bytes(…) calls (practicalswift) +- #12949 `6b46288` Avoid copies of CTransaction (MarcoFalke) +- #13007 `0d12570` Fix dangling wallet pointer in vpwallets (promag) +- #13048 `cac6d11` Fix `feature_block` flakiness (jnewbery) +- #12510 `d5b2e98` Add `rpc_bind` test to default-run tests (laanwj) +- #13022 `896a9d0` Attach node index to `test_node` AssertionError and print messages (jamesob) +- #13024 `018c7e5` Add rpcauth pair that generated by rpcauth.py (ken2812221) +- #13013 `a0079d4` bench: Amend `mempool_eviction` test for witness txs (MarcoFalke) +- #13051 `e074097` Normalize executable location (MarcoFalke) +- #13056 `106d929` Make rpcauth.py testable and add unit tests (nixbox) +- #13073 `a785bc3` add rpcauth-test to `AC_CONFIG_LINKS` to fix out-of-tree make check (laanwj) +- #12830 `25ad2f7` Clarify address book error messages, add tests (jamesob) +- #13082 `24106a8` don't test against min relay fee information in `mining_prioritisetransaction.py` (kristapsk) +- #13003 `8d045a0` Add test for orphan handling (MarcoFalke) +- #13105 `9e9b48d` Add --failfast option to functional test runner (jamesob) +- #13130 `3186ad4` Fix race in `rpc_deprecated.py` (jnewbery) +- #13136 `baf6b4e` Fix flake8 warnings in several wallet functional tests (jnewbery) +- #13094 `bf9b03d` Add test for 64-bit Windows PE, modify 32-bit test results (ken2812221) +- #13183 `9458b05` travis: New travis job for `check_docs` steps (glaksmono) +- #12265 `1834d4d` fundrawtransaction: lock watch-only shared address (kallewoof) +- #13188 `4a50ec0` Remove unused option --srcdir (MarcoFalke) +- #12755 `612ba35` Better stderr testing (jnewbery) +- #13198 `196c5a9` Avoid printing to console during cache creation (sdaftuar) +- #13075 `cb9bbf7` Remove 'account' API from wallet functional tests (jnewbery) +- #13221 `ffa86af` travis: Rename the build stage `check_doc` to `lint` (practicalswift) +- #13205 `3cbd25f` Remove spurious error log in `p2p_segwit.py` (jnewbery) +- #13291 `536120e` Don't include torcontrol.cpp into the test file (Empact) +- #13281 `2ac6315` Move linters to test/lint, add readme (MarcoFalke) +- #13215 `f8a29ca` travis: Build tests on ubuntu 18.04 with docker (ken2812221) +- #13349 `24f7011` bench: Don't return a bool from main (laanwj) +- #13347 `87a9d03` travis: Skip cache for lint stage (MarcoFalke) +- #13355 `0b1c0c4` Fix "gmake check" under OpenBSD 6.3 (probably `*BSD`): Avoid using GNU grep specific regexp handling (practicalswift) +- #13353 `d4f6dac` Fixup setting of PATH env var (MarcoFalke) +- #13352 `e24bf1c` Avoid checking reject code for now (MarcoFalke) +- #13383 `2722a1f` bench: Use non-throwing parsedouble(…) instead of throwing boost::lexical_cast(…) (practicalswift) +- #13367 `264efdc` Increase includeconf test coverage (MarcoFalke) +- #13404 `3d3d8ae` speed up of `tx_validationcache_tests` by reusing of CTransaction (lucash-dev) +- #13421 `531a033` Remove `portseed_offset` from test runner (MarcoFalke) +- #13440 `5315660` Log as utf-8 (MarcoFalke) +- #13066 `fa4b906` Migrate verify-commits script to python, run in travis (ken2812221) +- #13447 `4b1edd3` travis: Increase `travis_wait` time while verifying commits (ken2812221) +- #13350 `f532d52` Add logging to provide anchor points when debugging p2p_sendheaders (lmanners) +- #13406 `4382f19` travis: Change mac goal to all deploy (ken2812221) +- #13457 `b222138` Drop variadic macro (MarcoFalke) +- #13512 `3a45493` mininode: Expose connection state through `is_connected` (MarcoFalke) +- #13496 `9ab4c2a` Harden lint-filenames.sh (wodry) +- #13219 `08516e0` bench: Add block assemble benchmark (MarcoFalke) +- #13530 `b1dc39d` bench: Add missing pow.h header (laanwj) +- #12686 `2643fa5` Add -ftrapv to CFLAGS and CXXFLAGS when --enable-debug is used. Enable -ftrapv in Travis (practicalswift) +- #12882 `d96bdd7` Make `test_bitcoin` pass under ThreadSanitzer (clang). Fix lock-order-inversion (potential deadlock) (practicalswift) +- #13535 `2328039` `wallet_basic`: Specify minimum required amount for listunspent (MarcoFalke) +- #13551 `c93c360` Fix incorrect documentation for test case `cuckoocache_hit_rate_ok` (practicalswift) +- #13563 `b330f3f` bench: Simplify coinselection (promag) +- #13517 `a6ed99a` Remove need to handle the network thread in tests (MarcoFalke) +- #13522 `686e97a` Fix `p2p_sendheaders` race (jnewbery) +- #13467 `3dc2dcf` Make `p2p_segwit` easier to debug (jnewbery) +- #13598 `0212187` bench: Fix incorrect behaviour in prevector.cpp (AkioNak) +- #13565 `b05ded1` Fix AreInputsStandard test to reference the proper scriptPubKey (Empact) +- #13145 `d3dae3d` Use common getPath method to create temp directory in tests (winder) +- #13645 `2ea7eb6` skip `rpc_zmq` functional test as necessary (jamesob) +- #13626 `8f1106d` Fix some TODOs in `p2p_segwit` (MarcoFalke) +- #13138 `8803c91` Remove accounts from `wallet_importprunedfunds.py` (jnewbery) +- #13663 `cbc9b50` Avoid read/write to default datadir (MarcoFalke) +- #13682 `f8a32a3` bench: Remove unused variable (practicalswift) +- #13638 `6fcdb5e` Use `MAX_SCRIPT_ELEMENT_SIZE` from script.py (domob1812) +- #13687 `9d26b69` travis: Check that ~/.bitcoin is never created (MarcoFalke) +- #13715 `e1260a7` fixes mininode's P2PConnection sending messages on closing transport (marcoagner) +- #13729 `aa9429a` travis: Avoid unnecessarily setting env variables on the lint build (Empact) +- #13747 `ab28b5b` Skip P2PConnection's `is_closing()` check when not available (domob1812) +- #13650 `7a9bca6` travis: Don't store debug info if --enable-debug is set (ken2812221) +- #13711 `f98d1e0` bench: Add benchmark for unserialize prevector (AkioNak) +- #13771 `365384f` travis: Retry to fetch docker image (MarcoFalke) +- #13806 `4d550ff` Fix `bench/block_assemble` assert failure (jamesob) +- #13779 `d25079a` travis: Improve readability of travis.yml and log outputs (scravy) +- #13822 `0fb9c87` bench: Make coinselection output groups pass eligibility filter (achow101) +- #13247 `e83d82a` Add tests to SingleThreadedSchedulerClient() and document the memory model (skeees) +- #13811 `660abc1` travis: Run `bench_bitcoin` once (MarcoFalke) +- #13837 `990e182` Extract `rpc_timewait` as test param (MarcoFalke) +- #13851 `9c4324d` fix locale for lint-shell (scravy) +- #13823 `489b51b` quote path in authproxy for external multiwallets (MarcoFalke) +- #13849 `2b67354` travis: Use only travis jobs: instead of mix of jobs+matrix (scravy) +- #13859 `2384323` Add emojis to `test_runner` path and wallet filename (MarcoFalke) +- #13916 `8ac7125` `wait_for_verack` by default (MarcoFalke) +- #13669 `f66e1c7` Cleanup `create_transaction` implementations (conscott) +- #13924 `09ada21` Simplify comparison in `rpc_blockchain.py` (domob1812) +- #13913 `a08533c` Remove redundant checkmempool/checkblockindex `extra_args` (MarcoFalke) +- #13915 `a04888a` Add test for max number of entries in locator (MarcoFalke) +- #13867 `1b04b55` Make extended tests pass on native Windows (MarcoFalke) +- #13944 `0df7a6c` Port usage of deprecated optparse module to argparse module (Kvaciral) +- #13928 `b8eb0df` blocktools enforce named args for amount (MarcoFalke) +- #13054 `bffb35f` Enable automatic detection of undefined names in Python tests scripts. Remove wildcard imports (practicalswift) +- #14069 `cf3d7f9` Use assert not `BOOST_CHECK_*` from multithreaded tests (skeees) +- #14071 `fab0fbe` Stop txindex thread before calling destructor (MarcoFalke) + +### Miscellaneous +- #11909 `8897135` contrib: Replace developer keys with list of pgp fingerprints (MarcoFalke) +- #12394 `fe53d5f` gitian-builder.sh: fix --setup doc, since lxc is default (Sjors) +- #12468 `294a766` Add missing newline in init.cpp log message (Aesti) +- #12308 `dcfe218` contrib: Add support for out-of-tree builds in gen-manpages.sh (laanwj) +- #12451 `aae64a2` Bump leveldb subtree (MarcoFalke) +- #12527 `d77b4a7` gitian-build.sh: fix signProg being recognized as two parameters (ken2812221) +- #12588 `d74b01d` utils: Remove deprecated pyzmq call from python zmq example (kosciej) +- #10271 `bc67982` Use `std::thread::hardware_concurrency`, instead of Boost, to determine available cores (fanquake) +- #12097 `14475e2` scripts: Lint-whitespace: use perl instead of grep -p (Sjors) +- #12098 `17c44b2` scripts: Lint-whitespace: add param to check last n commits (Sjors) +- #11900 `842f61a` script: Simplify checkminimalpush checks, add safety assert (instagibbs) +- #12567 `bb98aec` util: Print timestamp strings in logs using iso 8601 formatting (practicalswift) +- #12572 `d8d9162` script: Lint-whitespace: find errors more easily (AkioNak) +- #10694 `ae5bcc7` Remove redundant code in MutateTxSign(CMutableTransaction&, const std::string&) (practicalswift) +- #12659 `3d16f58` Improve Fatal LevelDB Log Messages (eklitzke) +- #12643 `0f0229d` util: Remove unused `sync_chain` (MarcoFalke) +- #12102 `7fb8fb4` Apply hardening measures in bitcoind systemd service file (Flowdalic) +- #12652 `55f490a` bitcoin-cli: Provide a better error message when bitcoind is not running (practicalswift) +- #12630 `c290508` Provide useful error message if datadir is not writable (murrayn) +- #11881 `624bee9` Remove Python2 support (jnewbery) +- #12821 `082e26c` contrib: Remove unused import string (MarcoFalke) +- #12829 `252c1b0` Python3 fixup (jnewbery) +- #12822 `ff48f62` Revert 7deba93bdc76616011a9f493cbc203d60084416f and fix expired-key-sigs properly (TheBlueMatt) +- #12820 `5e53b80` contrib: Fix check-doc script regexes (MarcoFalke) +- #12713 `4490871` Track negated options in the option parser (eklitzke) +- #12708 `b2e5fe8` Make verify-commits.sh test that merges are clean (sipa) +- #12891 `3190785` logging: Add lint-logs.sh to check for newline termination (jnewbery) +- #12923 `a7cbe38` util: Pass `pthread_self()` to `pthread_setschedparam` instead of 0 (laanwj) +- #12871 `fb17fae` Add shell script linting: Check for shellcheck warnings in shell scripts (practicalswift) +- #12970 `5df84de` logging: Bypass timestamp formatting when not logging (theuni) +- #12987 `fe8fa22` tests/tools: Enable additional Python flake8 rules for automatic linting via Travis (practicalswift) +- #12972 `0782508` Add python3 script shebang lint (ken2812221) +- #13004 `58bbc55` Print to console by default when not run with -daemon (practicalswift) +- #13039 `8b4081a` Add logging and error handling for file syncing (laanwj) +- #13020 `4741ca5` Consistently log CValidationState on call failure (Empact) +- #13031 `826acc9` Fix for utiltime to compile with msvc (sipsorcery) +- #13119 `81743b5` Remove script to clean up datadirs (MarcoFalke) +- #12954 `5a66642` util: Refactor logging code into a global object (jimpo) +- #12769 `35eb9d6` Add systemd service to bitcoind in debian package (ghost) +- #13146 `0bc980b` rpcauth: Make it possible to provide a custom password (laanwj) +- #13148 `b62b437` logging: Fix potential use-after-free in logprintstr(…) (practicalswift) +- #13214 `0612d96` Enable Travis checking for two Python linting rules we are currently not violating (practicalswift) +- #13197 `6826989` util: Warn about ignored recursive -includeconf calls (kallewoof) +- #13176 `d9ebb63` Improve CRollingBloomFilter performance: replace modulus with FastMod (martinus) +- #13228 `d792e47` Add script to detect circular dependencies between source modules (sipa) +- #13320 `e08c130` Ensure gitian-build.sh uses bash (jhfrontz) +- #13301 `e4082d5` lint: Add linter to error on `#include <*.cpp>` (Empact) +- #13374 `56f6936` utils and libraries: checking for bitcoin address in translations (kaplanmaxe) +- #13230 `7c32b41` Simplify include analysis by enforcing the developer guide's include syntax (practicalswift) +- #13450 `32bf4c6` Add linter: Enforce the source code file naming convention described in the developer notes (practicalswift) +- #13479 `fa2ea37` contrib: Fix cve-2018-12356 by hardening the regex (loganaden) +- #13448 `a90ca40` Add linter: Make sure we explicitly open all text files using UTF-8 encoding in Python (practicalswift) +- #13494 `d67eff8` Follow-up to #13454: Fix broken build by exporting `LC_ALL=C` (practicalswift) +- #13510 `03f3925` Scripts and tools: Obsolete #!/bin/bash shebang (DesWurstes) +- #13577 `c9eb8d1` logging: Avoid nstart may be used uninitialized in appinitmain warning (mruddy) +- #13603 `453ae5e` bitcoin-tx: Stricter check for valid integers (domob1812) +- #13118 `c05c93c` RPCAuth Detection in Logs (Linrono) +- #13647 `4027ec1` Scripts and tools: Fix `BIND_NOW` check in security-check.py (conradoplg) +- #13692 `f5d166a` contrib: Clone core repo in gitian-build (MarcoFalke) +- #13699 `4c6d1b9` contrib: Correct version check (kallewoof) +- #13695 `dcc0cff` lint: Add linter for circular dependencies (Empact) +- #13733 `0d1ebf4` utils: Refactor argsmanager a little (AtsukiTak) +- #13714 `29b4ee6` contrib: Add lxc network setup for bionic host (ken2812221) +- #13764 `f8685f4` contrib: Fix test-security-check fail in ubuntu 18.04 (ken2812221) +- #13809 `77168f7` contrib: Remove debian and rpm subfolder (MarcoFalke) +- #13799 `230652c` Ignore unknown config file options; warn instead of error (sipa) +- #13894 `df9f712` shutdown: Stop threads before resetting ptrs (MarcoFalke) +- #13925 `71dec5c` Merge leveldb subtree (MarcoFalke) +- #13939 `ef86f26` lint: Make format string linter understand basic template parameter syntax (practicalswift) +- #14105 `eb202ea` util: Report parse errors in configuration file (laanwj) +- #12604 `9903537` Add DynamicMemoryUsage() to CDBWrapper to estimate LevelDB memory use (eklitzke) +- #12495 `047865e` Increase LevelDB `max_open_files` (eklitzke) +- #12784 `e80716d` Fix bug in memory usage calculation (unintended integer division) (practicalswift) +- #12618 `becd8dd` Set `SCHED_BATCH` priority on the loadblk thread (eklitzke) +- #12854 `5ca1509` Add P2P, Network, and Qt categories to the desktop icon (luke-jr) +- #11862 `4366f61` Network specific conf sections (ajtowns) +- #13441 `4a7e64f` Prevent shared conf files from failing with different available options in different binaries (achow101) +- #13471 `5eca4e8` For AVX2 code, also check for AVX, XSAVE, and OS support (sipa) +- #13503 `c655b2c` Document FreeBSD quirk. Fix FreeBSD build: Use std::min(…) to allow for compilation under certain FreeBSD versions (practicalswift) +- #13725 `07ce278` Fix bitcoin-cli --version (Empact) + +### Documentation +- #12306 `216f9a4` Improvements to UNIX documentation (axvr) +- #12309 `895fbd7` Explain how to update chainTxData in release process (laanwj) +- #12317 `85123be` Document method for reviewers to verify chainTxData (jnewbery) +- #12331 `d32528e` Properly alphabetize output of CLI --help option (murrayn) +- #12322 `c345148` Remove step making cloned repository world-writable for Windows build (murrayn) +- #12354 `b264528` add gpg key for fivepiece (fivepiece) +- #11761 `89005dd` initial QT documentation (Sjors) +- #12232 `fdc2188` Improve "Turn Windows Features On or Off" step (MCFX2) +- #12487 `4528f74` init: Remove translation for `-blockmaxsize` option help (laanwj) +- #12546 `a4a5fc7` Minor improvements to Compatibility Notes (randolf) +- #12434 `21e2670` dev-notes: Members should be initialized (MarcoFalke) +- #12452 `71f56da` clarified systemd installation instructions in init.md for Ubuntu users (DaveFromBinary) +- #12615 `1f93491` allow for SIGNER containing spaces (ken2812221) +- #12603 `85424d7` PeerLogicValidation interface (jamesob) +- #12581 `12ac2f0` Mention configure without wallet in FreeBSD instructions (dbolser) +- #12619 `8a709fb` Give hint about gitian not able to download (kallewoof) +- #12668 `de2fcaa` do update before fetching packages in WSL build guide (nvercamm) +- #12586 `e7721e6` Update osx brew install instruction (fanquake) +- #12760 `7466a26` Improve documentation on standard communication channels (jimpo) +- #12797 `0415b1e` init: Fix help message for checkblockindex (MarcoFalke) +- #12800 `2d97611` Add note about our preference for scoped enumerations ("enum class") (practicalswift) +- #12798 `174d016` Refer to witness reserved value as spec. in the BIP (MarcoFalke) +- #12759 `d3908e2` Improve formatting of developer notes (eklitzke) +- #12877 `2b54155` Use bitcoind in Tor documentation (knoxcard) +- #12896 `b15485e` Fix conflicting statements about initialization in developer notes (practicalswift) +- #12850 `319991d` add qrencode to brew install instructions (buddilla) +- #12007 `cd8e45b` Clarify the meaning of fee delta not being a fee rate in prioritisetransaction RPC (honzik666) +- #12927 `06ead15` fixed link, replaced QT with Qt (trulex) +- #12852 `ebd786b` devtools: Setup ots git integration (MarcoFalke) +- #12933 `3cf76c2` Refine header include policy (MarcoFalke) +- #12951 `6df0c6c` Fix comment in FindForkInGlobalIndex (jamesob) +- #12982 `a63b4e3` Fix inconsistent namespace formatting guidelines (ryanofsky) +- #13026 `9b3a67e` Fix include comment in src/interfaces/wallet.h (promag) +- #13012 `d1e3c5e` Add comments for chainparams.h, validation.cpp (jamesob) +- #13064 `569e381` List support for BIP173 in bips.md (sipa) +- #12997 `646b7f6` build-windows: Switch to Artful, since Zesty is EOL (MarcoFalke) +- #12384 `c5f7efe` Add version footnote to tor.md (Willtech) +- #13165 `627c376` Mention good first issue list in CONTRIBUTING.md (fanquake) +- #13295 `fb77310` Update OpenBSD build instructions for OpenBSD 6.3 (practicalswift) +- #13340 `3a8e3f4` remove leftover check-doc documentation (fanquake) +- #13346 `60f0358` update bitcoin-dot-org links in release-process.md (fanquake) +- #13372 `f014933` split FreeBSD build instructions out of build-unix.md (steverusso) +- #13366 `861de3b` Rename “OS X” to the newer “macOS” convention (giulio92) +- #13369 `f8bcef3` update transifex doc link (mess110) +- #13312 `b22115d` Add a note about the source code filename naming convention (practicalswift) +- #13460 `1939536` Remove note to install all boost dev packages (MarcoFalke) +- #13476 `9501938` Fix incorrect shell quoting in FreeBSD build instructions (murrayn) +- #13402 `43fa355` Document validationinterace callback blocking deadlock potential (TheBlueMatt) +- #13488 `d6cf4bd` Improve readability of "Squashing commits" (wodry) +- #13531 `ee02deb` Clarify that mempool txiter is `const_iterator` (MarcoFalke) +- #13418 `01f9098` More precise explanation of parameter onlynet (wodry) +- #13592 `1756cb4` Modify policy to not translate command-line help (ken2812221) +- #13588 `b77c38e` Improve doc of options addnode, connect, seednode (wodry) +- #13614 `17e9106` Update command line help for -printtoconsole and -debuglogfile (satwo, fanquake) +- #13605 `8cc048e` corrected text to reflect new(er) process of specifying fingerprints (jhfrontz) +- #13481 `b641f60` Rewrite some validation docs as lock annotations (MarcoFalke) +- #13680 `30640f8` Remove outdated comment about miner ignoring CPFP (jamesob) +- #13625 `7146672` Add release notes for -printtoconsole and -debuglogfile changes (satwo) +- #13718 `f7f574d` Specify preferred Python string formatting technique (masonicboom) +- #12764 `10b9a81` Remove field in getblocktemplate help that has never been used (conscott) +- #13742 `d2186b3` Adjust bitcoincore.org links (MarcoFalke) +- #13706 `94dd89e` Minor improvements to release-process.md (MitchellCash) +- #13775 `ef4fac0` Remove newlines from error message (practicalswift) +- #13803 `feb7dd9` add note to contributor docs about warranted PR's (kallewoof) +- #13814 `67af7ef` Add BIP174 to list of implemented BIPs (sipa) +- #13835 `c1cba35` Fix memory consistency model in comment (skeees) +- #13824 `aa30e4b` Remove outdated net comment (MarcoFalke) +- #13853 `317477a` correct versions in dependencies.md (fanquake) +- #13872 `37ab117` Reformat -help output for help2man (real-or-random) +- #13717 `8c3c402` Link to python style guidelines from developer notes (masonicboom) +- #13895 `1cd5f2c` fix GetWarnings docs to reflect behavior (Empact) +- #13911 `3e3a50a` Revert translated string change, clarify wallet log messages (PierreRochard) +- #13908 `d6faea4` upgrade rescan time warning from minutes to >1 hour (masonicboom) +- #13905 `73a09b4` fixed bitcoin-cli -help output for help2man (hebasto) +- #14100 `2936dbc` Change documentation for =0 for non-boolean options (laanwj) +- #14096 `465a583` Add reference documentation for descriptors language (sipa) +- #12757 `0c5f67b` Clarify include guard naming convention (practicalswift) +- #13844 `d3325b0` Correct the help output for `-prune` (hebasto) + +Credits +======= + +Thanks to everyone who directly contributed to this release: + +- 251 +- 532479301 +- Aaron Clauson +- Akio Nakamura +- Akira Takizawa +- Alex Morcos +- Alex Vear +- Alexey Ivanov +- Alin Rus +- Andrea Comand +- Andrew Chow +- Anthony Towns +- AtsukiTak +- Ben Woosley +- Bernhard M. Wiedemann +- Brandon Ruggles +- buddilla +- ccdle12 +- Chris Moore +- Chun Kuan Lee +- Clem Taylor +- Conor Scott +- Conrado Gouvea +- Cory Fields +- Cristian Mircea Messel +- ctp-tsteenholdt +- Damian Williamson +- Dan Bolser +- Daniel Kraft +- Darko Janković +- DaveFromBinary +- David A. Harding +- DesWurstes +- Dimitris Apostolou +- donaloconnor +- Douglas Roark +- DrahtBot +- Drew Rasmussen +- e0 +- Ernest Hemingway +- Ethan Heilman +- Evan Klitzke +- fanquake +- Felix Wolfsteller +- fivepiece +- Florian Schmaus +- Fuzzbawls +- Gabriel Davidian +- Giulio Lombardo +- Gleb +- Grady Laksmono +- GreatSock +- Gregory Maxwell +- Gregory Sanders +- Hennadii Stepanov +- Henrik Jonsson +- Indospace.io +- James O'Beirne +- Jan Čapek +- Jeff Frontz +- Jeff Rade +- Jeremy Rubin +- JeremyRand +- Jesse Cohen +- Jim Posen +- joemphilips +- John Bampton +- John Newbery +- johnlow95 +- Johnson Lau +- Jonas Nick +- Jonas Schnelli +- João Barbosa +- Jorge Timón +- Josh Hartshorn +- Julian Fleischer +- kallewoof +- Karel Bilek +- Karl-Johan Alm +- Ken Lee +- Kevin Pan +- Kosta Zertsekel +- Kristaps Kaupe +- Kvaciral +- Lawrence Nahum +- Linrono +- lmanners +- Loganaden Velvindron +- Lowell Manners +- lucash.dev@gmail.com +- Luke Dashjr +- lutangar +- Marcin Jachymiak +- marcoagner +- MarcoFalke +- Mark Erhardt +- Mark Friedenbach +- Martin Ankerl +- Mason Simon +- Matt Corallo +- Matteo Sumberaz +- Max Kaplan +- MeshCollider +- Michał Zabielski +- Mitchell Cash +- mruddy +- mryandao +- murrayn +- Nick Vercammen +- Nicolas Dorier +- Nikolay Mitev +- okayplanet +- Pierre Rochard +- Pieter Wuille +- practicalswift +- Qasim Javed +- Randolf Richardson +- Richard Kiss +- Roman Zeyde +- Russell Yanofsky +- Samuel B. Atwood +- Sebastian Kung +- Sjors Provoost +- Steve Lee +- steverusso +- Suhas Daftuar +- Tamas Blummer +- TheCharlatan +- Thomas Kerin +- Thomas Snider +- Tim Ruffing +- Varunram +- Vasil Dimov +- Will Ayd +- William Robinson +- winder +- Wladimir J. van der Laan +- wodry + +And to those that reported security issues: + +- awemany (for CVE-2018-17144, previously credited as "anonymous reporter") + +As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/). diff --git a/doc/release-process.md b/doc/release-process.md index 3ba622ee6d..f2fe44c8bf 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -296,6 +296,8 @@ bitcoin.org (see below for bitcoin.org update instructions). - bitcoincore.org blog post + - bitcoincore.org RPC documentation update + - Update title of #bitcoin on Freenode IRC - Optionally twitter, reddit /r/Bitcoin, ... but this will usually sort out itself diff --git a/doc/zmq.md b/doc/zmq.md index 5d67df9d22..a1a506f2e7 100644 --- a/doc/zmq.md +++ b/doc/zmq.md @@ -33,8 +33,10 @@ buffering or reassembly. ## Prerequisites -The ZeroMQ feature in Bitcoin Core requires ZeroMQ API version 4.x or -newer. Typically, it is packaged by distributions as something like +The ZeroMQ feature in Bitcoin Core requires the ZeroMQ API >= 4.0.0 +[libzmq](https://github.com/zeromq/libzmq/releases). +For version information, see [dependencies.md](dependencies.md). +Typically, it is packaged by distributions as something like *libzmq3-dev*. The C++ wrapper for ZeroMQ is *not* needed. In order to run the example Python client scripts in contrib/ one must diff --git a/share/setup.nsi.in b/share/setup.nsi.in index 8383252e7d..2802919f87 100644 --- a/share/setup.nsi.in +++ b/share/setup.nsi.in @@ -10,11 +10,11 @@ SetCompressor /SOLID lzma !define URL @PACKAGE_URL@ # MUI Symbol Definitions -!define MUI_ICON "pixmaps/bitcoin.ico" -!define MUI_WELCOMEFINISHPAGE_BITMAP "pixmaps/nsis-wizard.bmp" +!define MUI_ICON "@abs_top_srcdir@/share/pixmaps/bitcoin.ico" +!define MUI_WELCOMEFINISHPAGE_BITMAP "@abs_top_srcdir@/share/pixmaps/nsis-wizard.bmp" !define MUI_HEADERIMAGE !define MUI_HEADERIMAGE_RIGHT -!define MUI_HEADERIMAGE_BITMAP "pixmaps/nsis-header.bmp" +!define MUI_HEADERIMAGE_BITMAP "@abs_top_srcdir@/share/pixmaps/nsis-header.bmp" !define MUI_FINISHPAGE_NOAUTOCLOSE !define MUI_STARTMENUPAGE_REGISTRY_ROOT HKLM !define MUI_STARTMENUPAGE_REGISTRY_KEY ${REGKEY} @@ -23,7 +23,7 @@ SetCompressor /SOLID lzma !define MUI_FINISHPAGE_RUN "$WINDIR\explorer.exe" !define MUI_FINISHPAGE_RUN_PARAMETERS $INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@ !define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico" -!define MUI_UNWELCOMEFINISHPAGE_BITMAP "pixmaps/nsis-wizard.bmp" +!define MUI_UNWELCOMEFINISHPAGE_BITMAP "@abs_top_srcdir@/share/pixmaps/nsis-wizard.bmp" !define MUI_UNFINISHPAGE_NOAUTOCLOSE # Included files @@ -49,7 +49,7 @@ Var StartMenuGroup !insertmacro MUI_LANGUAGE English # Installer attributes -OutFile ./@PACKAGE_TARNAME@-${VERSION}-win-setup.exe +OutFile @abs_top_srcdir@/@PACKAGE_TARNAME@-${VERSION}-win-setup.exe !if "@WINDOWS_BITS@" == "64" InstallDir $PROGRAMFILES64\Feathercoin !else @@ -74,9 +74,12 @@ ShowUninstDetails show Section -Main SEC0000 SetOutPath $INSTDIR SetOverwrite on - File ../src/qt/@BITCOIN_GUI_NAME@@EXEEXT@ - File /oname=COPYING.txt ../COPYING - File /oname=readme.txt ../doc/README_windows.txt + File @abs_top_srcdir@/release/@BITCOIN_GUI_NAME@@EXEEXT@ + File /oname=COPYING.txt @abs_top_srcdir@/COPYING + File /oname=readme.txt @abs_top_srcdir@/doc/README_windows.txt + SetOutPath $INSTDIR\daemon + File @abs_top_srcdir@/release/@BITCOIN_DAEMON_NAME@@EXEEXT@ + File @abs_top_srcdir@/release/@BITCOIN_CLI_NAME@@EXEEXT@ SetOutPath $INSTDIR WriteRegStr HKCU "${REGKEY}\Components" Main 1 SectionEnd diff --git a/src/Makefile.am b/src/Makefile.am index eb8e6a7f08..9958d2189f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -83,8 +83,11 @@ if BUILD_BITCOIND bin_PROGRAMS += feathercoind endif -if BUILD_BITCOIN_UTILS - bin_PROGRAMS += feathercoin-cli feathercoin-tx +if BUILD_BITCOIN_CLI + bin_PROGRAMS += feathercoin-cli +endif +if BUILD_BITCOIN_TX + bin_PROGRAMS += feathercoin-tx endif .PHONY: FORCE check-symbols check-security @@ -189,6 +192,7 @@ BITCOIN_CORE_H = \ validation.h \ validationinterface.h \ versionbits.h \ + versionbitsinfo.h \ walletinitinterface.h \ wallet/coincontrol.h \ wallet/crypter.h \ @@ -232,6 +236,8 @@ libbitcoin_server_a_SOURCES = \ httpserver.cpp \ index/base.cpp \ index/txindex.cpp \ + interfaces/handler.cpp \ + interfaces/node.cpp \ init.cpp \ dbwrapper.cpp \ merkleblock.cpp \ @@ -264,6 +270,10 @@ libbitcoin_server_a_SOURCES = \ versionbits.cpp \ $(BITCOIN_CORE_H) +if !ENABLE_WALLET +libbitcoin_server_a_SOURCES += dummywallet.cpp +endif + if ENABLE_ZMQ libbitcoin_zmq_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(ZMQ_CFLAGS) libbitcoin_zmq_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) @@ -402,6 +412,7 @@ libbitcoin_common_a_SOURCES = \ script/ismine.cpp \ script/sign.cpp \ script/standard.cpp \ + versionbitsinfo.cpp \ warnings.cpp \ $(BITCOIN_CORE_H) @@ -418,8 +429,6 @@ libbitcoin_util_a_SOURCES = \ compat/glibcxx_sanity.cpp \ compat/strnlen.cpp \ fs.cpp \ - interfaces/handler.cpp \ - interfaces/node.cpp \ logging.cpp \ random.cpp \ rpc/protocol.cpp \ @@ -471,7 +480,7 @@ feathercoind_LDADD = \ $(LIBMEMENV) \ $(LIBSECP256K1) -feathercoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS) +feathercoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS) # bitcoin-cli binary # feathercoin_cli_SOURCES = bitcoin-cli.cpp @@ -489,7 +498,7 @@ feathercoin_cli_LDADD = \ $(LIBBITCOIN_UTIL) \ $(LIBBITCOIN_CRYPTO) -feathercoin_cli_LDADD += $(BOOST_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(EVENT_LIBS) +feathercoin_cli_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS) $(EVENT_LIBS) # # bitcoin-tx binary # diff --git a/src/Makefile.bench.include b/src/Makefile.bench.include index 76177630ab..544092520f 100644 --- a/src/Makefile.bench.include +++ b/src/Makefile.bench.include @@ -56,7 +56,7 @@ if ENABLE_WALLET bench_bench_bitcoin_SOURCES += bench/coin_selection.cpp endif -bench_bench_bitcoin_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) +bench_bench_bitcoin_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) bench_bench_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) CLEAN_BITCOIN_BENCH = bench/*.gcda bench/*.gcno $(GENERATED_BENCH_FILES) diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 019799eb0b..203ac4b8b0 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -8,6 +8,7 @@ TEST_SRCDIR = test TEST_BINARY=test/test_bitcoin$(EXEEXT) JSON_TEST_FILES = \ + test/data/script_tests.json \ test/data/base58_encode_decode.json \ test/data/blockfilters.json \ test/data/key_io_valid.json \ @@ -95,6 +96,15 @@ BITCOIN_TESTS =\ test/validation_block_tests.cpp \ test/versionbits_tests.cpp +if ENABLE_PROPERTY_TESTS +BITCOIN_TESTS += \ + test/key_properties.cpp + +BITCOIN_TEST_SUITE += \ + test/gen/crypto_gen.cpp \ + test/gen/crypto_gen.h +endif + if ENABLE_WALLET BITCOIN_TESTS += \ wallet/test/psbt_wallet_tests.cpp \ @@ -118,7 +128,7 @@ test_test_bitcoin_LDADD += $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_C $(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(EVENT_LIBS) $(EVENT_PTHREADS_LIBS) test_test_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) -test_test_bitcoin_LDADD += $(LIBBITCOIN_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) +test_test_bitcoin_LDADD += $(LIBBITCOIN_CONSENSUS) $(BDB_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(RAPIDCHECK_LIBS) test_test_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static if ENABLE_ZMQ @@ -151,7 +161,7 @@ nodist_test_test_bitcoin_SOURCES = $(GENERATED_TEST_FILES) $(BITCOIN_TESTS): $(GENERATED_TEST_FILES) -CLEAN_BITCOIN_TEST = test/*.gcda test/*.gcno $(GENERATED_TEST_FILES) +CLEAN_BITCOIN_TEST = test/*.gcda test/*.gcno $(GENERATED_TEST_FILES) $(BITCOIN_TESTS:.cpp=.cpp.log) CLEANFILES += $(CLEAN_BITCOIN_TEST) @@ -164,8 +174,10 @@ bitcoin_test_clean : FORCE rm -f $(CLEAN_BITCOIN_TEST) $(test_test_bitcoin_OBJECTS) $(TEST_BINARY) check-local: $(BITCOIN_TESTS:.cpp=.cpp.test) +if BUILD_BITCOIN_TX @echo "Running test/util/bitcoin-util-test.py..." $(PYTHON) $(top_builddir)/test/util/bitcoin-util-test.py +endif @echo "Running test/util/rpcauth-test.py..." $(PYTHON) $(top_builddir)/test/util/rpcauth-test.py $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C secp256k1 check diff --git a/src/addrman.h b/src/addrman.h index cf1949c28c..6d5780afa8 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -187,36 +187,37 @@ class CAddrInfo : public CAddress */ class CAddrMan { -private: +protected: //! critical section to protect the inner data structures mutable CCriticalSection cs; +private: //! last used nId - int nIdCount; + int nIdCount GUARDED_BY(cs); //! table with information about all nIds - std::map mapInfo; + std::map mapInfo GUARDED_BY(cs); //! find an nId based on its network address - std::map mapAddr; + std::map mapAddr GUARDED_BY(cs); //! randomly-ordered vector of all nIds - std::vector vRandom; + std::vector vRandom GUARDED_BY(cs); // number of "tried" entries - int nTried; + int nTried GUARDED_BY(cs); //! list of "tried" buckets - int vvTried[ADDRMAN_TRIED_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE]; + int vvTried[ADDRMAN_TRIED_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE] GUARDED_BY(cs); //! number of (unique) "new" entries - int nNew; + int nNew GUARDED_BY(cs); //! list of "new" buckets - int vvNew[ADDRMAN_NEW_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE]; + int vvNew[ADDRMAN_NEW_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE] GUARDED_BY(cs); //! last time Good was called (memory only) - int64_t nLastGood; + int64_t nLastGood GUARDED_BY(cs); //! Holds addrs inserted into tried table that collide with existing entries. Test-before-evict discipline used to resolve these collisions. std::set m_tried_collisions; @@ -229,58 +230,58 @@ class CAddrMan FastRandomContext insecure_rand; //! Find an entry. - CAddrInfo* Find(const CNetAddr& addr, int *pnId = nullptr); + CAddrInfo* Find(const CNetAddr& addr, int *pnId = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs); //! find an entry, creating it if necessary. //! nTime and nServices of the found node are updated, if necessary. - CAddrInfo* Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId = nullptr); + CAddrInfo* Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs); //! Swap two elements in vRandom. - void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2); + void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2) EXCLUSIVE_LOCKS_REQUIRED(cs); //! Move an entry from the "new" table(s) to the "tried" table - void MakeTried(CAddrInfo& info, int nId); + void MakeTried(CAddrInfo& info, int nId) EXCLUSIVE_LOCKS_REQUIRED(cs); //! Delete an entry. It must not be in tried, and have refcount 0. - void Delete(int nId); + void Delete(int nId) EXCLUSIVE_LOCKS_REQUIRED(cs); //! Clear a position in a "new" table. This is the only place where entries are actually deleted. - void ClearNew(int nUBucket, int nUBucketPos); + void ClearNew(int nUBucket, int nUBucketPos) EXCLUSIVE_LOCKS_REQUIRED(cs); //! Mark an entry "good", possibly moving it from "new" to "tried". - void Good_(const CService &addr, bool test_before_evict, int64_t time); + void Good_(const CService &addr, bool test_before_evict, int64_t time) EXCLUSIVE_LOCKS_REQUIRED(cs); //! Add an entry to the "new" table. - bool Add_(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty); + bool Add_(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty) EXCLUSIVE_LOCKS_REQUIRED(cs); //! Mark an entry as attempted to connect. - void Attempt_(const CService &addr, bool fCountFailure, int64_t nTime); + void Attempt_(const CService &addr, bool fCountFailure, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs); //! Select an address to connect to, if newOnly is set to true, only the new table is selected from. - CAddrInfo Select_(bool newOnly); + CAddrInfo Select_(bool newOnly) EXCLUSIVE_LOCKS_REQUIRED(cs); //! See if any to-be-evicted tried table entries have been tested and if so resolve the collisions. - void ResolveCollisions_(); + void ResolveCollisions_() EXCLUSIVE_LOCKS_REQUIRED(cs); //! Return a random to-be-evicted tried table address. - CAddrInfo SelectTriedCollision_(); + CAddrInfo SelectTriedCollision_() EXCLUSIVE_LOCKS_REQUIRED(cs); //! Wraps GetRandInt to allow tests to override RandomInt and make it determinismistic. virtual int RandomInt(int nMax); #ifdef DEBUG_ADDRMAN //! Perform consistency check. Returns an error code or zero. - int Check_(); + int Check_() EXCLUSIVE_LOCKS_REQUIRED(cs); #endif //! Select several addresses at once. - void GetAddr_(std::vector &vAddr); + void GetAddr_(std::vector &vAddr) EXCLUSIVE_LOCKS_REQUIRED(cs); //! Mark an entry as currently-connected-to. - void Connected_(const CService &addr, int64_t nTime); + void Connected_(const CService &addr, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs); //! Update an entry's service bits. - void SetServices_(const CService &addr, ServiceFlags nServices); + void SetServices_(const CService &addr, ServiceFlags nServices) EXCLUSIVE_LOCKS_REQUIRED(cs); public: /** diff --git a/src/amount.h b/src/amount.h index 4c76006fea..627bb1f008 100644 --- a/src/amount.h +++ b/src/amount.h @@ -12,7 +12,6 @@ typedef int64_t CAmount; static const CAmount COIN = 100000000; -static const CAmount CENT = 1000000; /** No amount larger than this (in satoshi) is valid. * diff --git a/src/bech32.cpp b/src/bech32.cpp index c55f22b9b7..d6b29391a9 100644 --- a/src/bech32.cpp +++ b/src/bech32.cpp @@ -62,7 +62,7 @@ uint32_t PolyMod(const data& v) // v, it corresponds to x^2 + v0*x + v1 mod g(x). As 1 mod g(x) = 1, that is the starting value // for `c`. uint32_t c = 1; - for (auto v_i : v) { + for (const auto v_i : v) { // We want to update `c` to correspond to a polynomial with one extra term. If the initial // value of `c` consists of the coefficients of c(x) = f(x) mod g(x), we modify it to // correspond to c'(x) = (f(x) * x + v_i) mod g(x), where v_i is the next input to @@ -149,7 +149,7 @@ std::string Encode(const std::string& hrp, const data& values) { data combined = Cat(values, checksum); std::string ret = hrp + '1'; ret.reserve(ret.size() + combined.size()); - for (auto c : combined) { + for (const auto c : combined) { ret += CHARSET[c]; } return ret; diff --git a/src/bench/bench_bitcoin.cpp b/src/bench/bench_bitcoin.cpp index d7b8083e7c..4fa516cb81 100644 --- a/src/bench/bench_bitcoin.cpp +++ b/src/bench/bench_bitcoin.cpp @@ -82,7 +82,7 @@ int main(int argc, char** argv) return EXIT_FAILURE; } - std::unique_ptr printer(new benchmark::ConsolePrinter()); + std::unique_ptr printer = MakeUnique(); std::string printer_arg = gArgs.GetArg("-printer", DEFAULT_BENCH_PRINTER); if ("plot" == printer_arg) { printer.reset(new benchmark::PlotlyPrinter( diff --git a/src/bench/ccoins_caching.cpp b/src/bench/ccoins_caching.cpp index db303eeead..b8d82c0a89 100644 --- a/src/bench/ccoins_caching.cpp +++ b/src/bench/ccoins_caching.cpp @@ -12,8 +12,8 @@ // FIXME: Dedup with SetupDummyInputs in test/transaction_tests.cpp. // // Helper: create two dummy transactions, each with -// two outputs. The first has 11 and 50 CENT outputs -// paid to a TX_PUBKEY, the second 21 and 22 CENT outputs +// two outputs. The first has 11 and 50 COIN outputs +// paid to a TX_PUBKEY, the second 21 and 22 COIN outputs // paid to a TX_PUBKEYHASH. // static std::vector @@ -31,16 +31,16 @@ SetupDummyInputs(CBasicKeyStore& keystoreRet, CCoinsViewCache& coinsRet) // Create some dummy input transactions dummyTransactions[0].vout.resize(2); - dummyTransactions[0].vout[0].nValue = 11 * CENT; + dummyTransactions[0].vout[0].nValue = 11 * COIN; dummyTransactions[0].vout[0].scriptPubKey << ToByteVector(key[0].GetPubKey()) << OP_CHECKSIG; - dummyTransactions[0].vout[1].nValue = 50 * CENT; + dummyTransactions[0].vout[1].nValue = 50 * COIN; dummyTransactions[0].vout[1].scriptPubKey << ToByteVector(key[1].GetPubKey()) << OP_CHECKSIG; AddCoins(coinsRet, dummyTransactions[0], 0); dummyTransactions[1].vout.resize(2); - dummyTransactions[1].vout[0].nValue = 21 * CENT; + dummyTransactions[1].vout[0].nValue = 21 * COIN; dummyTransactions[1].vout[0].scriptPubKey = GetScriptForDestination(key[2].GetPubKey().GetID()); - dummyTransactions[1].vout[1].nValue = 22 * CENT; + dummyTransactions[1].vout[1].nValue = 22 * COIN; dummyTransactions[1].vout[1].scriptPubKey = GetScriptForDestination(key[3].GetPubKey().GetID()); AddCoins(coinsRet, dummyTransactions[1], 0); @@ -72,7 +72,7 @@ static void CCoinsCaching(benchmark::State& state) t1.vin[2].prevout.n = 1; t1.vin[2].scriptSig << std::vector(65, 0) << std::vector(33, 4); t1.vout.resize(2); - t1.vout[0].nValue = 90 * CENT; + t1.vout[0].nValue = 90 * COIN; t1.vout[0].scriptPubKey << OP_1; // Benchmark. @@ -80,7 +80,7 @@ static void CCoinsCaching(benchmark::State& state) bool success = AreInputsStandard(t1, coins); assert(success); CAmount value = coins.GetValueIn(t1); - assert(value == (50 + 21 + 22) * CENT); + assert(value == (50 + 21 + 22) * COIN); } } diff --git a/src/bench/checkblock.cpp b/src/bench/checkblock.cpp index 6f03581c4b..e325333c01 100644 --- a/src/bench/checkblock.cpp +++ b/src/bench/checkblock.cpp @@ -20,7 +20,7 @@ namespace block_bench { static void DeserializeBlockTest(benchmark::State& state) { CDataStream stream((const char*)block_bench::block413567, - (const char*)&block_bench::block413567[sizeof(block_bench::block413567)], + (const char*)block_bench::block413567 + sizeof(block_bench::block413567), SER_NETWORK, PROTOCOL_VERSION); char a = '\0'; stream.write(&a, 1); // Prevent compaction @@ -36,7 +36,7 @@ static void DeserializeBlockTest(benchmark::State& state) static void DeserializeAndCheckBlockTest(benchmark::State& state) { CDataStream stream((const char*)block_bench::block413567, - (const char*)&block_bench::block413567[sizeof(block_bench::block413567)], + (const char*)block_bench::block413567 + sizeof(block_bench::block413567), SER_NETWORK, PROTOCOL_VERSION); char a = '\0'; stream.write(&a, 1); // Prevent compaction diff --git a/src/bench/coin_selection.cpp b/src/bench/coin_selection.cpp index 0a6f5d85ea..27c23d6834 100644 --- a/src/bench/coin_selection.cpp +++ b/src/bench/coin_selection.cpp @@ -66,7 +66,7 @@ static void add_coin(const CAmount& nValue, int nInput, std::vector CMutableTransaction tx; tx.vout.resize(nInput + 1); tx.vout[nInput].nValue = nValue; - std::unique_ptr wtx(new CWalletTx(&testWallet, MakeTransactionRef(std::move(tx)))); + std::unique_ptr wtx = MakeUnique(&testWallet, MakeTransactionRef(std::move(tx))); set.emplace_back(COutput(wtx.get(), nInput, 0, true, true, true).GetInputCoin(), 0, true, 0, 0); wtxn.emplace_back(std::move(wtx)); } diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index a21805e0a9..b65d4b1871 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include @@ -35,6 +36,7 @@ static void SetupCliArgs() { const auto defaultBaseParams = CreateBaseChainParams(CBaseChainParams::MAIN); const auto testnetBaseParams = CreateBaseChainParams(CBaseChainParams::TESTNET); + const auto regtestBaseParams = CreateBaseChainParams(CBaseChainParams::REGTEST); gArgs.AddArg("-?", "This help message", false, OptionsCategory::OPTIONS); gArgs.AddArg("-version", "Print version and exit", false, OptionsCategory::OPTIONS); @@ -45,9 +47,9 @@ static void SetupCliArgs() gArgs.AddArg("-named", strprintf("Pass named instead of positional arguments (default: %s)", DEFAULT_NAMED), false, OptionsCategory::OPTIONS); gArgs.AddArg("-rpcclienttimeout=", strprintf("Timeout in seconds during HTTP requests, or 0 for no timeout. (default: %d)", DEFAULT_HTTP_CLIENT_TIMEOUT), false, OptionsCategory::OPTIONS); gArgs.AddArg("-rpcconnect=", strprintf("Send commands to node running on (default: %s)", DEFAULT_RPCCONNECT), false, OptionsCategory::OPTIONS); - gArgs.AddArg("-rpccookiefile=", _("Location of the auth cookie. Relative paths will be prefixed by a net-specific datadir location. (default: data dir)"), false, OptionsCategory::OPTIONS); + gArgs.AddArg("-rpccookiefile=", "Location of the auth cookie. Relative paths will be prefixed by a net-specific datadir location. (default: data dir)", false, OptionsCategory::OPTIONS); gArgs.AddArg("-rpcpassword=", "Password for JSON-RPC connections", false, OptionsCategory::OPTIONS); - gArgs.AddArg("-rpcport=", strprintf("Connect to JSON-RPC on (default: %u or testnet: %u)", defaultBaseParams->RPCPort(), testnetBaseParams->RPCPort()), false, OptionsCategory::OPTIONS); + gArgs.AddArg("-rpcport=", strprintf("Connect to JSON-RPC on (default: %u, testnet: %u, regtest: %u)", defaultBaseParams->RPCPort(), testnetBaseParams->RPCPort(), regtestBaseParams->RPCPort()), false, OptionsCategory::OPTIONS); gArgs.AddArg("-rpcuser=", "Username for JSON-RPC connections", false, OptionsCategory::OPTIONS); gArgs.AddArg("-rpcwait", "Wait for RPC server to start", false, OptionsCategory::OPTIONS); gArgs.AddArg("-rpcwallet=", "Send RPC for non-default wallet on RPC server (needs to exactly match corresponding -wallet option passed to feathercoind)", false, OptionsCategory::OPTIONS); @@ -138,11 +140,6 @@ static int AppInitRPC(int argc, char* argv[]) fprintf(stderr, "Error: %s\n", e.what()); return EXIT_FAILURE; } - if (gArgs.GetBoolArg("-rpcssl", false)) - { - fprintf(stderr, "Error: SSL mode for RPC (-rpcssl) is no longer supported.\n"); - return EXIT_FAILURE; - } return CONTINUE_EXECUTION; } @@ -515,6 +512,10 @@ static int CommandLineRPC(int argc, char *argv[]) int main(int argc, char* argv[]) { +#ifdef WIN32 + util::WinCmdLineArgs winArgs; + std::tie(argc, argv) = winArgs.get(); +#endif SetupEnvironment(); if (!SetupNetworking()) { fprintf(stderr, "Error: Initializing networking failed\n"); diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 0cd6fac7d3..d8bfadbe80 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -240,10 +240,10 @@ static void MutateTxAddInput(CMutableTransaction& tx, const std::string& strInpu throw std::runtime_error("TX input missing separator"); // extract and validate TXID - std::string strTxid = vStrInputParts[0]; - if ((strTxid.size() != 64) || !IsHex(strTxid)) + uint256 txid; + if (!ParseHashStr(vStrInputParts[0], txid)) { throw std::runtime_error("invalid TX input txid"); - uint256 txid(uint256S(strTxid)); + } static const unsigned int minTxOutSz = 9; static const unsigned int maxVout = MAX_BLOCK_WEIGHT / (WITNESS_SCALE_FACTOR * minTxOutSz); @@ -385,7 +385,7 @@ static void MutateTxAddOutMultiSig(CMutableTransaction& tx, const std::string& s CScript scriptPubKey = GetScriptForMultisig(required, pubkeys); if (bSegWit) { - for (CPubKey& pubkey : pubkeys) { + for (const CPubKey& pubkey : pubkeys) { if (!pubkey.IsCompressed()) { throw std::runtime_error("Uncompressed pubkeys are not useable for SegWit outputs"); } @@ -590,7 +590,10 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr) if (!prevOut.checkObject(types)) throw std::runtime_error("prevtxs internal object typecheck fail"); - uint256 txid = ParseHashStr(prevOut["txid"].get_str(), "txid"); + uint256 txid; + if (!ParseHashStr(prevOut["txid"].get_str(), txid)) { + throw std::runtime_error("txid must be hexadecimal string (not '" + prevOut["txid"].get_str() + "')"); + } const int nOut = prevOut["vout"].get_int(); if (nOut < 0) diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index 49121dfb58..8ace3d653c 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -183,6 +183,10 @@ static bool AppInit(int argc, char* argv[]) int main(int argc, char* argv[]) { +#ifdef WIN32 + util::WinCmdLineArgs winArgs; + std::tie(argc, argv) = winArgs.get(); +#endif SetupEnvironment(); // Connect bitcoind signal handlers diff --git a/src/blockencodings.cpp b/src/blockencodings.cpp index b17ff3507d..4c57965bec 100644 --- a/src/blockencodings.cpp +++ b/src/blockencodings.cpp @@ -162,7 +162,7 @@ ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& c break; } - LogPrint(BCLog::CMPCTBLOCK, "Initialized PartiallyDownloadedBlock for block %s using a cmpctblock of size %lu\n", cmpctblock.header.GetHash().ToString(), GetSerializeSize(cmpctblock, SER_NETWORK, PROTOCOL_VERSION)); + LogPrint(BCLog::CMPCTBLOCK, "Initialized PartiallyDownloadedBlock for block %s using a cmpctblock of size %lu\n", cmpctblock.header.GetHash().ToString(), GetSerializeSize(cmpctblock, PROTOCOL_VERSION)); return READ_STATUS_OK; } diff --git a/src/chainparams.cpp b/src/chainparams.cpp index ea8c84d914..d5f394f604 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -4,15 +4,18 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include -#include +#include +#include #include #include #include +#include #include -#include +#include +#include static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward) { @@ -42,23 +45,9 @@ static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward); } -void CChainParams::UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout) -{ - consensus.vDeployments[d].nStartTime = nStartTime; - consensus.vDeployments[d].nTimeout = nTimeout; -} - /** * Main network */ -/** - * What makes a good checkpoint block? - * + Is surrounded by blocks with reasonable timestamps - * (no blocks before with a timestamp after, none after with - * timestamp before) - * + Contains no strange transactions - */ - class CMainParams : public CChainParams { public: CMainParams() { @@ -288,7 +277,7 @@ class CTestNetParams : public CChainParams { */ class CRegTestParams : public CChainParams { public: - CRegTestParams() { + explicit CRegTestParams(const ArgsManager& args) { strNetworkID = "regtest"; consensus.nSubsidyHalvingInterval = 256; consensus.BIP34Height = 100000000; // BIP34 has not activated on regtest (far in the future so block v1 are not rejected in tests) @@ -340,6 +329,8 @@ class CRegTestParams : public CChainParams { consensus.nTimeLimit = 0; consensus.nNeoScryptFork = 1524127760; + UpdateVersionBitsParametersFromArgs(args); + genesis = CreateGenesisBlock(1515840634, 0, 0x207fffff, 1, 50 * COIN); consensus.hashGenesisBlock = genesis.GetHash(); assert(consensus.hashGenesisBlock == uint256S("0xc797e583cd93b97b1370a687519606abebd2b84fc4294b0e7584f59187e23ebb")); @@ -375,23 +366,65 @@ class CRegTestParams : public CChainParams { /* enable fallback fee on regtest */ m_fallback_fee_enabled = true; } + + /** + * Allows modifying the Version Bits regtest parameters. + */ + void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout) + { + consensus.vDeployments[d].nStartTime = nStartTime; + consensus.vDeployments[d].nTimeout = nTimeout; + } + void UpdateVersionBitsParametersFromArgs(const ArgsManager& args); }; -static std::unique_ptr globalChainParams; +void CRegTestParams::UpdateVersionBitsParametersFromArgs(const ArgsManager& args) +{ + if (!args.IsArgSet("-vbparams")) return; + + for (const std::string& strDeployment : args.GetArgs("-vbparams")) { + std::vector vDeploymentParams; + boost::split(vDeploymentParams, strDeployment, boost::is_any_of(":")); + if (vDeploymentParams.size() != 3) { + throw std::runtime_error("Version bits parameters malformed, expecting deployment:start:end"); + } + int64_t nStartTime, nTimeout; + if (!ParseInt64(vDeploymentParams[1], &nStartTime)) { + throw std::runtime_error(strprintf("Invalid nStartTime (%s)", vDeploymentParams[1])); + } + if (!ParseInt64(vDeploymentParams[2], &nTimeout)) { + throw std::runtime_error(strprintf("Invalid nTimeout (%s)", vDeploymentParams[2])); + } + bool found = false; + for (int j=0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) { + if (vDeploymentParams[0] == VersionBitsDeploymentInfo[j].name) { + UpdateVersionBitsParameters(Consensus::DeploymentPos(j), nStartTime, nTimeout); + found = true; + LogPrintf("Setting version bits activation parameters for %s to start=%ld, timeout=%ld\n", vDeploymentParams[0], nStartTime, nTimeout); + break; + } + } + if (!found) { + throw std::runtime_error(strprintf("Invalid deployment (%s)", vDeploymentParams[0])); + } + } +} + +static std::unique_ptr globalChainParams; const CChainParams &Params() { assert(globalChainParams); return *globalChainParams; } -std::unique_ptr CreateChainParams(const std::string& chain) +std::unique_ptr CreateChainParams(const std::string& chain) { if (chain == CBaseChainParams::MAIN) return std::unique_ptr(new CMainParams()); else if (chain == CBaseChainParams::TESTNET) return std::unique_ptr(new CTestNetParams()); else if (chain == CBaseChainParams::REGTEST) - return std::unique_ptr(new CRegTestParams()); + return std::unique_ptr(new CRegTestParams(gArgs)); throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain)); } @@ -400,8 +433,3 @@ void SelectParams(const std::string& network) SelectBaseParams(network); globalChainParams = CreateChainParams(network); } - -void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout) -{ - globalChainParams->UpdateVersionBitsParameters(d, nStartTime, nTimeout); -} diff --git a/src/chainparams.h b/src/chainparams.h index 4de5d2a997..0e80027efd 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -81,7 +81,6 @@ class CChainParams const std::vector& FixedSeeds() const { return vFixedSeeds; } const CCheckpointData& Checkpoints() const { return checkpointData; } const ChainTxData& TxData() const { return chainTxData; } - void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout); protected: CChainParams() {} @@ -109,7 +108,7 @@ class CChainParams * @returns a CChainParams* of the chosen chain. * @throws a std::runtime_error if the chain is not supported. */ -std::unique_ptr CreateChainParams(const std::string& chain); +std::unique_ptr CreateChainParams(const std::string& chain); /** * Return the currently selected parameters. This won't change after app @@ -123,9 +122,4 @@ const CChainParams &Params(); */ void SelectParams(const std::string& chain); -/** - * Allows modifying the Version Bits regtest parameters. - */ -void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout); - #endif // BITCOIN_CHAINPARAMS_H diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp index bc928b8ed6..fc4299ebf4 100644 --- a/src/chainparamsbase.cpp +++ b/src/chainparamsbase.cpp @@ -20,6 +20,7 @@ void SetupChainParamsBaseOptions() gArgs.AddArg("-regtest", "Enter regression test mode, which uses a special chain in which blocks can be solved instantly. " "This is intended for regression testing tools and app development.", true, OptionsCategory::CHAINPARAMS); gArgs.AddArg("-testnet", "Use the test chain", false, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-vbparams=deployment:start:end", "Use given start/end times for specified version bits deployment (regtest-only)", true, OptionsCategory::CHAINPARAMS); } static std::unique_ptr globalChainBaseParams; diff --git a/src/coins.cpp b/src/coins.cpp index da1036acfb..f125b483bb 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -244,7 +244,7 @@ bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const return true; } -static const size_t MIN_TRANSACTION_OUTPUT_WEIGHT = WITNESS_SCALE_FACTOR * ::GetSerializeSize(CTxOut(), SER_NETWORK, PROTOCOL_VERSION); +static const size_t MIN_TRANSACTION_OUTPUT_WEIGHT = WITNESS_SCALE_FACTOR * ::GetSerializeSize(CTxOut(), PROTOCOL_VERSION); static const size_t MAX_OUTPUTS_PER_BLOCK = MAX_BLOCK_WEIGHT / MIN_TRANSACTION_OUTPUT_WEIGHT; const Coin& AccessByTxid(const CCoinsViewCache& view, const uint256& txid) diff --git a/src/coins.h b/src/coins.h index 41a422f485..3867a37b39 100644 --- a/src/coins.h +++ b/src/coins.h @@ -285,8 +285,8 @@ class CCoinsViewCache : public CCoinsViewBacked * Note that lightweight clients may not know anything besides the hash of previous transactions, * so may not be able to calculate this. * - * @param[in] tx transaction for which we are checking input total - * @return Sum of value of all inputs (scriptSigs) + * @param[in] tx transaction for which we are checking input total + * @return Sum of value of all inputs (scriptSigs) */ CAmount GetValueIn(const CTransaction& tx) const; diff --git a/src/consensus/tx_verify.cpp b/src/consensus/tx_verify.cpp index be73d0a2f9..0628ec1d47 100644 --- a/src/consensus/tx_verify.cpp +++ b/src/consensus/tx_verify.cpp @@ -164,7 +164,7 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state, bool fChe if (tx.vout.empty()) return state.DoS(10, false, REJECT_INVALID, "bad-txns-vout-empty"); // Size limits (this doesn't take the witness into account, as that hasn't been checked for malleability) - if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT) + if (::GetSerializeSize(tx, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT) return state.DoS(100, false, REJECT_INVALID, "bad-txns-oversize"); // Check for negative or overflow output values diff --git a/src/consensus/validation.h b/src/consensus/validation.h index 008eda69b2..f2e2c3585a 100644 --- a/src/consensus/validation.h +++ b/src/consensus/validation.h @@ -95,16 +95,16 @@ class CValidationState { // weight = (stripped_size * 3) + total_size. static inline int64_t GetTransactionWeight(const CTransaction& tx) { - return ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); + return ::GetSerializeSize(tx, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(tx, PROTOCOL_VERSION); } static inline int64_t GetBlockWeight(const CBlock& block) { - return ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION); + return ::GetSerializeSize(block, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(block, PROTOCOL_VERSION); } static inline int64_t GetTransactionInputWeight(const CTxIn& txin) { // scriptWitness size is added here because witnesses and txins are split up in segwit serialization. - return ::GetSerializeSize(txin, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(txin, SER_NETWORK, PROTOCOL_VERSION) + ::GetSerializeSize(txin.scriptWitness.stack, SER_NETWORK, PROTOCOL_VERSION); + return ::GetSerializeSize(txin, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(txin, PROTOCOL_VERSION) + ::GetSerializeSize(txin.scriptWitness.stack, PROTOCOL_VERSION); } #endif // BITCOIN_CONSENSUS_VALIDATION_H diff --git a/src/core_io.h b/src/core_io.h index d53a45c0cb..2c3b64d81e 100644 --- a/src/core_io.h +++ b/src/core_io.h @@ -25,7 +25,16 @@ std::string ScriptToAsmStr(const CScript& script, const bool fAttemptSighashDeco bool DecodeHexTx(CMutableTransaction& tx, const std::string& hex_tx, bool try_no_witness = false, bool try_witness = true); bool DecodeHexBlk(CBlock&, const std::string& strHexBlk); bool DecodeHexBlockHeader(CBlockHeader&, const std::string& hex_header); -uint256 ParseHashStr(const std::string&, const std::string& strName); + +/** + * Parse a hex string into 256 bits + * @param[in] strHex a hex-formatted, 64-character string + * @param[out] result the result of the parasing + * @returns true if successful, false if not + * + * @see ParseHashV for an RPC-oriented version of this + */ +bool ParseHashStr(const std::string& strHex, uint256& result); std::vector ParseHexUV(const UniValue& v, const std::string& strName); bool DecodePSBT(PartiallySignedTransaction& psbt, const std::string& base64_tx, std::string& error); int ParseSighashString(const UniValue& sighash); diff --git a/src/core_read.cpp b/src/core_read.cpp index b02016c014..301f99bc1c 100644 --- a/src/core_read.cpp +++ b/src/core_read.cpp @@ -193,14 +193,13 @@ bool DecodePSBT(PartiallySignedTransaction& psbt, const std::string& base64_tx, return true; } -uint256 ParseHashStr(const std::string& strHex, const std::string& strName) +bool ParseHashStr(const std::string& strHex, uint256& result) { - if (!IsHex(strHex)) // Note: IsHex("") is false - throw std::runtime_error(strName + " must be hexadecimal string (not '" + strHex + "')"); + if ((strHex.size() != 64) || !IsHex(strHex)) + return false; - uint256 result; result.SetHex(strHex); - return result; + return true; } std::vector ParseHexUV(const UniValue& v, const std::string& strName) diff --git a/src/core_write.cpp b/src/core_write.cpp index 55dcb1661d..b86490716f 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -181,7 +181,7 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, entry.pushKV("txid", tx.GetHash().GetHex()); entry.pushKV("hash", tx.GetWitnessHash().GetHex()); entry.pushKV("version", tx.nVersion); - entry.pushKV("size", (int)::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION)); + entry.pushKV("size", (int)::GetSerializeSize(tx, PROTOCOL_VERSION)); entry.pushKV("vsize", (GetTransactionWeight(tx) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR); entry.pushKV("weight", GetTransactionWeight(tx)); entry.pushKV("locktime", (int64_t)tx.nLockTime); diff --git a/src/cuckoocache.h b/src/cuckoocache.h index 15f6873961..4d0b094fa2 100644 --- a/src/cuckoocache.h +++ b/src/cuckoocache.h @@ -397,7 +397,7 @@ class cache std::array locs = compute_hashes(e); // Make sure we have not already inserted this element // If we have, make sure that it does not get deleted - for (uint32_t loc : locs) + for (const uint32_t loc : locs) if (table[loc] == e) { please_keep(loc); epoch_flags[loc] = last_epoch; @@ -405,7 +405,7 @@ class cache } for (uint8_t depth = 0; depth < depth_limit; ++depth) { // First try to insert to an empty slot, if one exists - for (uint32_t loc : locs) { + for (const uint32_t loc : locs) { if (!collection_flags.bit_is_set(loc)) continue; table[loc] = std::move(e); @@ -467,7 +467,7 @@ class cache inline bool contains(const Element& e, const bool erase) const { std::array locs = compute_hashes(e); - for (uint32_t loc : locs) + for (const uint32_t loc : locs) if (table[loc] == e) { if (erase) allow_erase(loc); diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp index f5fb715800..58d8cc2c9d 100644 --- a/src/dbwrapper.cpp +++ b/src/dbwrapper.cpp @@ -78,7 +78,7 @@ static void SetMaxOpenFiles(leveldb::Options *options) { // do not interfere with select() loops. On 64-bit Unix hosts this value is // also OK, because up to that amount LevelDB will use an mmap // implementation that does not use extra file descriptors (the fds are - // closed after being mmaped). + // closed after being mmap'ed). // // Increasing the value beyond the default is dangerous because LevelDB will // fall back to a non-mmap implementation when the file count is too large. diff --git a/src/dummywallet.cpp b/src/dummywallet.cpp new file mode 100644 index 0000000000..3714187a96 --- /dev/null +++ b/src/dummywallet.cpp @@ -0,0 +1,51 @@ +// Copyright (c) 2018 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include +#include + +class CWallet; + +class DummyWalletInit : public WalletInitInterface { +public: + + bool HasWalletSupport() const override {return false;} + void AddWalletOptions() const override; + bool ParameterInteraction() const override {return true;} + void RegisterRPC(CRPCTable &) const override {} + bool Verify() const override {return true;} + bool Open() const override {LogPrintf("No wallet support compiled in!\n"); return true;} + void Start(CScheduler& scheduler) const override {} + void Flush() const override {} + void Stop() const override {} + void Close() const override {} +}; + +void DummyWalletInit::AddWalletOptions() const +{ + std::vector opts = {"-addresstype", "-changetype", "-disablewallet", "-discardfee=", "-fallbackfee=", + "-keypool=", "-mintxfee=", "-paytxfee=", "-rescan", "-salvagewallet", "-spendzeroconfchange", "-txconfirmtarget=", + "-upgradewallet", "-wallet=", "-walletbroadcast", "-walletdir=", "-walletnotify=", "-walletrbf", "-zapwallettxes=", + "-dblogsize=", "-flushwallet", "-privdb", "-walletrejectlongchains"}; + gArgs.AddHiddenArgs(opts); +} + +const WalletInitInterface& g_wallet_init_interface = DummyWalletInit(); + +std::vector> GetWallets() +{ + throw std::logic_error("Wallet function called in non-wallet build."); +} + +namespace interfaces { + +class Wallet; + +std::unique_ptr MakeWallet(const std::shared_ptr& wallet) +{ + throw std::logic_error("Wallet function called in non-wallet build."); +} + +} // namespace interfaces diff --git a/src/fs.cpp b/src/fs.cpp index 2dbc13643b..df79b5e3df 100644 --- a/src/fs.cpp +++ b/src/fs.cpp @@ -11,7 +11,12 @@ namespace fsbridge { FILE *fopen(const fs::path& p, const char *mode) { +#ifndef WIN32 return ::fopen(p.string().c_str(), mode); +#else + std::wstring_convert,wchar_t> utf8_cvt; + return ::_wfopen(p.wstring().c_str(), utf8_cvt.from_bytes(mode).c_str()); +#endif } #ifndef WIN32 @@ -92,4 +97,20 @@ bool FileLock::TryLock() } #endif +std::string get_filesystem_error_message(const fs::filesystem_error& e) +{ +#ifndef WIN32 + return e.what(); +#else + // Convert from Multi Byte to utf-16 + std::string mb_string(e.what()); + int size = MultiByteToWideChar(CP_ACP, 0, mb_string.c_str(), mb_string.size(), nullptr, 0); + + std::wstring utf16_string(size, L'\0'); + MultiByteToWideChar(CP_ACP, 0, mb_string.c_str(), mb_string.size(), &*utf16_string.begin(), size); + // Convert from utf-16 to utf-8 + return std::wstring_convert, wchar_t>().to_bytes(utf16_string); +#endif +} + } // fsbridge diff --git a/src/fs.h b/src/fs.h index 5a28d9a81c..a7074f446a 100644 --- a/src/fs.h +++ b/src/fs.h @@ -10,7 +10,6 @@ #include #include -#include /** Filesystem operations and types */ namespace fs = boost::filesystem; @@ -38,6 +37,8 @@ namespace fsbridge { void* hFile = (void*)-1; // INVALID_HANDLE_VALUE #endif }; + + std::string get_filesystem_error_message(const fs::filesystem_error& e); }; #endif // BITCOIN_FS_H diff --git a/src/httprpc.cpp b/src/httprpc.cpp index 38f6e79643..4064251c71 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -30,7 +31,7 @@ static const char* WWW_AUTH_HEADER_DATA = "Basic realm=\"jsonrpc\""; class HTTPRPCTimer : public RPCTimerBase { public: - HTTPRPCTimer(struct event_base* eventBase, std::function& func, int64_t millis) : + HTTPRPCTimer(struct event_base* eventBase, std::function& func, int64_t millis) : ev(eventBase, false, func) { struct timeval tv; @@ -52,7 +53,7 @@ class HTTPRPCTimerInterface : public RPCTimerInterface { return "HTTP"; } - RPCTimerBase* NewTimer(std::function& func, int64_t millis) override + RPCTimerBase* NewTimer(std::function& func, int64_t millis) override { return new HTTPRPCTimer(base, func, millis); } @@ -240,10 +241,9 @@ bool StartHTTPRPC() return false; RegisterHTTPHandler("/", true, HTTPReq_JSONRPC); -#ifdef ENABLE_WALLET - // ifdef can be removed once we switch to better endpoint support and API versioning - RegisterHTTPHandler("/wallet/", false, HTTPReq_JSONRPC); -#endif + if (g_wallet_init_interface.HasWalletSupport()) { + RegisterHTTPHandler("/wallet/", false, HTTPReq_JSONRPC); + } struct event_base* eventBase = EventBase(); assert(eventBase); httpRPCTimerInterface = MakeUnique(eventBase); @@ -260,9 +260,9 @@ void StopHTTPRPC() { LogPrint(BCLog::RPC, "Stopping HTTP RPC server\n"); UnregisterHTTPHandler("/", true); -#ifdef ENABLE_WALLET - UnregisterHTTPHandler("/wallet/", false); -#endif + if (g_wallet_init_interface.HasWalletSupport()) { + UnregisterHTTPHandler("/wallet/", false); + } if (httpRPCTimerInterface) { RPCUnsetTimerInterface(httpRPCTimerInterface.get()); httpRPCTimerInterface.reset(); diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 326f7f6b64..c29f7a4375 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -352,13 +352,6 @@ bool InitHTTPServer() if (!InitHTTPAllowList()) return false; - if (gArgs.GetBoolArg("-rpcssl", false)) { - uiInterface.ThreadSafeMessageBox( - "SSL mode for RPC (-rpcssl) is no longer supported.", - "", CClientUIInterface::MSG_ERROR); - return false; - } - // Redirect libevent's logging to our own log event_set_log_callback(&libevent_log_cb); // Update libevent's log handling. Returns false if our version of @@ -505,7 +498,7 @@ static void httpevent_callback_fn(evutil_socket_t, short, void* data) delete self; } -HTTPEvent::HTTPEvent(struct event_base* base, bool _deleteWhenTriggered, const std::function& _handler): +HTTPEvent::HTTPEvent(struct event_base* base, bool _deleteWhenTriggered, const std::function& _handler): deleteWhenTriggered(_deleteWhenTriggered), handler(_handler) { ev = event_new(base, -1, 0, httpevent_callback_fn, this); diff --git a/src/httpserver.h b/src/httpserver.h index 67c6a88314..63f96734f8 100644 --- a/src/httpserver.h +++ b/src/httpserver.h @@ -134,7 +134,7 @@ class HTTPEvent * deleteWhenTriggered deletes this event object after the event is triggered (and the handler called) * handler is the handler to call when the event is triggered. */ - HTTPEvent(struct event_base* base, bool deleteWhenTriggered, const std::function& handler); + HTTPEvent(struct event_base* base, bool deleteWhenTriggered, const std::function& handler); ~HTTPEvent(); /** Trigger the event. If tv is 0, trigger it immediately. Otherwise trigger it after @@ -143,7 +143,7 @@ class HTTPEvent void trigger(struct timeval* tv); bool deleteWhenTriggered; - std::function handler; + std::function handler; private: struct event* ev; }; diff --git a/src/index/txindex.cpp b/src/index/txindex.cpp index c85030e18e..f606c8993c 100644 --- a/src/index/txindex.cpp +++ b/src/index/txindex.cpp @@ -250,7 +250,7 @@ bool TxIndex::WriteBlock(const CBlock& block, const CBlockIndex* pindex) vPos.reserve(block.vtx.size()); for (const auto& tx : block.vtx) { vPos.emplace_back(tx->GetHash(), pos); - pos.nTxOffset += ::GetSerializeSize(*tx, SER_DISK, CLIENT_VERSION); + pos.nTxOffset += ::GetSerializeSize(*tx, CLIENT_VERSION); } return m_db->WriteTxs(vPos); } diff --git a/src/init.cpp b/src/init.cpp index 880d128d9c..70e9e23a86 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -75,33 +75,6 @@ static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false; std::unique_ptr g_connman; std::unique_ptr peerLogic; -#if !(ENABLE_WALLET) -class DummyWalletInit : public WalletInitInterface { -public: - - void AddWalletOptions() const override; - bool ParameterInteraction() const override {return true;} - void RegisterRPC(CRPCTable &) const override {} - bool Verify() const override {return true;} - bool Open() const override {LogPrintf("No wallet support compiled in!\n"); return true;} - void Start(CScheduler& scheduler) const override {} - void Flush() const override {} - void Stop() const override {} - void Close() const override {} -}; - -void DummyWalletInit::AddWalletOptions() const -{ - std::vector opts = {"-addresstype", "-changetype", "-disablewallet", "-discardfee=", "-fallbackfee=", - "-keypool=", "-mintxfee=", "-paytxfee=", "-rescan", "-salvagewallet", "-spendzeroconfchange", "-txconfirmtarget=", - "-upgradewallet", "-wallet=", "-walletbroadcast", "-walletdir=", "-walletnotify=", "-walletrbf", "-zapwallettxes=", - "-dblogsize=", "-flushwallet", "-privdb", "-walletrejectlongchains"}; - gArgs.AddHiddenArgs(opts); -} - -const WalletInitInterface& g_wallet_init_interface = DummyWalletInit(); -#endif - #ifdef WIN32 // Win32 LevelDB doesn't use filedescriptors, and the ones used for // accessing block files don't count towards the fd_set size limit @@ -344,12 +317,14 @@ void SetupServerArgs() { const auto defaultBaseParams = CreateBaseChainParams(CBaseChainParams::MAIN); const auto testnetBaseParams = CreateBaseChainParams(CBaseChainParams::TESTNET); + const auto regtestBaseParams = CreateBaseChainParams(CBaseChainParams::REGTEST); const auto defaultChainParams = CreateChainParams(CBaseChainParams::MAIN); const auto testnetChainParams = CreateChainParams(CBaseChainParams::TESTNET); + const auto regtestChainParams = CreateChainParams(CBaseChainParams::REGTEST); // Hidden Options - std::vector hidden_args = {"-rpcssl", "-benchmark", "-h", "-help", "-socks", "-tor", "-debugnet", "-whitelistalwaysrelay", - "-prematurewitness", "-walletprematurewitness", "-promiscuousmempoolflags", "-blockminsize", "-dbcrashratio", "-forcecompactdb", "-usehd", + std::vector hidden_args = {"-h", "-help", + "-dbcrashratio", "-forcecompactdb", // GUI args. These will be overwritten by SetupUIArgs for the GUI "-allowselfsignedrootcertificates", "-choosedatadir", "-lang=", "-min", "-resetguisettings", "-rootcertificates=", "-splash", "-uiplatform"}; @@ -367,7 +342,7 @@ void SetupServerArgs() 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("-debuglogfile=", strprintf("Specify location of debug log file. Relative paths will be prefixed by a net-specific datadir location. (0 to disable; default: %s)", DEFAULT_DEBUGLOGFILE), 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("-feefilter", strprintf("Tell other nodes to filter invs to us by our mempool min fee (default: %u)", DEFAULT_FEEFILTER), true, 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); @@ -387,7 +362,7 @@ void SetupServerArgs() "Warning: Reverting this setting requires re-downloading the entire blockchain. " "(default: 0 = disable pruning blocks, 1 = allow manual pruning via RPC, >=%u = automatically prune block files to stay under the specified target size in MiB)", MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024), false, OptionsCategory::OPTIONS); gArgs.AddArg("-reindex", "Rebuild chain state and block index from the blk*.dat files on disk", false, OptionsCategory::OPTIONS); - gArgs.AddArg("-reindex-chainstate", "Rebuild chain state from the currently indexed blocks", false, OptionsCategory::OPTIONS); + gArgs.AddArg("-reindex-chainstate", "Rebuild chain state from the currently indexed blocks. When in pruning mode or if blocks on disk might be corrupted, use full -reindex instead.", false, OptionsCategory::OPTIONS); #ifndef WIN32 gArgs.AddArg("-sysperms", "Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)", false, OptionsCategory::OPTIONS); #else @@ -399,7 +374,7 @@ void SetupServerArgs() gArgs.AddArg("-banscore=", strprintf("Threshold for disconnecting misbehaving peers (default: %u)", DEFAULT_BANSCORE_THRESHOLD), false, OptionsCategory::CONNECTION); gArgs.AddArg("-bantime=", strprintf("Number of seconds to keep misbehaving peers from reconnecting (default: %u)", DEFAULT_MISBEHAVING_BANTIME), false, OptionsCategory::CONNECTION); gArgs.AddArg("-bind=", "Bind to given address and always listen on it. Use [host]:port notation for IPv6", false, OptionsCategory::CONNECTION); - gArgs.AddArg("-connect=", "Connect only to the specified node; -connect=0 disables automatic connections (the rules for this peer are the same as for -addnode). This option can be specified multiple times to connect to multiple nodes.", false, OptionsCategory::CONNECTION); + gArgs.AddArg("-connect=", "Connect only to the specified node; -noconnect disables automatic connections (the rules for this peer are the same as for -addnode). This option can be specified multiple times to connect to multiple nodes.", false, OptionsCategory::CONNECTION); gArgs.AddArg("-discover", "Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)", false, OptionsCategory::CONNECTION); gArgs.AddArg("-dns", strprintf("Allow DNS lookups for -addnode, -seednode and -connect (default: %u)", DEFAULT_NAME_LOOKUP), false, OptionsCategory::CONNECTION); gArgs.AddArg("-dnsseed", "Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect used)", false, OptionsCategory::CONNECTION); @@ -413,12 +388,12 @@ void SetupServerArgs() gArgs.AddArg("-maxsendbuffer=", strprintf("Maximum per-connection send buffer, *1000 bytes (default: %u)", DEFAULT_MAXSENDBUFFER), false, OptionsCategory::CONNECTION); gArgs.AddArg("-maxtimeadjustment", strprintf("Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds)", DEFAULT_MAX_TIME_ADJUSTMENT), false, OptionsCategory::CONNECTION); gArgs.AddArg("-maxuploadtarget=", strprintf("Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)", DEFAULT_MAX_UPLOAD_TARGET), false, OptionsCategory::CONNECTION); - gArgs.AddArg("-onion=", "Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)", false, OptionsCategory::CONNECTION); + gArgs.AddArg("-onion=", "Use separate SOCKS5 proxy to reach peers via Tor hidden services, set -noonion to disable (default: -proxy)", false, OptionsCategory::CONNECTION); gArgs.AddArg("-onlynet=", "Make outgoing connections only through network (ipv4, ipv6 or onion). Incoming connections are not affected by this option. This option can be specified multiple times to allow multiple networks.", false, OptionsCategory::CONNECTION); gArgs.AddArg("-peerbloomfilters", strprintf("Support filtering of blocks and transaction with bloom filters (default: %u)", DEFAULT_PEERBLOOMFILTERS), false, OptionsCategory::CONNECTION); gArgs.AddArg("-permitbaremultisig", strprintf("Relay non-P2SH multisig (default: %u)", DEFAULT_PERMIT_BAREMULTISIG), false, OptionsCategory::CONNECTION); - gArgs.AddArg("-port=", strprintf("Listen for connections on (default: %u or testnet: %u)", defaultChainParams->GetDefaultPort(), testnetChainParams->GetDefaultPort()), false, OptionsCategory::CONNECTION); - gArgs.AddArg("-proxy=", "Connect through SOCKS5 proxy", false, OptionsCategory::CONNECTION); + gArgs.AddArg("-port=", strprintf("Listen for connections on (default: %u, testnet: %u, regtest: %u)", defaultChainParams->GetDefaultPort(), testnetChainParams->GetDefaultPort(), regtestChainParams->GetDefaultPort()), false, OptionsCategory::CONNECTION); + gArgs.AddArg("-proxy=", "Connect through SOCKS5 proxy, set -noproxy to disable (default: disabled)", false, OptionsCategory::CONNECTION); gArgs.AddArg("-proxyrandomize", strprintf("Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)", DEFAULT_PROXYRANDOMIZE), false, OptionsCategory::CONNECTION); gArgs.AddArg("-seednode=", "Connect to a node to retrieve peer addresses, and disconnect. This option can be specified multiple times to connect to multiple nodes.", false, OptionsCategory::CONNECTION); gArgs.AddArg("-timeout=", strprintf("Specify connection timeout in milliseconds (minimum: 1, default: %d)", DEFAULT_CONNECT_TIMEOUT), false, OptionsCategory::CONNECTION); @@ -452,9 +427,16 @@ void SetupServerArgs() #endif gArgs.AddArg("-checkblocks=", strprintf("How many blocks to check at startup (default: %u, 0 = all)", DEFAULT_CHECKBLOCKS), true, OptionsCategory::DEBUG_TEST); - gArgs.AddArg("-checklevel=", strprintf("How thorough the block verification of -checkblocks is (0-4, default: %u)", DEFAULT_CHECKLEVEL), true, OptionsCategory::DEBUG_TEST); - gArgs.AddArg("-checkblockindex", strprintf("Do a full consistency check for mapBlockIndex, setBlockIndexCandidates, chainActive and mapBlocksUnlinked occasionally. (default: %u)", defaultChainParams->DefaultConsistencyChecks()), true, OptionsCategory::DEBUG_TEST); - gArgs.AddArg("-checkmempool=", strprintf("Run checks every transactions (default: %u)", defaultChainParams->DefaultConsistencyChecks()), true, OptionsCategory::DEBUG_TEST); + gArgs.AddArg("-checklevel=", strprintf("How thorough the block verification of -checkblocks is: " + "level 0 reads the blocks from disk, " + "level 1 verifies block validity, " + "level 2 verifies undo data, " + "level 3 checks disconnection of tip blocks, " + "and level 4 tries to reconnect the blocks, " + "each level includes the checks of the previous levels " + "(0-4, default: %u)", DEFAULT_CHECKLEVEL), true, OptionsCategory::DEBUG_TEST); + gArgs.AddArg("-checkblockindex", strprintf("Do a full consistency check for mapBlockIndex, setBlockIndexCandidates, chainActive and mapBlocksUnlinked occasionally. (default: %u, regtest: %u)", defaultChainParams->DefaultConsistencyChecks(), regtestChainParams->DefaultConsistencyChecks()), true, OptionsCategory::DEBUG_TEST); + gArgs.AddArg("-checkmempool=", strprintf("Run checks every transactions (default: %u, regtest: %u)", defaultChainParams->DefaultConsistencyChecks(), regtestChainParams->DefaultConsistencyChecks()), true, OptionsCategory::DEBUG_TEST); gArgs.AddArg("-checkpoints", strprintf("Disable expensive verification for known chain history (default: %u)", DEFAULT_CHECKPOINTS_ENABLED), true, OptionsCategory::DEBUG_TEST); gArgs.AddArg("-deprecatedrpc=", "Allows deprecated RPC method(s) to be used", true, OptionsCategory::DEBUG_TEST); gArgs.AddArg("-dropmessagestest=", "Randomly drop 1 of every network messages", true, OptionsCategory::DEBUG_TEST); @@ -464,12 +446,11 @@ void SetupServerArgs() gArgs.AddArg("-limitancestorsize=", strprintf("Do not accept transactions whose size with all in-mempool ancestors exceeds kilobytes (default: %u)", DEFAULT_ANCESTOR_SIZE_LIMIT), true, OptionsCategory::DEBUG_TEST); gArgs.AddArg("-limitdescendantcount=", strprintf("Do not accept transactions if any ancestor would have or more in-mempool descendants (default: %u)", DEFAULT_DESCENDANT_LIMIT), true, OptionsCategory::DEBUG_TEST); gArgs.AddArg("-limitdescendantsize=", strprintf("Do not accept transactions if any ancestor would have more than kilobytes of in-mempool descendants (default: %u).", DEFAULT_DESCENDANT_SIZE_LIMIT), true, OptionsCategory::DEBUG_TEST); - gArgs.AddArg("-vbparams=deployment:start:end", "Use given start/end times for specified version bits deployment (regtest-only)", true, OptionsCategory::DEBUG_TEST); gArgs.AddArg("-addrmantest", "Allows to test address relay on localhost", true, OptionsCategory::DEBUG_TEST); - gArgs.AddArg("-debug=", strprintf("Output debugging information (default: %u, supplying is optional)", 0) + ". " + + gArgs.AddArg("-debug=", "Output debugging information (default: -nodebug, supplying is optional). " "If is not supplied or if = 1, output all debugging information. can be: " + ListLogCategories() + ".", false, OptionsCategory::DEBUG_TEST); gArgs.AddArg("-debugexclude=", strprintf("Exclude debugging information for a category. Can be used in conjunction with -debug=1 to output debug logs for all categories except one or more specified categories."), false, OptionsCategory::DEBUG_TEST); - gArgs.AddArg("-help-debug", "Show all debugging options (usage: --help -help-debug)", false, OptionsCategory::DEBUG_TEST); + gArgs.AddArg("-help-debug", "Print help message with debugging options and exit", false, OptionsCategory::DEBUG_TEST); gArgs.AddArg("-logips", strprintf("Include IP addresses in debug output (default: %u)", DEFAULT_LOGIPS), false, OptionsCategory::DEBUG_TEST); gArgs.AddArg("-logtimestamps", strprintf("Prepend debug output with timestamp (default: %u)", DEFAULT_LOGTIMESTAMPS), false, OptionsCategory::DEBUG_TEST); gArgs.AddArg("-logtimemicros", strprintf("Add microsecond precision to debug timestamps (default: %u)", DEFAULT_LOGTIMEMICROS), true, OptionsCategory::DEBUG_TEST); @@ -479,7 +460,7 @@ void SetupServerArgs() gArgs.AddArg("-maxtxfee=", strprintf("Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s)", CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MAXFEE)), false, OptionsCategory::DEBUG_TEST); gArgs.AddArg("-printpriority", strprintf("Log transaction fee per kB when mining blocks (default: %u)", DEFAULT_PRINTPRIORITY), true, OptionsCategory::DEBUG_TEST); - gArgs.AddArg("-printtoconsole", "Send trace/debug info to console (default: 1 when no -daemon. To disable logging to file, set debuglogfile=0)", false, OptionsCategory::DEBUG_TEST); + gArgs.AddArg("-printtoconsole", "Send trace/debug info to console (default: 1 when no -daemon. To disable logging to file, set -nodebuglogfile)", false, OptionsCategory::DEBUG_TEST); gArgs.AddArg("-shrinkdebugfile", "Shrink debug.log file on client startup (default: 1 when no -debug)", false, OptionsCategory::DEBUG_TEST); gArgs.AddArg("-uacomment=", "Append comment to the user agent string", false, OptionsCategory::DEBUG_TEST); @@ -508,7 +489,7 @@ void SetupServerArgs() gArgs.AddArg("-rpcbind=[:port]", "Bind to given address to listen for JSON-RPC connections. This option is ignored unless -rpcallowip is also passed. Port is optional and overrides -rpcport. Use [host]:port notation for IPv6. This option can be specified multiple times (default: 127.0.0.1 and ::1 i.e., localhost, or if -rpcallowip has been specified, 0.0.0.0 and :: i.e., all addresses)", false, OptionsCategory::RPC); gArgs.AddArg("-rpccookiefile=", "Location of the auth cookie. Relative paths will be prefixed by a net-specific datadir location. (default: data dir)", false, OptionsCategory::RPC); gArgs.AddArg("-rpcpassword=", "Password for JSON-RPC connections", false, OptionsCategory::RPC); - gArgs.AddArg("-rpcport=", strprintf("Listen for JSON-RPC connections on (default: %u or testnet: %u)", defaultBaseParams->RPCPort(), testnetBaseParams->RPCPort()), false, OptionsCategory::RPC); + gArgs.AddArg("-rpcport=", strprintf("Listen for JSON-RPC connections on (default: %u, testnet: %u, regtest: %u)", defaultBaseParams->RPCPort(), testnetBaseParams->RPCPort(), regtestBaseParams->RPCPort()), false, OptionsCategory::RPC); gArgs.AddArg("-rpcserialversion", strprintf("Sets the serialization of raw transaction or block hex returned in non-verbose mode, non-segwit(0) or segwit(1) (default: %d)", DEFAULT_RPC_SERIALIZE_VERSION), false, OptionsCategory::RPC); gArgs.AddArg("-rpcservertimeout=", strprintf("Timeout during HTTP requests (default: %d)", DEFAULT_HTTP_SERVER_TIMEOUT), true, OptionsCategory::RPC); gArgs.AddArg("-rpcthreads=", strprintf("Set the number of threads to service RPC calls (default: %d)", DEFAULT_HTTP_THREADS), false, OptionsCategory::RPC); @@ -710,7 +691,7 @@ static void ThreadImport(std::vector vImportFiles) * Ensure that Bitcoin is running in a usable environment with all * necessary library support. */ -static bool InitSanityCheck(void) +static bool InitSanityCheck() { if(!ECC_InitSanityCheck()) { InitError("Elliptic curve cryptography sanity check failure. Aborting."); @@ -984,25 +965,6 @@ bool AppInitParameterInteraction() } } - // Check for -debugnet - if (gArgs.GetBoolArg("-debugnet", false)) - InitWarning(_("Unsupported argument -debugnet ignored, use -debug=net.")); - // Check for -socks - as this is a privacy risk to continue, exit here - if (gArgs.IsArgSet("-socks")) - return InitError(_("Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.")); - // Check for -tor - as this is a privacy risk to continue, exit here - if (gArgs.GetBoolArg("-tor", false)) - return InitError(_("Unsupported argument -tor found, use -onion.")); - - if (gArgs.GetBoolArg("-benchmark", false)) - InitWarning(_("Unsupported argument -benchmark ignored, use -debug=bench.")); - - if (gArgs.GetBoolArg("-whitelistalwaysrelay", false)) - InitWarning(_("Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay.")); - - if (gArgs.IsArgSet("-blockminsize")) - InitWarning("Unsupported argument -blockminsize ignored."); - // Checkmempool and checkblockindex default to true in regtest mode int ratio = std::min(std::max(gArgs.GetArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0), 1000000); if (ratio != 0) { @@ -1145,40 +1107,6 @@ bool AppInitParameterInteraction() fEnableReplacement = (std::find(vstrReplacementModes.begin(), vstrReplacementModes.end(), "fee") != vstrReplacementModes.end()); } - if (gArgs.IsArgSet("-vbparams")) { - // Allow overriding version bits parameters for testing - if (!chainparams.MineBlocksOnDemand()) { - return InitError("Version bits parameters may only be overridden on regtest."); - } - for (const std::string& strDeployment : gArgs.GetArgs("-vbparams")) { - std::vector vDeploymentParams; - boost::split(vDeploymentParams, strDeployment, boost::is_any_of(":")); - if (vDeploymentParams.size() != 3) { - return InitError("Version bits parameters malformed, expecting deployment:start:end"); - } - int64_t nStartTime, nTimeout; - if (!ParseInt64(vDeploymentParams[1], &nStartTime)) { - return InitError(strprintf("Invalid nStartTime (%s)", vDeploymentParams[1])); - } - if (!ParseInt64(vDeploymentParams[2], &nTimeout)) { - return InitError(strprintf("Invalid nTimeout (%s)", vDeploymentParams[2])); - } - bool found = false; - for (int j=0; j<(int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) - { - if (vDeploymentParams[0].compare(VersionBitsDeploymentInfo[j].name) == 0) { - UpdateVersionBitsParameters(Consensus::DeploymentPos(j), nStartTime, nTimeout); - found = true; - LogPrintf("Setting version bits activation parameters for %s to start=%ld, timeout=%ld\n", vDeploymentParams[0], nStartTime, nTimeout); - break; - } - } - if (!found) { - return InitError(strprintf("Invalid deployment (%s)", vDeploymentParams[0])); - } - } - } - if (gArgs.IsArgSet("-checkpointkey")) // Checkpoint master priv key { if (!SetCheckpointPrivKey(gArgs.GetArg("-checkpointkey", ""))) @@ -1256,7 +1184,19 @@ bool AppInitMain() LogPrintf("Startup time: %s\n", FormatISO8601DateTime(GetTime())); LogPrintf("Default data directory %s\n", GetDefaultDataDir().string()); LogPrintf("Using data directory %s\n", GetDataDir().string()); - LogPrintf("Using config file %s\n", GetConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME)).string()); + + // Only log conf file usage message if conf file actually exists. + fs::path config_file_path = GetConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME)); + if (fs::exists(config_file_path)) { + LogPrintf("Config file: %s\n", config_file_path.string()); + } else if (gArgs.IsArgSet("-conf")) { + // Warn if no conf file exists at path provided by user + InitWarning(strprintf(_("The specified config file %s does not exist\n"), config_file_path.string())); + } else { + // Not categorizing as "Warning" because it's the default behavior + LogPrintf("Config file: %s (not found, skipping)\n", config_file_path.string()); + } + LogPrintf("Using at most %i automatic connections (%i file descriptors available)\n", nMaxConnections, nFD); // Warn about relative -datadir path. diff --git a/src/init.h b/src/init.h index 0c85d3c9dc..c58ba5cfd3 100644 --- a/src/init.h +++ b/src/init.h @@ -13,9 +13,6 @@ class CScheduler; class CWallet; -class WalletInitInterface; -extern const WalletInitInterface& g_wallet_init_interface; - namespace boost { class thread_group; diff --git a/src/interfaces/node.cpp b/src/interfaces/node.cpp index 1da58fe487..d95b41657c 100644 --- a/src/interfaces/node.cpp +++ b/src/interfaces/node.cpp @@ -32,19 +32,18 @@ #if defined(HAVE_CONFIG_H) #include #endif -#ifdef ENABLE_WALLET -#include -#include -#define CHECK_WALLET(x) x -#else -#define CHECK_WALLET(x) throw std::logic_error("Wallet function called in non-wallet build.") -#endif #include #include #include +class CWallet; +std::vector> GetWallets(); + namespace interfaces { + +class Wallet; + namespace { class NodeImpl : public Node @@ -221,15 +220,11 @@ class NodeImpl : public Node } std::vector> getWallets() override { -#ifdef ENABLE_WALLET std::vector> wallets; for (const std::shared_ptr& wallet : GetWallets()) { wallets.emplace_back(MakeWallet(wallet)); } return wallets; -#else - throw std::logic_error("Node::getWallets() called in non-wallet build."); -#endif } std::unique_ptr handleInitMessage(InitMessageFn fn) override { @@ -249,8 +244,7 @@ class NodeImpl : public Node } std::unique_ptr handleLoadWallet(LoadWalletFn fn) override { - CHECK_WALLET( - return MakeHandler(::uiInterface.LoadWallet_connect([fn](std::shared_ptr wallet) { fn(MakeWallet(wallet)); }))); + return MakeHandler(::uiInterface.LoadWallet_connect([fn](std::shared_ptr wallet) { fn(MakeWallet(wallet)); })); } std::unique_ptr handleNotifyNumConnectionsChanged(NotifyNumConnectionsChangedFn fn) override { diff --git a/src/interfaces/wallet.h b/src/interfaces/wallet.h index 44240a5726..7aa91f37e1 100644 --- a/src/interfaces/wallet.h +++ b/src/interfaces/wallet.h @@ -366,8 +366,8 @@ struct WalletTxOut bool is_spent = false; }; -//! Return implementation of Wallet interface. This function will be undefined -//! in builds where ENABLE_WALLET is false. +//! Return implementation of Wallet interface. This function is defined in +//! dummywallet.cpp and throws if the wallet component is not compiled. std::unique_ptr MakeWallet(const std::shared_ptr& wallet); } // namespace interfaces diff --git a/src/key.h b/src/key.h index a3baa421e6..0f695c07b7 100644 --- a/src/key.h +++ b/src/key.h @@ -181,12 +181,12 @@ struct CExtKey { }; /** Initialize the elliptic curve support. May not be called twice without calling ECC_Stop first. */ -void ECC_Start(void); +void ECC_Start(); /** Deinitialize the elliptic curve support. No-op if ECC_Start wasn't called first. */ -void ECC_Stop(void); +void ECC_Stop(); /** Check that required EC support is available at runtime. */ -bool ECC_InitSanityCheck(void); +bool ECC_InitSanityCheck(); #endif // BITCOIN_KEY_H diff --git a/src/logging.h b/src/logging.h index 6400b131c2..0c8e7f5291 100644 --- a/src/logging.h +++ b/src/logging.h @@ -125,42 +125,31 @@ std::vector ListActiveLogCategories(); /** Return true if str parses as a log category and set the flag */ bool GetLogCategory(BCLog::LogFlags& flag, const std::string& str); -/** Get format string from VA_ARGS for error reporting */ -template std::string FormatStringFromLogArgs(const char *fmt, const Args&... args) { return fmt; } - -static inline void MarkUsed() {} -template static inline void MarkUsed(const T& t, const Args&... args) -{ - (void)t; - MarkUsed(args...); -} - // Be conservative when using LogPrintf/error or other things which // unconditionally log to debug.log! It should not be the case that an inbound // peer can fill up a user's disk with debug.log entries. -#ifdef USE_COVERAGE -#define LogPrintf(...) do { MarkUsed(__VA_ARGS__); } while(0) -#define LogPrint(category, ...) do { MarkUsed(__VA_ARGS__); } while(0) -#else -#define LogPrintf(...) do { \ - if (g_logger->Enabled()) { \ - std::string _log_msg_; /* Unlikely name to avoid shadowing variables */ \ - try { \ - _log_msg_ = tfm::format(__VA_ARGS__); \ - } catch (tinyformat::format_error &fmterr) { \ - /* Original format string will have newline so don't add one here */ \ - _log_msg_ = "Error \"" + std::string(fmterr.what()) + "\" while formatting log message: " + FormatStringFromLogArgs(__VA_ARGS__); \ - } \ - g_logger->LogPrintStr(_log_msg_); \ - } \ -} while(0) - -#define LogPrint(category, ...) do { \ - if (LogAcceptCategory((category))) { \ - LogPrintf(__VA_ARGS__); \ - } \ -} while(0) -#endif +template +static inline void LogPrintf(const char* fmt, const Args&... args) +{ + if (g_logger->Enabled()) { + std::string log_msg; + try { + log_msg = tfm::format(fmt, args...); + } catch (tinyformat::format_error& fmterr) { + /* Original format string will have newline so don't add one here */ + log_msg = "Error \"" + std::string(fmterr.what()) + "\" while formatting log message: " + fmt; + } + g_logger->LogPrintStr(log_msg); + } +} + +template +static inline void LogPrint(const BCLog::LogFlags& category, const Args&... args) +{ + if (LogAcceptCategory((category))) { + LogPrintf(args...); + } +} #endif // BITCOIN_LOGGING_H diff --git a/src/net.cpp b/src/net.cpp index d749e539a8..a6448541f8 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -344,7 +344,7 @@ CNode* CConnman::FindNode(const CService& addr) bool CConnman::CheckIncomingNonce(uint64_t nonce) { LOCK(cs_vNodes); - for (CNode* pnode : vNodes) { + for (const CNode* pnode : vNodes) { if (!pnode->fSuccessfullyConnected && !pnode->fInbound && pnode->GetLocalNonce() == nonce) return false; } @@ -1227,7 +1227,7 @@ void CConnman::ThreadSocketHandler() if(vNodesSize != nPrevNodeCount) { nPrevNodeCount = vNodesSize; if(clientInterface) - clientInterface->NotifyNumConnectionsChanged(nPrevNodeCount); + clientInterface->NotifyNumConnectionsChanged(vNodesSize); } // @@ -1614,7 +1614,7 @@ void CConnman::ThreadDNSAddressSeed() LOCK(cs_vNodes); int nRelevant = 0; - for (auto pnode : vNodes) { + for (const CNode* pnode : vNodes) { nRelevant += pnode->fSuccessfullyConnected && !pnode->fFeeler && !pnode->fOneShot && !pnode->m_manual_connection && !pnode->fInbound; } if (nRelevant >= 2) { @@ -1733,7 +1733,7 @@ int CConnman::GetExtraOutboundCount() int nOutbound = 0; { LOCK(cs_vNodes); - for (CNode* pnode : vNodes) { + for (const CNode* pnode : vNodes) { if (!pnode->fInbound && !pnode->m_manual_connection && !pnode->fFeeler && !pnode->fDisconnect && !pnode->fOneShot && pnode->fSuccessfullyConnected) { ++nOutbound; } @@ -1803,7 +1803,7 @@ void CConnman::ThreadOpenConnections(const std::vector connect) std::set > setConnected; { LOCK(cs_vNodes); - for (CNode* pnode : vNodes) { + for (const CNode* pnode : vNodes) { if (!pnode->fInbound && !pnode->m_manual_connection) { // Netgroups for inbound and addnode peers are not excluded because our goal here // is to not use multiple of our limited outbound slots on a single netgroup @@ -2167,7 +2167,7 @@ void Discover() } } } -#else +#elif (HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS) // Get local host ip struct ifaddrs* myaddrs; if (getifaddrs(&myaddrs) == 0) diff --git a/src/net.h b/src/net.h index 3e6fcf1010..ccd5c8bc0e 100644 --- a/src/net.h +++ b/src/net.h @@ -149,6 +149,7 @@ class CConnman nLocalServices = connOptions.nLocalServices; nMaxConnections = connOptions.nMaxConnections; nMaxOutbound = std::min(connOptions.nMaxOutbound, connOptions.nMaxConnections); + m_use_addrman_outgoing = connOptions.m_use_addrman_outgoing; nMaxAddnode = connOptions.nMaxAddnode; nMaxFeeler = connOptions.nMaxFeeler; nBestHeight = connOptions.nBestHeight; @@ -174,6 +175,7 @@ class CConnman void Stop(); void Interrupt(); bool GetNetworkActive() const { return fNetworkActive; }; + bool GetUseAddrmanOutgoing() const { return m_use_addrman_outgoing; }; void SetNetworkActive(bool active); void OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound = nullptr, const char *strDest = nullptr, bool fOneShot = false, bool fFeeler = false, bool manual_connection = false); bool CheckIncomingNonce(uint64_t nonce); @@ -416,6 +418,7 @@ class CConnman int nMaxOutbound; int nMaxAddnode; int nMaxFeeler; + bool m_use_addrman_outgoing; std::atomic nBestHeight; CClientUIInterface* clientInterface; NetEventsInterface* m_msgproc; diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 0ded7b508b..d436da121a 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -884,7 +884,7 @@ void PeerLogicValidation::BlockConnected(const std::shared_ptr& pb // Erase orphan transactions included or precluded by this block if (vOrphanErase.size()) { int nErased = 0; - for (uint256 &orphanHash : vOrphanErase) { + for (const uint256& orphanHash : vOrphanErase) { nErased += EraseOrphanTx(orphanHash); } LogPrint(BCLog::MEMPOOL, "Erased %d orphan tx included or conflicted by block\n", nErased); @@ -2296,7 +2296,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr } } - for (uint256 hash : vEraseQueue) + for (const uint256& hash : vEraseQueue) EraseOrphanTx(hash); } else if (fMissingInputs) @@ -3216,8 +3216,6 @@ void PeerLogicValidation::EvictExtraOutboundPeers(int64_t time_in_seconds) NodeId worst_peer = -1; int64_t oldest_block_announcement = std::numeric_limits::max(); - LOCK(cs_main); - connman->ForEachNode([&](CNode* pnode) { AssertLockHeld(cs_main); @@ -3265,6 +3263,8 @@ void PeerLogicValidation::EvictExtraOutboundPeers(int64_t time_in_seconds) void PeerLogicValidation::CheckForStaleTipAndEvictPeers(const Consensus::Params &consensusParams) { + LOCK(cs_main); + if (connman == nullptr) return; int64_t time_in_seconds = GetTime(); @@ -3272,10 +3272,9 @@ void PeerLogicValidation::CheckForStaleTipAndEvictPeers(const Consensus::Params EvictExtraOutboundPeers(time_in_seconds); if (time_in_seconds > m_stale_tip_check_time) { - LOCK(cs_main); // Check whether our tip is stale, and if so, allow using an extra // outbound peer - if (TipMayBeStale(consensusParams)) { + if (!fImporting && !fReindex && connman->GetNetworkActive() && connman->GetUseAddrmanOutgoing() && TipMayBeStale(consensusParams)) { LogPrintf("Potential stale tip detected, will try using extra outbound peer (last tip update: %d seconds ago)\n", time_in_seconds - g_last_tip_update); connman->SetTryNewOutboundPeer(true); } else if (connman->GetTryNewOutboundPeer()) { diff --git a/src/net_processing.h b/src/net_processing.h index f16d00032e..0113e25f7e 100644 --- a/src/net_processing.h +++ b/src/net_processing.h @@ -9,13 +9,16 @@ #include #include #include +#include + +extern CCriticalSection cs_main; /** Default for -maxorphantx, maximum number of orphan transactions kept in memory */ static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100; /** Default number of orphan+recently-replaced txn to keep around for block reconstruction */ static const unsigned int DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN = 100; /** Default for BIP61 (sending reject messages) */ -static constexpr bool DEFAULT_ENABLE_BIP61 = true; +static constexpr bool DEFAULT_ENABLE_BIP61{false}; class PeerLogicValidation final : public CValidationInterface, public NetEventsInterface { private: @@ -65,10 +68,10 @@ class PeerLogicValidation final : public CValidationInterface, public NetEventsI /** Evict extra outbound peers. If we think our tip may be stale, connect to an extra outbound */ void CheckForStaleTipAndEvictPeers(const Consensus::Params &consensusParams); /** If we have extra outbound peers, try to disconnect the one with the oldest block announcement */ - void EvictExtraOutboundPeers(int64_t time_in_seconds); + void EvictExtraOutboundPeers(int64_t time_in_seconds) EXCLUSIVE_LOCKS_REQUIRED(cs_main); private: - int64_t m_stale_tip_check_time; //! Next time to check for stale tip + int64_t m_stale_tip_check_time; //!< Next time to check for stale tip /** Enable BIP61 (sending reject messages) */ const bool m_enable_bip61; diff --git a/src/netbase.cpp b/src/netbase.cpp index 4b63757f3d..04d5eb12c8 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -17,6 +17,8 @@ #ifndef WIN32 #include +#else +#include #endif #if !defined(MSG_NOSIGNAL) @@ -189,10 +191,10 @@ enum SOCKSVersion: uint8_t { /** Values defined for METHOD in RFC1928 */ enum SOCKS5Method: uint8_t { - NOAUTH = 0x00, //! No authentication required - GSSAPI = 0x01, //! GSSAPI - USER_PASS = 0x02, //! Username/password - NO_ACCEPTABLE = 0xff, //! No acceptable methods + NOAUTH = 0x00, //!< No authentication required + GSSAPI = 0x01, //!< GSSAPI + USER_PASS = 0x02, //!< Username/password + NO_ACCEPTABLE = 0xff, //!< No acceptable methods }; /** Values defined for CMD in RFC1928 */ @@ -204,15 +206,15 @@ enum SOCKS5Command: uint8_t { /** Values defined for REP in RFC1928 */ enum SOCKS5Reply: uint8_t { - SUCCEEDED = 0x00, //! Succeeded - GENFAILURE = 0x01, //! General failure - NOTALLOWED = 0x02, //! Connection not allowed by ruleset - NETUNREACHABLE = 0x03, //! Network unreachable - HOSTUNREACHABLE = 0x04, //! Network unreachable - CONNREFUSED = 0x05, //! Connection refused - TTLEXPIRED = 0x06, //! TTL expired - CMDUNSUPPORTED = 0x07, //! Command not supported - ATYPEUNSUPPORTED = 0x08, //! Address type not supported + SUCCEEDED = 0x00, //!< Succeeded + GENFAILURE = 0x01, //!< General failure + NOTALLOWED = 0x02, //!< Connection not allowed by ruleset + NETUNREACHABLE = 0x03, //!< Network unreachable + HOSTUNREACHABLE = 0x04, //!< Network unreachable + CONNREFUSED = 0x05, //!< Connection refused + TTLEXPIRED = 0x06, //!< TTL expired + CMDUNSUPPORTED = 0x07, //!< Command not supported + ATYPEUNSUPPORTED = 0x08, //!< Address type not supported }; /** Values defined for ATYPE in RFC1928 */ @@ -649,13 +651,13 @@ bool LookupSubNet(const char* pszName, CSubNet& ret) #ifdef WIN32 std::string NetworkErrorString(int err) { - char buf[256]; + wchar_t buf[256]; buf[0] = 0; - if(FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, + if(FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, nullptr, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - buf, sizeof(buf), nullptr)) + buf, ARRAYSIZE(buf), nullptr)) { - return strprintf("%s (%d)", buf, err); + return strprintf("%s (%d)", std::wstring_convert,wchar_t>().to_bytes(buf), err); } else { diff --git a/src/noui.cpp b/src/noui.cpp index 3a1ec2d050..df4bfabb66 100644 --- a/src/noui.cpp +++ b/src/noui.cpp @@ -14,7 +14,7 @@ #include -static bool noui_ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style) +bool noui_ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style) { bool fSecure = style & CClientUIInterface::SECURE; style &= ~CClientUIInterface::SECURE; @@ -41,19 +41,18 @@ static bool noui_ThreadSafeMessageBox(const std::string& message, const std::str return false; } -static bool noui_ThreadSafeQuestion(const std::string& /* ignored interactive message */, const std::string& message, const std::string& caption, unsigned int style) +bool noui_ThreadSafeQuestion(const std::string& /* ignored interactive message */, const std::string& message, const std::string& caption, unsigned int style) { return noui_ThreadSafeMessageBox(message, caption, style); } -static void noui_InitMessage(const std::string& message) +void noui_InitMessage(const std::string& message) { LogPrintf("init message: %s\n", message); } void noui_connect() { - // Connect bitcoind signal handlers uiInterface.ThreadSafeMessageBox_connect(noui_ThreadSafeMessageBox); uiInterface.ThreadSafeQuestion_connect(noui_ThreadSafeQuestion); uiInterface.InitMessage_connect(noui_InitMessage); diff --git a/src/noui.h b/src/noui.h index ff16cc9aa8..169c2bbd7f 100644 --- a/src/noui.h +++ b/src/noui.h @@ -5,6 +5,16 @@ #ifndef BITCOIN_NOUI_H #define BITCOIN_NOUI_H -extern void noui_connect(); +#include + +/** Non-GUI handler, which logs and prints messages. */ +bool noui_ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style); +/** Non-GUI handler, which logs and prints questions. */ +bool noui_ThreadSafeQuestion(const std::string& /* ignored interactive message */, const std::string& message, const std::string& caption, unsigned int style); +/** Non-GUI handler, which only logs a message. */ +void noui_InitMessage(const std::string& message); + +/** Connect all bitcoind signal handlers */ +void noui_connect(); #endif // BITCOIN_NOUI_H diff --git a/src/policy/fees.h b/src/policy/fees.h index 2733c5a7de..90f159b48c 100644 --- a/src/policy/fees.h +++ b/src/policy/fees.h @@ -50,9 +50,9 @@ std::string StringForFeeReason(FeeReason reason); /* Used to determine type of fee estimation requested */ enum class FeeEstimateMode { - UNSET, //! Use default settings based on other criteria - ECONOMICAL, //! Force estimateSmartFee to use non-conservative estimates - CONSERVATIVE, //! Force estimateSmartFee to use conservative estimates + UNSET, //!< Use default settings based on other criteria + ECONOMICAL, //!< Force estimateSmartFee to use non-conservative estimates + CONSERVATIVE, //!< Force estimateSmartFee to use conservative estimates }; bool FeeModeFromString(const std::string& mode_string, FeeEstimateMode& fee_estimate_mode); diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 47d6644551..ac1b75edb4 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -34,7 +34,7 @@ CAmount GetDustThreshold(const CTxOut& txout, const CFeeRate& dustRelayFeeIn) if (txout.scriptPubKey.IsUnspendable()) return 0; - size_t nSize = GetSerializeSize(txout, SER_DISK, 0); + size_t nSize = GetSerializeSize(txout); int witnessversion = 0; std::vector witnessprogram; diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index 59865a5eab..bdb470470e 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -93,7 +93,7 @@ CAmount CTransaction::GetValueOut() const unsigned int CTransaction::GetTotalSize() const { - return ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION); + return ::GetSerializeSize(*this, PROTOCOL_VERSION); } std::string CTransaction::ToString() const diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index fb9db508d2..6d8b530f69 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -64,7 +64,7 @@ class CTxIn COutPoint prevout; CScript scriptSig; uint32_t nSequence; - CScriptWitness scriptWitness; //! Only serialized through CTransaction + CScriptWitness scriptWitness; //!< Only serialized through CTransaction /* Setting nSequence to this value for every input in a transaction * disables nLockTime. */ diff --git a/src/qt/README.md b/src/qt/README.md index 3ec538b4f4..0eb18f7cd5 100644 --- a/src/qt/README.md +++ b/src/qt/README.md @@ -64,8 +64,8 @@ Represents the view to a single wallet. * `callback.h` * `guiconstants.h`: UI colors, app name, etc * `guiutil.h`: several helper functions -* `macdockiconhandler.(h/cpp)` -* `macdockiconhandler.(h/cpp)`: display notifications in macOS +* `macdockiconhandler.(h/mm)`: macOS dock icon handler +* `macnotificationhandler.(h/mm)`: display notifications in macOS ## Contribute diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index 57d7005554..819fbb3d93 100644 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -123,16 +123,15 @@ void AskPassphraseDialog::accept() { QMessageBox::warning(this, tr("Wallet encrypted"), "" + - tr("%1 will close now to finish the encryption process. " + tr("Your wallet is now encrypted. " "Remember that encrypting your wallet cannot fully protect " - "your feathercoins from being stolen by malware infecting your computer.").arg(tr(PACKAGE_NAME)) + + "your feathercoins from being stolen by malware infecting your computer.") + "

      " + tr("IMPORTANT: Any previous backups you have made of your wallet file " "should be replaced with the newly generated, encrypted wallet file. " "For security reasons, previous backups of the unencrypted wallet file " "will become useless as soon as you start using the new, encrypted wallet.") + "
      "); - QApplication::quit(); } else { diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index c1c4775e5b..72873a3da5 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -71,9 +72,9 @@ Q_DECLARE_METATYPE(bool*) Q_DECLARE_METATYPE(CAmount) Q_DECLARE_METATYPE(uint256) -static void InitMessage(const std::string &message) +static void InitMessage(const std::string& message) { - LogPrintf("init message: %s\n", message); + noui_InitMessage(message); } /** Translate string to current locale using Qt. */ @@ -416,7 +417,7 @@ void BitcoinApplication::requestShutdown() #ifdef ENABLE_WALLET window->removeAllWallets(); - for (WalletModel *walletModel : m_wallet_models) { + for (const WalletModel* walletModel : m_wallet_models) { delete walletModel; } m_wallet_models.clear(); @@ -551,6 +552,10 @@ static void SetupUIArgs() #ifndef BITCOIN_QT_TEST int main(int argc, char *argv[]) { +#ifdef WIN32 + util::WinCmdLineArgs winArgs; + std::tie(argc, argv) = winArgs.get(); +#endif SetupEnvironment(); std::unique_ptr node = interfaces::MakeNode(); @@ -585,7 +590,7 @@ int main(int argc, char *argv[]) // Need to pass name here as CAmount is a typedef (see http://qt-project.org/doc/qt-5/qmetatype.html#qRegisterMetaType) // IMPORTANT if it is no longer a typedef use the normal variant above qRegisterMetaType< CAmount >("CAmount"); - qRegisterMetaType< std::function >("std::function"); + qRegisterMetaType< std::function >("std::function"); #ifdef ENABLE_WALLET qRegisterMetaType("WalletModel*"); #endif diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 95cb88d244..919f1dce5c 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -614,8 +615,11 @@ void BitcoinGUI::createTrayIconMenu() #endif // Configuration of the tray icon (or dock icon) icon menu +#ifndef Q_OS_MAC + // Note: On Mac, the dock icon's menu already has show / hide action. trayIconMenu->addAction(toggleHideAction); trayIconMenu->addSeparator(); +#endif trayIconMenu->addAction(sendCoinsMenuAction); trayIconMenu->addAction(receiveCoinsMenuAction); trayIconMenu->addSeparator(); @@ -1214,8 +1218,11 @@ void BitcoinGUI::showModalOverlay() modalOverlay->toggleVisibility(); } -static bool ThreadSafeMessageBox(BitcoinGUI *gui, const std::string& message, const std::string& caption, unsigned int style) +static bool ThreadSafeMessageBox(BitcoinGUI* gui, const std::string& message, const std::string& caption, unsigned int style) { + // Redundantly log and print message in non-gui fashion + noui_ThreadSafeMessageBox(message, caption, style); + bool modal = (style & CClientUIInterface::MODAL); // The SECURE flag has no effect in the Qt GUI. // bool secure = (style & CClientUIInterface::SECURE); @@ -1273,7 +1280,7 @@ void UnitDisplayStatusBarControl::mousePressEvent(QMouseEvent *event) void UnitDisplayStatusBarControl::createContextMenu() { menu = new QMenu(this); - for (BitcoinUnits::Unit u : BitcoinUnits::availableUnits()) + for (const BitcoinUnits::Unit u : BitcoinUnits::availableUnits()) { QAction *menuAction = new QAction(QString(BitcoinUnits::longName(u)), this); menuAction->setData(QVariant(u)); diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index b27ceae9fa..0ce71a07d2 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -38,8 +38,6 @@ #include #endif -#include - #include #include #include @@ -62,8 +60,6 @@ #include #endif -static fs::detail::utf8_codecvt_facet utf8; - namespace GUIUtil { QString dateTimeStr(const QDateTime &date) @@ -548,40 +544,28 @@ bool SetStartOnSystemStartup(bool fAutoStart) CoInitialize(nullptr); // Get a pointer to the IShellLink interface. - IShellLink* psl = nullptr; + IShellLinkW* psl = nullptr; HRESULT hres = CoCreateInstance(CLSID_ShellLink, nullptr, - CLSCTX_INPROC_SERVER, IID_IShellLink, + CLSCTX_INPROC_SERVER, IID_IShellLinkW, reinterpret_cast(&psl)); if (SUCCEEDED(hres)) { // Get the current executable path - TCHAR pszExePath[MAX_PATH]; - GetModuleFileName(nullptr, pszExePath, sizeof(pszExePath)); + WCHAR pszExePath[MAX_PATH]; + GetModuleFileNameW(nullptr, pszExePath, ARRAYSIZE(pszExePath)); // Start client minimized QString strArgs = "-min"; // Set -testnet /-regtest options strArgs += QString::fromStdString(strprintf(" -testnet=%d -regtest=%d", gArgs.GetBoolArg("-testnet", false), gArgs.GetBoolArg("-regtest", false))); -#ifdef UNICODE - boost::scoped_array args(new TCHAR[strArgs.length() + 1]); - // Convert the QString to TCHAR* - strArgs.toWCharArray(args.get()); - // Add missing '\0'-termination to string - args[strArgs.length()] = '\0'; -#endif - // Set the path to the shortcut target psl->SetPath(pszExePath); - PathRemoveFileSpec(pszExePath); + PathRemoveFileSpecW(pszExePath); psl->SetWorkingDirectory(pszExePath); psl->SetShowCmd(SW_SHOWMINNOACTIVE); -#ifndef UNICODE - psl->SetArguments(strArgs.toStdString().c_str()); -#else - psl->SetArguments(args.get()); -#endif + psl->SetArguments(strArgs.toStdWString().c_str()); // Query IShellLink for the IPersistFile interface for // saving the shortcut in persistent storage. @@ -589,11 +573,8 @@ bool SetStartOnSystemStartup(bool fAutoStart) hres = psl->QueryInterface(IID_IPersistFile, reinterpret_cast(&ppf)); if (SUCCEEDED(hres)) { - WCHAR pwsz[MAX_PATH]; - // Ensure that the string is ANSI. - MultiByteToWideChar(CP_ACP, 0, StartupShortcutPath().string().c_str(), -1, pwsz, MAX_PATH); // Save the link by calling IPersistFile::Save. - hres = ppf->Save(pwsz, TRUE); + hres = ppf->Save(StartupShortcutPath().wstring().c_str(), TRUE); ppf->Release(); psl->Release(); CoUninitialize(); @@ -781,12 +762,12 @@ void setClipboard(const QString& str) fs::path qstringToBoostPath(const QString &path) { - return fs::path(path.toStdString(), utf8); + return fs::path(path.toStdString()); } QString boostPathToQString(const fs::path &path) { - return QString::fromStdString(path.string(utf8)); + return QString::fromStdString(path.string()); } QString formatDurationStr(int secs) diff --git a/src/qt/macnotificationhandler.h b/src/qt/macnotificationhandler.h index 23993adc2e..03c744c12e 100644 --- a/src/qt/macnotificationhandler.h +++ b/src/qt/macnotificationhandler.h @@ -19,7 +19,7 @@ class MacNotificationHandler : public QObject void showNotification(const QString &title, const QString &text); /** check if OS can handle UserNotifications */ - bool hasUserNotificationCenterSupport(void); + bool hasUserNotificationCenterSupport(); static MacNotificationHandler *instance(); }; diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp index 944bcc8ad0..a989988c45 100644 --- a/src/qt/paymentrequestplus.cpp +++ b/src/qt/paymentrequestplus.cpp @@ -142,7 +142,6 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c if (result != 1) { int error = X509_STORE_CTX_get_error(store_ctx); // For testing payment requests, we allow self signed root certs! - // This option is just shown in the UI options, if -help-debug is enabled. if (!(error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT && gArgs.GetBoolArg("-allowselfsignedrootcertificates", DEFAULT_SELFSIGNED_ROOTCERTS))) { throw SSLVerifyError(X509_verify_cert_error_string(error)); } else { diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp index 59a751fb12..8cfedca57f 100644 --- a/src/qt/peertablemodel.cpp +++ b/src/qt/peertablemodel.cpp @@ -65,7 +65,7 @@ class PeerTablePriv interfaces::Node::NodesStats nodes_stats; node.getNodesStats(nodes_stats); cachedNodeStats.reserve(nodes_stats.size()); - for (auto& node_stats : nodes_stats) + for (const auto& node_stats : nodes_stats) { CNodeCombinedStats stats; stats.nodeStats = std::get<0>(node_stats); diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index ad13b20ebe..3857befdf2 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -101,7 +101,7 @@ class QtRPCTimerBase: public QObject, public RPCTimerBase { Q_OBJECT public: - QtRPCTimerBase(std::function& _func, int64_t millis): + QtRPCTimerBase(std::function& _func, int64_t millis): func(_func) { timer.setSingleShot(true); @@ -111,7 +111,7 @@ class QtRPCTimerBase: public QObject, public RPCTimerBase ~QtRPCTimerBase() {} private: QTimer timer; - std::function func; + std::function func; }; class QtRPCTimerInterface: public RPCTimerInterface @@ -119,7 +119,7 @@ class QtRPCTimerInterface: public RPCTimerInterface public: ~QtRPCTimerInterface() {} const char *Name() { return "Qt"; } - RPCTimerBase* NewTimer(std::function& func, int64_t millis) + RPCTimerBase* NewTimer(std::function& func, int64_t millis) { return new QtRPCTimerBase(func, millis); } diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index bc5c069c7c..b8b648ecf0 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -334,7 +334,7 @@ void SendCoinsDialog::on_sendButton_clicked() questionString.append("
      "); CAmount totalAmount = currentTransaction.getTotalTransactionAmount() + txFee; QStringList alternativeUnits; - for (BitcoinUnits::Unit u : BitcoinUnits::availableUnits()) + for (const BitcoinUnits::Unit u : BitcoinUnits::availableUnits()) { if(u != model->getOptionsModel()->getDisplayUnit()) alternativeUnits.append(BitcoinUnits::formatHtmlWithUnit(u, totalAmount)); diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index 30be2cb5cb..0e64b8e789 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -200,7 +200,7 @@ void SplashScreen::unsubscribeFromCoreSignals() // Disconnect signals from client m_handler_init_message->disconnect(); m_handler_show_progress->disconnect(); - for (auto& handler : m_connected_wallet_handlers) { + for (const auto& handler : m_connected_wallet_handlers) { handler->disconnect(); } m_connected_wallet_handlers.clear(); diff --git a/src/qt/test/util.h b/src/qt/test/util.h index 324386c139..5363c94547 100644 --- a/src/qt/test/util.h +++ b/src/qt/test/util.h @@ -5,7 +5,7 @@ * Press "Ok" button in message box dialog. * * @param text - Optionally store dialog text. - * @param msec - Number of miliseconds to pause before triggering the callback. + * @param msec - Number of milliseconds to pause before triggering the callback. */ void ConfirmMessage(QString* text = nullptr, int msec = 0); diff --git a/src/qt/trafficgraphwidget.cpp b/src/qt/trafficgraphwidget.cpp index f087e7569c..3aed3f2b97 100644 --- a/src/qt/trafficgraphwidget.cpp +++ b/src/qt/trafficgraphwidget.cpp @@ -141,10 +141,10 @@ void TrafficGraphWidget::updateRates() } float tmax = 0.0f; - for (float f : vSamplesIn) { + for (const float f : vSamplesIn) { if(f > tmax) tmax = f; } - for (float f : vSamplesOut) { + for (const float f : vSamplesOut) { if(f > tmax) tmax = f; } fMax = tmax; diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 885049f456..9877a83730 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -152,13 +152,13 @@ QString TransactionDesc::toHTML(interfaces::Node& node, interfaces::Wallet& wall else { isminetype fAllFromMe = ISMINE_SPENDABLE; - for (isminetype mine : wtx.txin_is_mine) + for (const isminetype mine : wtx.txin_is_mine) { if(fAllFromMe > mine) fAllFromMe = mine; } isminetype fAllToMe = ISMINE_SPENDABLE; - for (isminetype mine : wtx.txout_is_mine) + for (const isminetype mine : wtx.txout_is_mine) { if(fAllToMe > mine) fAllToMe = mine; } diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index c767de5eda..d1a7527ac7 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -77,14 +77,14 @@ QList TransactionRecord::decomposeTransaction(const interface { bool involvesWatchAddress = false; isminetype fAllFromMe = ISMINE_SPENDABLE; - for (isminetype mine : wtx.txin_is_mine) + for (const isminetype mine : wtx.txin_is_mine) { if(mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true; if(fAllFromMe > mine) fAllFromMe = mine; } isminetype fAllToMe = ISMINE_SPENDABLE; - for (isminetype mine : wtx.txout_is_mine) + for (const isminetype mine : wtx.txout_is_mine) { if(mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true; if(fAllToMe > mine) fAllToMe = mine; diff --git a/src/rest.cpp b/src/rest.cpp index 12358cf50d..1850c0b7a6 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -105,15 +105,6 @@ static std::string AvailableDataFormatsString() return formats; } -static bool ParseHashStr(const std::string& strReq, uint256& v) -{ - if (!IsHex(strReq) || (strReq.size() != 64)) - return false; - - v.SetHex(strReq); - return true; -} - static bool CheckWarmup(HTTPRequest* req) { std::string statusmessage; @@ -157,13 +148,13 @@ static bool rest_headers(HTTPRequest* req, } } - CDataStream ssHeader(SER_NETWORK, PROTOCOL_VERSION); - for (const CBlockIndex *pindex : headers) { - ssHeader << pindex->GetBlockHeader(); - } - switch (rf) { case RetFormat::BINARY: { + CDataStream ssHeader(SER_NETWORK, PROTOCOL_VERSION); + for (const CBlockIndex *pindex : headers) { + ssHeader << pindex->GetBlockHeader(); + } + std::string binaryHeader = ssHeader.str(); req->WriteHeader("Content-Type", "application/octet-stream"); req->WriteReply(HTTP_OK, binaryHeader); @@ -171,6 +162,11 @@ static bool rest_headers(HTTPRequest* req, } case RetFormat::HEX: { + CDataStream ssHeader(SER_NETWORK, PROTOCOL_VERSION); + for (const CBlockIndex *pindex : headers) { + ssHeader << pindex->GetBlockHeader(); + } + std::string strHex = HexStr(ssHeader.begin(), ssHeader.end()) + "\n"; req->WriteHeader("Content-Type", "text/plain"); req->WriteReply(HTTP_OK, strHex); @@ -224,11 +220,10 @@ static bool rest_block(HTTPRequest* req, return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); } - CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); - ssBlock << block; - switch (rf) { case RetFormat::BINARY: { + CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); + ssBlock << block; std::string binaryBlock = ssBlock.str(); req->WriteHeader("Content-Type", "application/octet-stream"); req->WriteReply(HTTP_OK, binaryBlock); @@ -236,6 +231,8 @@ static bool rest_block(HTTPRequest* req, } case RetFormat::HEX: { + CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); + ssBlock << block; std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()) + "\n"; req->WriteHeader("Content-Type", "text/plain"); req->WriteReply(HTTP_OK, strHex); @@ -360,11 +357,11 @@ static bool rest_tx(HTTPRequest* req, const std::string& strURIPart) if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true)) return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); - CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); - ssTx << tx; - switch (rf) { case RetFormat::BINARY: { + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); + ssTx << tx; + std::string binaryTx = ssTx.str(); req->WriteHeader("Content-Type", "application/octet-stream"); req->WriteReply(HTTP_OK, binaryTx); @@ -372,6 +369,9 @@ static bool rest_tx(HTTPRequest* req, const std::string& strURIPart) } case RetFormat::HEX: { + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); + ssTx << tx; + std::string strHex = HexStr(ssTx.begin(), ssTx.end()) + "\n"; req->WriteHeader("Content-Type", "text/plain"); req->WriteReply(HTTP_OK, strHex); @@ -464,7 +464,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) oss >> fCheckMemPool; oss >> vOutPoints; } - } catch (const std::ios_base::failure& e) { + } catch (const std::ios_base::failure&) { // abort in case of unreadable binary data return RESTERR(req, HTTP_BAD_REQUEST, "Parse error"); } diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index a144d9cb74..e207f935cc 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -123,8 +124,8 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx if (chainActive.Contains(blockindex)) confirmations = chainActive.Height() - blockindex->nHeight + 1; result.pushKV("confirmations", confirmations); - result.pushKV("strippedsize", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS)); - result.pushKV("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)); + result.pushKV("strippedsize", (int)::GetSerializeSize(block, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS)); + result.pushKV("size", (int)::GetSerializeSize(block, PROTOCOL_VERSION)); result.pushKV("weight", (int)::GetBlockWeight(block)); result.pushKV("height", blockindex->nHeight); result.pushKV("version", block.nVersion); @@ -262,7 +263,7 @@ static UniValue waitforblock(const JSONRPCRequest& request) ); int timeout = 0; - uint256 hash = uint256S(request.params[0].get_str()); + uint256 hash(ParseHashV(request.params[0], "blockhash")); if (!request.params[1].isNull()) timeout = request.params[1].get_int(); @@ -428,7 +429,7 @@ static void entryToJSON(UniValue &info, const CTxMemPoolEntry &e) EXCLUSIVE_LOCK UniValue spent(UniValue::VARR); const CTxMemPool::txiter &it = mempool.mapTx.find(tx.GetHash()); const CTxMemPool::setEntries &setChildren = mempool.GetMemPoolChildren(it); - for (const CTxMemPool::txiter &childiter : setChildren) { + for (CTxMemPool::txiter childiter : setChildren) { spent.push_back(childiter->GetTx().GetHash().ToString()); } @@ -729,8 +730,7 @@ static UniValue getblockheader(const JSONRPCRequest& request) LOCK(cs_main); - std::string strHash = request.params[0].get_str(); - uint256 hash(uint256S(strHash)); + uint256 hash(ParseHashV(request.params[0], "hash")); bool fVerbose = true; if (!request.params[1].isNull()) @@ -824,8 +824,7 @@ static UniValue getblock(const JSONRPCRequest& request) LOCK(cs_main); - std::string strHash = request.params[0].get_str(); - uint256 hash(uint256S(strHash)); + uint256 hash(ParseHashV(request.params[0], "blockhash")); int verbosity = 1; if (!request.params[1].isNull()) { @@ -862,20 +861,18 @@ UniValue getcheckpoint(const JSONRPCRequest& request) "getcheckpoint\n" "Show info of synchronized checkpoint.\n"); - UniValue result(UniValue::VARR); - UniValue entry(UniValue::VOBJ); + UniValue result(UniValue::VOBJ); CBlockIndex* pindexCheckpoint; - entry.push_back(Pair("synccheckpoint", hashSyncCheckpoint.ToString().c_str())); + result.pushKV("synccheckpoint", hashSyncCheckpoint.ToString().c_str()); if (mapBlockIndex.count(hashSyncCheckpoint)) { pindexCheckpoint = mapBlockIndex[hashSyncCheckpoint]; - entry.push_back(Pair("height", pindexCheckpoint->nHeight)); - entry.push_back(Pair("timestamp", (boost::int64_t) pindexCheckpoint->GetBlockTime())); + result.pushKV("height", pindexCheckpoint->nHeight); + result.pushKV("timestamp", (boost::int64_t) pindexCheckpoint->GetBlockTime()); } if (gArgs.IsArgSet("-checkpointkey")) - entry.push_back(Pair("checkpointmaster", true)); - result.push_back(entry); + result.pushKV("checkpointmaster", true); return result; } @@ -896,20 +893,18 @@ UniValue sendcheckpoint(const JSONRPCRequest& request) if (!SendSyncCheckpoint(hash)) throw std::runtime_error("Failed to send checkpoint, check log. "); - UniValue result(UniValue::VARR); - UniValue entry(UniValue::VOBJ); + UniValue result(UniValue::VOBJ); CBlockIndex* pindexCheckpoint; - entry.push_back(Pair("synccheckpoint", hashSyncCheckpoint.ToString().c_str())); + result.pushKV("synccheckpoint", hashSyncCheckpoint.ToString().c_str()); if (mapBlockIndex.count(hashSyncCheckpoint)) { pindexCheckpoint = mapBlockIndex[hashSyncCheckpoint]; - entry.push_back(Pair("height", pindexCheckpoint->nHeight)); - entry.push_back(Pair("timestamp", (boost::int64_t) pindexCheckpoint->GetBlockTime())); + result.pushKV("height", pindexCheckpoint->nHeight); + result.pushKV("timestamp", (boost::int64_t) pindexCheckpoint->GetBlockTime()); } if (gArgs.IsArgSet("-checkpointkey")) - entry.push_back(Pair("checkpointmaster", true)); - result.push_back(entry); + result.pushKV("checkpointmaster", true); return result; } @@ -1118,8 +1113,7 @@ UniValue gettxout(const JSONRPCRequest& request) UniValue ret(UniValue::VOBJ); - std::string strHash = request.params[0].get_str(); - uint256 hash(uint256S(strHash)); + uint256 hash(ParseHashV(request.params[0], "txid")); int n = request.params[1].get_int(); COutPoint out(hash, n); bool fMempool = true; @@ -1527,8 +1521,7 @@ static UniValue preciousblock(const JSONRPCRequest& request) + HelpExampleRpc("preciousblock", "\"blockhash\"") ); - std::string strHash = request.params[0].get_str(); - uint256 hash(uint256S(strHash)); + uint256 hash(ParseHashV(request.params[0], "blockhash")); CBlockIndex* pblockindex; { @@ -1563,8 +1556,7 @@ static UniValue invalidateblock(const JSONRPCRequest& request) + HelpExampleRpc("invalidateblock", "\"blockhash\"") ); - std::string strHash = request.params[0].get_str(); - uint256 hash(uint256S(strHash)); + uint256 hash(ParseHashV(request.params[0], "blockhash")); CValidationState state; { @@ -1603,8 +1595,7 @@ static UniValue reconsiderblock(const JSONRPCRequest& request) + HelpExampleRpc("reconsiderblock", "\"blockhash\"") ); - std::string strHash = request.params[0].get_str(); - uint256 hash(uint256S(strHash)); + uint256 hash(ParseHashV(request.params[0], "blockhash")); { LOCK(cs_main); @@ -1657,7 +1648,7 @@ static UniValue getchaintxstats(const JSONRPCRequest& request) LOCK(cs_main); pindex = chainActive.Tip(); } else { - uint256 hash = uint256S(request.params[1].get_str()); + uint256 hash(ParseHashV(request.params[1], "blockhash")); LOCK(cs_main); pindex = LookupBlockIndex(hash); if (!pindex) { @@ -1831,8 +1822,7 @@ static UniValue getblockstats(const JSONRPCRequest& request) pindex = chainActive[height]; } else { - const std::string strHash = request.params[0].get_str(); - const uint256 hash(uint256S(strHash)); + const uint256 hash(ParseHashV(request.params[0], "hash_or_height")); pindex = LookupBlockIndex(hash); if (!pindex) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); @@ -1894,7 +1884,7 @@ static UniValue getblockstats(const JSONRPCRequest& request) if (loop_outputs) { for (const CTxOut& out : tx->vout) { tx_total_out += out.nValue; - utxo_size_inc += GetSerializeSize(out, SER_NETWORK, PROTOCOL_VERSION) + PER_UTXO_OVERHEAD; + utxo_size_inc += GetSerializeSize(out, PROTOCOL_VERSION) + PER_UTXO_OVERHEAD; } } @@ -1945,7 +1935,7 @@ static UniValue getblockstats(const JSONRPCRequest& request) CTxOut prevoutput = tx_in->vout[in.prevout.n]; tx_total_in += prevoutput.nValue; - utxo_size_inc -= GetSerializeSize(prevoutput, SER_NETWORK, PROTOCOL_VERSION) + PER_UTXO_OVERHEAD; + utxo_size_inc -= GetSerializeSize(prevoutput, PROTOCOL_VERSION) + PER_UTXO_OVERHEAD; } CAmount txfee = tx_total_in - tx_total_out; @@ -2121,7 +2111,7 @@ UniValue scantxoutset(const JSONRPCRequest& request) "or more path elements separated by \"/\", and optionally ending in \"/*\" (unhardened), or \"/*'\" or \"/*h\" (hardened) to specify all\n" "unhardened or hardened child keys.\n" "In the latter case, a range needs to be specified by below if different from 1000.\n" - "For more information on output descriptors, see the documentation at TODO\n" + "For more information on output descriptors, see the documentation in the doc/descriptors.md file.\n" "\nArguments:\n" "1. \"action\" (string, required) The action to execute\n" " \"start\" for starting a scan\n" @@ -2255,6 +2245,7 @@ UniValue scantxoutset(const JSONRPCRequest& request) return result; } +// clang-format off static const CRPCCommand commands[] = { // category name actor (function) argNames // --------------------- ------------------------ ----------------------- ---------- @@ -2292,6 +2283,7 @@ static const CRPCCommand commands[] = { "hidden", "waitforblockheight", &waitforblockheight, {"height","timeout"} }, { "hidden", "syncwithvalidationinterfacequeue", &syncwithvalidationinterfacequeue, {} }, }; +// clang-format on void RegisterBlockchainRPCCommands(CRPCTable &t) { diff --git a/src/rpc/blockchain.h b/src/rpc/blockchain.h index 544bc62c36..add335eb8a 100644 --- a/src/rpc/blockchain.h +++ b/src/rpc/blockchain.h @@ -16,8 +16,7 @@ class UniValue; static constexpr int NUM_GETBLOCKSTATS_PERCENTILES = 5; /** - * Get the difficulty of the net wrt to the given block index, or the chain tip if - * not provided. + * Get the difficulty of the net wrt to the given block index. * * @return A floating point number that is a multiple of the main net minimum * difficulty (4295032833 hashes). diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index e4149aa893..1c3d7961cf 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -18,6 +18,7 @@ class CRPCConvertParam std::string paramName; //!< parameter name }; +// clang-format off /** * Specify a (method, idx, name) here if the argument is a non-string RPC * argument and needs to be converted from JSON. @@ -167,7 +168,9 @@ static const CRPCConvertParam vRPCConvertParams[] = { "rescanblockchain", 0, "start_height"}, { "rescanblockchain", 1, "stop_height"}, { "createwallet", 1, "disable_private_keys"}, + { "getnodeaddresses", 0, "count"}, }; +// clang-format on class CRPCConvertTable { diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 4d0620fef9..d44a6f6e6d 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -250,7 +251,7 @@ static UniValue prioritisetransaction(const JSONRPCRequest& request) LOCK(cs_main); - uint256 hash = ParseHashStr(request.params[0].get_str(), "txid"); + uint256 hash(ParseHashV(request.params[0], "txid")); CAmount nAmount = request.params[2].get_int64(); if (!(request.params[1].isNull() || request.params[1].get_real() == 0)) { @@ -458,7 +459,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request) // Format: std::string lpstr = lpval.get_str(); - hashWatchedChain.SetHex(lpstr.substr(0, 64)); + hashWatchedChain = ParseHashV(lpstr.substr(0, 64), "longpollid"); nTransactionsUpdatedLastLP = atoi64(lpstr.substr(64)); } else @@ -753,11 +754,7 @@ static UniValue submitblock(const JSONRPCRequest& request) RegisterValidationInterface(&sc); bool accepted = ProcessNewBlock(Params(), blockptr, /* fForceProcessing */ true, /* fNewBlock */ &new_block); UnregisterValidationInterface(&sc); - if (!new_block) { - if (!accepted) { - // TODO Maybe pass down fNewBlock to AcceptBlockHeader, so it is properly set to true in this case? - return "invalid"; - } + if (!new_block && accepted) { return "duplicate"; } if (!sc.found) { @@ -802,12 +799,6 @@ static UniValue submitheader(const JSONRPCRequest& request) throw JSONRPCError(RPC_VERIFY_ERROR, state.GetRejectReason()); } -static UniValue estimatefee(const JSONRPCRequest& request) -{ - throw JSONRPCError(RPC_METHOD_DEPRECATED, "estimatefee was removed in v0.17.\n" - "Clients should use estimatesmartfee."); -} - static UniValue estimatesmartfee(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) @@ -925,7 +916,7 @@ static UniValue estimaterawfee(const JSONRPCRequest& request) UniValue result(UniValue::VOBJ); - for (FeeEstimateHorizon horizon : {FeeEstimateHorizon::SHORT_HALFLIFE, FeeEstimateHorizon::MED_HALFLIFE, FeeEstimateHorizon::LONG_HALFLIFE}) { + for (const FeeEstimateHorizon horizon : {FeeEstimateHorizon::SHORT_HALFLIFE, FeeEstimateHorizon::MED_HALFLIFE, FeeEstimateHorizon::LONG_HALFLIFE}) { CFeeRate feeRate; EstimationResult buckets; @@ -971,6 +962,7 @@ static UniValue estimaterawfee(const JSONRPCRequest& request) return result; } +// clang-format off static const CRPCCommand commands[] = { // category name actor (function) argNames // --------------------- ------------------------ ----------------------- ---------- @@ -984,11 +976,11 @@ static const CRPCCommand commands[] = { "generating", "generatetoaddress", &generatetoaddress, {"nblocks","address","maxtries"} }, - { "hidden", "estimatefee", &estimatefee, {} }, { "util", "estimatesmartfee", &estimatesmartfee, {"conf_target", "estimate_mode"} }, { "hidden", "estimaterawfee", &estimaterawfee, {"conf_target", "threshold"} }, }; +// clang-format on void RegisterMiningRPCCommands(CRPCTable &t) { diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index aa1004753c..d6d5b7f5b7 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -19,11 +19,6 @@ #include #include #include -#ifdef ENABLE_WALLET -#include -#include -#include -#endif #include #include @@ -67,29 +62,18 @@ static UniValue validateaddress(const JSONRPCRequest& request) ret.pushKV("isvalid", isValid); if (isValid) { + std::string currentAddress = EncodeDestination(dest); + ret.pushKV("address", currentAddress); -#ifdef ENABLE_WALLET - if (HasWallets() && IsDeprecatedRPCEnabled("validateaddress")) { - ret.pushKVs(getaddressinfo(request)); - } -#endif - if (ret["address"].isNull()) { - std::string currentAddress = EncodeDestination(dest); - ret.pushKV("address", currentAddress); - - CScript scriptPubKey = GetScriptForDestination(dest); - ret.pushKV("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end())); + CScript scriptPubKey = GetScriptForDestination(dest); + ret.pushKV("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end())); - UniValue detail = DescribeAddress(dest); - ret.pushKVs(detail); - } + UniValue detail = DescribeAddress(dest); + ret.pushKVs(detail); } return ret; } -// Needed even with !ENABLE_WALLET, to pass (ignored) pointers around -class CWallet; - static UniValue createmultisig(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() < 2 || request.params.size() > 3) @@ -133,8 +117,7 @@ static UniValue createmultisig(const JSONRPCRequest& request) if (IsHex(keys[i].get_str()) && (keys[i].get_str().length() == 66 || keys[i].get_str().length() == 130)) { pubkeys.push_back(HexToPubKey(keys[i].get_str())); } else { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Invalid public key: %s\nNote that from v0.16, createmultisig no longer accepts addresses." - " Users must use addmultisigaddress to create multisig addresses with addresses known to the wallet.", keys[i].get_str())); + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Invalid public key: %s\n.", keys[i].get_str())); } } @@ -459,12 +442,13 @@ static UniValue echo(const JSONRPCRequest& request) return request.params; } +// clang-format off static const CRPCCommand commands[] = { // category name actor (function) argNames // --------------------- ------------------------ ----------------------- ---------- { "control", "getmemoryinfo", &getmemoryinfo, {"mode"} }, { "control", "logging", &logging, {"include", "exclude"}}, - { "util", "validateaddress", &validateaddress, {"address"} }, /* uses wallet if enabled */ + { "util", "validateaddress", &validateaddress, {"address"} }, { "util", "createmultisig", &createmultisig, {"nrequired","keys"} }, { "util", "verifymessage", &verifymessage, {"address","signature","message"} }, { "util", "signmessagewithprivkey", &signmessagewithprivkey, {"privkey","message"} }, @@ -474,6 +458,7 @@ static const CRPCCommand commands[] = { "hidden", "echo", &echo, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}}, { "hidden", "echojson", &echo, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}}, }; +// clang-format on void RegisterMiscRPCCommands(CRPCTable &t) { diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index ca0b64d72b..52025893f4 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -168,7 +168,7 @@ static UniValue getpeerinfo(const JSONRPCRequest& request) obj.pushKV("synced_headers", statestats.nSyncHeight); obj.pushKV("synced_blocks", statestats.nCommonHeight); UniValue heights(UniValue::VARR); - for (int height : statestats.vHeightInFlight) { + for (const int height : statestats.vHeightInFlight) { heights.push_back(height); } obj.pushKV("inflight", heights); @@ -680,21 +680,72 @@ UniValue sendalert(const JSONRPCRequest& request) alert.RelayTo(pnode); }); - UniValue result(UniValue::VARR); - UniValue entry(UniValue::VOBJ); - entry.push_back(Pair("strStatusBar", alert.strStatusBar)); - entry.push_back(Pair("nVersion", alert.nVersion)); - entry.push_back(Pair("nMinVer", alert.nMinVer)); - entry.push_back(Pair("nMaxVer", alert.nMaxVer)); - entry.push_back(Pair("nPriority", alert.nPriority)); - entry.push_back(Pair("nID", alert.nID)); + UniValue result(UniValue::VOBJ); + result.pushKV("strStatusBar", alert.strStatusBar); + result.pushKV("nVersion", alert.nVersion); + result.pushKV("nMinVer", alert.nMinVer); + result.pushKV("nMaxVer", alert.nMaxVer); + result.pushKV("nPriority", alert.nPriority); + result.pushKV("nID", alert.nID); if (alert.nCancel > 0) - entry.push_back(Pair("nCancel", alert.nCancel)); - result.push_back(entry); + result.pushKV("nCancel", alert.nCancel); return result; } +static UniValue getnodeaddresses(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() > 1) { + throw std::runtime_error( + "getnodeaddresses ( count )\n" + "\nReturn known addresses which can potentially be used to find new nodes in the network\n" + "\nArguments:\n" + "1. \"count\" (numeric, optional) How many addresses to return. Limited to the smaller of " + std::to_string(ADDRMAN_GETADDR_MAX) + + " or " + std::to_string(ADDRMAN_GETADDR_MAX_PCT) + "% of all known addresses. (default = 1)\n" + "\nResult:\n" + "[\n" + " {\n" + " \"time\": ttt, (numeric) Timestamp in seconds since epoch (Jan 1 1970 GMT) keeping track of when the node was last seen\n" + " \"services\": n, (numeric) The services offered\n" + " \"address\": \"host\", (string) The address of the node\n" + " \"port\": n (numeric) The port of the node\n" + " }\n" + " ,....\n" + "]\n" + "\nExamples:\n" + + HelpExampleCli("getnodeaddresses", "8") + + HelpExampleRpc("getnodeaddresses", "8") + ); + } + if (!g_connman) { + throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); + } + + int count = 1; + if (!request.params[0].isNull()) { + count = request.params[0].get_int(); + if (count <= 0) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Address count out of range"); + } + } + // returns a shuffled list of CAddress + std::vector vAddr = g_connman->GetAddresses(); + UniValue ret(UniValue::VARR); + + int address_return_count = std::min(count, vAddr.size()); + for (int i = 0; i < address_return_count; ++i) { + UniValue obj(UniValue::VOBJ); + const CAddress& addr = vAddr[i]; + obj.pushKV("time", (int)addr.nTime); + obj.pushKV("services", (uint64_t)addr.nServices); + obj.pushKV("address", addr.ToStringIP()); + obj.pushKV("port", addr.GetPort()); + ret.push_back(obj); + } + return ret; +} + +// clang-format off static const CRPCCommand commands[] = { // category name actor (function) argNames // --------------------- ------------------------ ----------------------- ---------- @@ -711,7 +762,9 @@ static const CRPCCommand commands[] = { "network", "clearbanned", &clearbanned, {} }, { "network", "setnetworkactive", &setnetworkactive, {"state"} }, { "network", "sendalert", &sendalert, {"message", "privatekey", "minver", "maxver", "priority", "id", "cancelupto"} }, + { "network", "getnodeaddresses", &getnodeaddresses, {"count"} }, }; +// clang-format on void RegisterNetRPCCommands(CRPCTable &t) { diff --git a/src/rpc/protocol.cpp b/src/rpc/protocol.cpp index dab63ab263..55bebb5662 100644 --- a/src/rpc/protocol.cpp +++ b/src/rpc/protocol.cpp @@ -128,7 +128,7 @@ void DeleteAuthCookie() try { fs::remove(GetAuthCookieFile()); } catch (const fs::filesystem_error& e) { - LogPrintf("%s: Unable to remove random auth cookie file: %s\n", __func__, e.what()); + LogPrintf("%s: Unable to remove random auth cookie file: %s\n", __func__, fsbridge::get_filesystem_error_message(e)); } } diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index caab483581..15dca3463e 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -27,9 +27,6 @@ #include #include #include -#ifdef ENABLE_WALLET -#include -#endif #include #include @@ -229,9 +226,7 @@ static UniValue gettxoutproof(const JSONRPCRequest& request) UniValue txids = request.params[0].get_array(); for (unsigned int idx = 0; idx < txids.size(); idx++) { const UniValue& txid = txids[idx]; - if (txid.get_str().length() != 64 || !IsHex(txid.get_str())) - throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid txid ")+txid.get_str()); - uint256 hash(uint256S(txid.get_str())); + uint256 hash(ParseHashV(txid, "txid")); if (setTxids.count(hash)) throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated txid: ")+txid.get_str()); setTxids.insert(hash); @@ -242,7 +237,7 @@ static UniValue gettxoutproof(const JSONRPCRequest& request) uint256 hashBlock; if (!request.params[1].isNull()) { LOCK(cs_main); - hashBlock = uint256S(request.params[1].get_str()); + hashBlock = ParseHashV(request.params[1], "blockhash"); pblockindex = LookupBlockIndex(hashBlock); if (!pblockindex) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); @@ -824,8 +819,7 @@ UniValue SignTransaction(CMutableTransaction& mtx, const UniValue& prevTxsUnival view.AddCoin(out, std::move(newcoin), true); } - // if redeemScript given and not using the local wallet (private keys - // given), add redeemScript to the keystore so it can be signed: + // if redeemScript and private keys were given, add redeemScript to the keystore so it can be signed if (is_temp_keystore && (scriptPubKey.IsPayToScriptHash() || scriptPubKey.IsPayToWitnessScriptHash())) { RPCTypeCheckObj(prevOut, { @@ -980,102 +974,10 @@ static UniValue signrawtransactionwithkey(const JSONRPCRequest& request) UniValue signrawtransaction(const JSONRPCRequest& request) { -#ifdef ENABLE_WALLET - std::shared_ptr const wallet = GetWalletForJSONRPCRequest(request); - CWallet* const pwallet = wallet.get(); -#endif - - if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) - throw std::runtime_error( - "signrawtransaction \"hexstring\" ( [{\"txid\":\"id\",\"vout\":n,\"scriptPubKey\":\"hex\",\"redeemScript\":\"hex\"},...] [\"privatekey1\",...] sighashtype )\n" - "\nDEPRECATED. Sign inputs for raw transaction (serialized, hex-encoded).\n" - "The second optional argument (may be null) is an array of previous transaction outputs that\n" - "this transaction depends on but may not yet be in the block chain.\n" - "The third optional argument (may be null) is an array of base58-encoded private\n" - "keys that, if given, will be the only keys used to sign the transaction.\n" -#ifdef ENABLE_WALLET - + HelpRequiringPassphrase(pwallet) + "\n" -#endif - "\nArguments:\n" - "1. \"hexstring\" (string, required) The transaction hex string\n" - "2. \"prevtxs\" (string, optional) An json array of previous dependent transaction outputs\n" - " [ (json array of json objects, or 'null' if none provided)\n" - " {\n" - " \"txid\":\"id\", (string, required) The transaction id\n" - " \"vout\":n, (numeric, required) The output number\n" - " \"scriptPubKey\": \"hex\", (string, required) script key\n" - " \"redeemScript\": \"hex\", (string, required for P2SH or P2WSH) redeem script\n" - " \"amount\": value (numeric, required) The amount spent\n" - " }\n" - " ,...\n" - " ]\n" - "3. \"privkeys\" (string, optional) A json array of base58-encoded private keys for signing\n" - " [ (json array of strings, or 'null' if none provided)\n" - " \"privatekey\" (string) private key in base58-encoding\n" - " ,...\n" - " ]\n" - "4. \"sighashtype\" (string, optional, default=ALL) The signature hash type. Must be one of\n" - " \"ALL\"\n" - " \"NONE\"\n" - " \"SINGLE\"\n" - " \"ALL|ANYONECANPAY\"\n" - " \"NONE|ANYONECANPAY\"\n" - " \"SINGLE|ANYONECANPAY\"\n" - - "\nResult:\n" - "{\n" - " \"hex\" : \"value\", (string) The hex-encoded raw transaction with signature(s)\n" - " \"complete\" : true|false, (boolean) If the transaction has a complete set of signatures\n" - " \"errors\" : [ (json array of objects) Script verification errors (if there are any)\n" - " {\n" - " \"txid\" : \"hash\", (string) The hash of the referenced, previous transaction\n" - " \"vout\" : n, (numeric) The index of the output to spent and used as input\n" - " \"scriptSig\" : \"hex\", (string) The hex-encoded signature script\n" - " \"sequence\" : n, (numeric) Script sequence number\n" - " \"error\" : \"text\" (string) Verification or signing error related to the input\n" - " }\n" - " ,...\n" - " ]\n" - "}\n" - - "\nExamples:\n" - + HelpExampleCli("signrawtransaction", "\"myhex\"") - + HelpExampleRpc("signrawtransaction", "\"myhex\"") - ); - - if (!IsDeprecatedRPCEnabled("signrawtransaction")) { - throw JSONRPCError(RPC_METHOD_DEPRECATED, "signrawtransaction is deprecated and will be fully removed in v0.18. " - "To use signrawtransaction in v0.17, restart feathercoind with -deprecatedrpc=signrawtransaction.\n" - "Projects should transition to using signrawtransactionwithkey and signrawtransactionwithwallet before upgrading to v0.18"); - } - - RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR, UniValue::VARR, UniValue::VSTR}, true); - - // Make a JSONRPCRequest to pass on to the right signrawtransaction* command - JSONRPCRequest new_request; - new_request.id = request.id; - new_request.params.setArray(); - - // For signing with private keys - if (!request.params[2].isNull()) { - new_request.params.push_back(request.params[0]); - // Note: the prevtxs and privkeys are reversed for signrawtransactionwithkey - new_request.params.push_back(request.params[2]); - new_request.params.push_back(request.params[1]); - new_request.params.push_back(request.params[3]); - return signrawtransactionwithkey(new_request); - } else { -#ifdef ENABLE_WALLET - // Otherwise sign with the wallet which does not take a privkeys parameter - new_request.params.push_back(request.params[0]); - new_request.params.push_back(request.params[1]); - new_request.params.push_back(request.params[3]); - return signrawtransactionwithwallet(new_request); -#else - // If we have made it this far, then wallet is disabled and no private keys were given, so fail here. - throw JSONRPCError(RPC_INVALID_PARAMETER, "No private keys available."); -#endif - } + // This method should be removed entirely in V0.19, along with the entries in the + // CRPCCommand table and rpc/client.cpp. + throw JSONRPCError(RPC_METHOD_DEPRECATED, "signrawtransaction was removed in v0.18.\n" + "Clients should transition to using signrawtransactionwithkey and signrawtransactionwithwallet"); } static UniValue sendrawtransaction(const JSONRPCRequest& request) @@ -1084,7 +986,7 @@ static UniValue sendrawtransaction(const JSONRPCRequest& request) throw std::runtime_error( "sendrawtransaction \"hexstring\" ( allowhighfees )\n" "\nSubmits raw transaction (serialized, hex-encoded) to local node and network.\n" - "\nAlso see createrawtransaction and signrawtransaction calls.\n" + "\nAlso see createrawtransaction and signrawtransactionwithkey calls.\n" "\nArguments:\n" "1. \"hexstring\" (string, required) The hex string of the raw transaction)\n" "2. allowhighfees (boolean, optional, default=false) Allow high fees\n" @@ -1094,7 +996,7 @@ static UniValue sendrawtransaction(const JSONRPCRequest& request) "\nCreate a transaction\n" + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\" : \\\"mytxid\\\",\\\"vout\\\":0}]\" \"{\\\"myaddress\\\":0.01}\"") + "Sign the transaction, and get back the hex\n" - + HelpExampleCli("signrawtransaction", "\"myhex\"") + + + HelpExampleCli("signrawtransactionwithwallet", "\"myhex\"") + "\nSend the transaction (signed hex)\n" + HelpExampleCli("sendrawtransaction", "\"signedhex\"") + "\nAs a json rpc call\n" @@ -1199,7 +1101,7 @@ static UniValue testmempoolaccept(const JSONRPCRequest& request) "\nCreate a transaction\n" + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\" : \\\"mytxid\\\",\\\"vout\\\":0}]\" \"{\\\"myaddress\\\":0.01}\"") + "Sign the transaction, and get back the hex\n" - + HelpExampleCli("signrawtransaction", "\"myhex\"") + + + HelpExampleCli("signrawtransactionwithwallet", "\"myhex\"") + "\nTest acceptance of the transaction (signed hex)\n" + HelpExampleCli("testmempoolaccept", "\"signedhex\"") + "\nAs a json rpc call\n" @@ -1740,7 +1642,7 @@ UniValue converttopsbt(const JSONRPCRequest& request) " will continue. If false, RPC will fail if any signatures are present.\n" "3. iswitness (boolean, optional) Whether the transaction hex is a serialized witness transaction.\n" " If iswitness is not present, heuristic tests will be used in decoding. If true, only witness deserializaion\n" - " will be tried. If false, only non-witness deserialization wil be tried. Only has an effect if\n" + " will be tried. If false, only non-witness deserialization will be tried. Only has an effect if\n" " permitsigdata is true.\n" "\nResult:\n" " \"psbt\" (string) The resulting raw transaction (base64-encoded string)\n" @@ -1791,6 +1693,7 @@ UniValue converttopsbt(const JSONRPCRequest& request) return EncodeBase64((unsigned char*)ssTx.data(), ssTx.size()); } +// clang-format off static const CRPCCommand commands[] = { // category name actor (function) argNames // --------------------- ------------------------ ----------------------- ---------- @@ -1800,7 +1703,7 @@ static const CRPCCommand commands[] = { "rawtransactions", "decodescript", &decodescript, {"hexstring"} }, { "rawtransactions", "sendrawtransaction", &sendrawtransaction, {"hexstring","allowhighfees"} }, { "rawtransactions", "combinerawtransaction", &combinerawtransaction, {"txs"} }, - { "rawtransactions", "signrawtransaction", &signrawtransaction, {"hexstring","prevtxs","privkeys","sighashtype"} }, /* uses wallet if enabled */ + { "hidden", "signrawtransaction", &signrawtransaction, {"hexstring","prevtxs","privkeys","sighashtype"} }, { "rawtransactions", "signrawtransactionwithkey", &signrawtransactionwithkey, {"hexstring","privkeys","prevtxs","sighashtype"} }, { "rawtransactions", "testmempoolaccept", &testmempoolaccept, {"rawtxs","allowhighfees"} }, { "rawtransactions", "decodepsbt", &decodepsbt, {"psbt"} }, @@ -1812,6 +1715,7 @@ static const CRPCCommand commands[] = { "blockchain", "gettxoutproof", &gettxoutproof, {"txids", "blockhash"} }, { "blockchain", "verifytxoutproof", &verifytxoutproof, {"proof"} }, }; +// clang-format on void RegisterRawTransactionRPCCommands(CRPCTable &t) { diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 28a72d3635..5c2869434e 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -116,16 +116,12 @@ CAmount AmountFromValue(const UniValue& value) uint256 ParseHashV(const UniValue& v, std::string strName) { - std::string strHex; - if (v.isStr()) - strHex = v.get_str(); + std::string strHex(v.get_str()); + if (64 != strHex.length()) + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%s must be of length %d (not %d, for '%s')", strName, 64, strHex.length(), strHex)); if (!IsHex(strHex)) // Note: IsHex("") is false throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')"); - if (64 != strHex.length()) - throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%s must be of length %d (not %d)", strName, 64, strHex.length())); - uint256 result; - result.SetHex(strHex); - return result; + return uint256S(strHex); } uint256 ParseHashO(const UniValue& o, std::string strKey) { @@ -252,6 +248,7 @@ static UniValue uptime(const JSONRPCRequest& jsonRequest) return GetTime() - GetStartupTime(); } +// clang-format off /** * Call Table */ @@ -263,6 +260,7 @@ static const CRPCCommand vRPCCommands[] = { "control", "stop", &stop, {} }, { "control", "uptime", &uptime, {} }, }; +// clang-format on CRPCTable::CRPCTable() { @@ -538,7 +536,7 @@ void RPCUnsetTimerInterface(RPCTimerInterface *iface) timerInterface = nullptr; } -void RPCRunLater(const std::string& name, std::function func, int64_t nSeconds) +void RPCRunLater(const std::string& name, std::function func, int64_t nSeconds) { if (!timerInterface) throw JSONRPCError(RPC_INTERNAL_ERROR, "No timer handler registered for RPC"); diff --git a/src/rpc/server.h b/src/rpc/server.h index 15d0ec80f5..2d62a76f3c 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -110,7 +110,7 @@ class RPCTimerInterface * This is needed to cope with the case in which there is no HTTP server, but * only GUI RPC console, and to break the dependency of pcserver on httprpc. */ - virtual RPCTimerBase* NewTimer(std::function& func, int64_t millis) = 0; + virtual RPCTimerBase* NewTimer(std::function& func, int64_t millis) = 0; }; /** Set the factory function for timers */ @@ -124,7 +124,7 @@ void RPCUnsetTimerInterface(RPCTimerInterface *iface); * Run func nSeconds from now. * Overrides previous timer (if any). */ -void RPCRunLater(const std::string& name, std::function func, int64_t nSeconds); +void RPCRunLater(const std::string& name, std::function func, int64_t nSeconds); typedef UniValue(*rpcfn_type)(const JSONRPCRequest& jsonRequest); diff --git a/src/scheduler.cpp b/src/scheduler.cpp index 89dfc2b363..552391d7d0 100644 --- a/src/scheduler.cpp +++ b/src/scheduler.cpp @@ -159,7 +159,7 @@ void SingleThreadedSchedulerClient::MaybeScheduleProcessQueue() { } void SingleThreadedSchedulerClient::ProcessQueue() { - std::function callback; + std::function callback; { LOCK(m_cs_callbacks_pending); if (m_are_callbacks_running) return; @@ -187,7 +187,7 @@ void SingleThreadedSchedulerClient::ProcessQueue() { callback(); } -void SingleThreadedSchedulerClient::AddToProcessQueue(std::function func) { +void SingleThreadedSchedulerClient::AddToProcessQueue(std::function func) { assert(m_pscheduler); { diff --git a/src/scheduler.h b/src/scheduler.h index 0c2551cf4f..6c45f508ec 100644 --- a/src/scheduler.h +++ b/src/scheduler.h @@ -40,7 +40,7 @@ class CScheduler CScheduler(); ~CScheduler(); - typedef std::function Function; + typedef std::function Function; // Call func at/after time t void schedule(Function f, boost::chrono::system_clock::time_point t=boost::chrono::system_clock::now()); @@ -99,7 +99,7 @@ class SingleThreadedSchedulerClient { CScheduler *m_pscheduler; CCriticalSection m_cs_callbacks_pending; - std::list> m_callbacks_pending GUARDED_BY(m_cs_callbacks_pending); + std::list> m_callbacks_pending GUARDED_BY(m_cs_callbacks_pending); bool m_are_callbacks_running GUARDED_BY(m_cs_callbacks_pending) = false; void MaybeScheduleProcessQueue(); @@ -111,10 +111,10 @@ class SingleThreadedSchedulerClient { /** * Add a callback to be executed. Callbacks are executed serially * and memory is release-acquire consistent between callback executions. - * Practially, this means that callbacks can behave as if they are executed + * Practically, this means that callbacks can behave as if they are executed * in order by a single thread. */ - void AddToProcessQueue(std::function func); + void AddToProcessQueue(std::function func); // Processes all remaining queue members on the calling thread, blocking until queue is empty // Must be called after the CScheduler has no remaining processing threads! diff --git a/src/script/bitcoinconsensus.cpp b/src/script/bitcoinconsensus.cpp index 01cfeb23f1..15e204062f 100644 --- a/src/script/bitcoinconsensus.cpp +++ b/src/script/bitcoinconsensus.cpp @@ -88,7 +88,7 @@ static int verify_script(const unsigned char *scriptPubKey, unsigned int scriptP CTransaction tx(deserialize, stream); if (nIn >= tx.vin.size()) return set_error(err, bitcoinconsensus_ERR_TX_INDEX); - if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen) + if (GetSerializeSize(tx, PROTOCOL_VERSION) != txToLen) return set_error(err, bitcoinconsensus_ERR_TX_SIZE_MISMATCH); // Regardless of the verification result, the tx did not error. diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp index f366b99ec3..45b097dde6 100644 --- a/src/script/descriptor.cpp +++ b/src/script/descriptor.cpp @@ -373,7 +373,7 @@ enum class ParseScriptContext { P2WSH, }; -/** Parse a constant. If succesful, sp is updated to skip the constant and return true. */ +/** Parse a constant. If successful, sp is updated to skip the constant and return true. */ bool Const(const std::string& str, Span& sp) { if ((size_t)sp.size() >= str.size() && std::equal(str.begin(), str.end(), sp.begin())) { @@ -383,7 +383,7 @@ bool Const(const std::string& str, Span& sp) return false; } -/** Parse a function call. If succesful, sp is updated to be the function's argument(s). */ +/** Parse a function call. If successful, sp is updated to be the function's argument(s). */ bool Func(const std::string& str, Span& sp) { if ((size_t)sp.size() >= str.size() + 2 && sp[str.size()] == '(' && sp[sp.size() - 1] == ')' && std::equal(str.begin(), str.end(), sp.begin())) { diff --git a/src/script/descriptor.h b/src/script/descriptor.h index e079c72e92..87e07369c7 100644 --- a/src/script/descriptor.h +++ b/src/script/descriptor.h @@ -22,55 +22,8 @@ // they can be included inside by changing public keys to private keys (WIF // format), and changing xpubs by xprvs. // -// 1. Examples -// -// A P2PK descriptor with a fixed public key: -// - pk(0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798) -// -// A P2SH-P2WSH-P2PKH descriptor with a fixed public key: -// - sh(wsh(pkh(02e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13))) -// -// A bare 1-of-2 multisig descriptor: -// - multi(1,022f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4,025cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc) -// -// A chain of P2PKH outputs (this needs the corresponding private key to derive): -// - pkh(xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw/1'/2/*) -// -// 2. Grammar description: -// -// X: xpub or xprv encoded extended key -// I: decimal encoded integer -// H: Hex encoded byte array -// A: Address in P2PKH, P2SH, or Bech32 encoding -// -// S (Scripts): -// * pk(P): Pay-to-pubkey (P2PK) output for public key P. -// * pkh(P): Pay-to-pubkey-hash (P2PKH) output for public key P. -// * wpkh(P): Pay-to-witness-pubkey-hash (P2WPKH) output for public key P. -// * sh(S): Pay-to-script-hash (P2SH) output for script S -// * wsh(S): Pay-to-witness-script-hash (P2WSH) output for script S -// * combo(P): combination of P2PK, P2PKH, P2WPKH, and P2SH-P2WPKH for public key P. -// * multi(I,L): k-of-n multisig for given public keys -// * addr(A): Output to address -// * raw(H): scriptPubKey with raw bytes -// -// P (Public keys): -// * H: fixed public key (or WIF-encoded private key) -// * E: extended public key -// * E/*: (ranged) all unhardened direct children of an extended public key -// * E/*': (ranged) all hardened direct children of an extended public key -// -// L (Comma-separated lists of public keys): -// * P -// * L,P -// -// E (Extended public keys): -// * X -// * E/I: unhardened child -// * E/I': hardened child -// * E/Ih: hardened child (alternative notation) -// -// The top level is S. +// Reference documentation about the descriptor language can be found in +// doc/descriptors.md. /** Interface for parsed descriptor objects. */ struct Descriptor { diff --git a/src/script/ismine.cpp b/src/script/ismine.cpp index 1433ebf42f..51bd2d6e9f 100644 --- a/src/script/ismine.cpp +++ b/src/script/ismine.cpp @@ -23,9 +23,9 @@ namespace { */ enum class IsMineSigVersion { - TOP = 0, //! scriptPubKey execution - P2SH = 1, //! P2SH redeemScript - WITNESS_V0 = 2 //! P2WSH witness script execution + TOP = 0, //!< scriptPubKey execution + P2SH = 1, //!< P2SH redeemScript + WITNESS_V0 = 2, //!< P2WSH witness script execution }; /** @@ -35,10 +35,10 @@ enum class IsMineSigVersion */ enum class IsMineResult { - NO = 0, //! Not ours - WATCH_ONLY = 1, //! Included in watch-only balance - SPENDABLE = 2, //! Included in all balances - INVALID = 3, //! Not spendable by anyone (uncompressed pubkey in segwit, P2SH inside P2SH or witness, witness inside witness) + NO = 0, //!< Not ours + WATCH_ONLY = 1, //!< Included in watch-only balance + SPENDABLE = 2, //!< Included in all balances + INVALID = 3, //!< Not spendable by anyone (uncompressed pubkey in segwit, P2SH inside P2SH or witness, witness inside witness) }; bool PermitsUncompressed(IsMineSigVersion sigversion) diff --git a/src/script/sign.h b/src/script/sign.h index 18b7320998..2fc4575e59 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -147,7 +147,7 @@ static constexpr uint8_t PSBT_SEPARATOR = 0x00; template void SerializeToVector(Stream& s, const X&... args) { - WriteCompactSize(s, GetSerializeSizeMany(s, args...)); + WriteCompactSize(s, GetSerializeSizeMany(s.GetVersion(), args...)); SerializeMany(s, args...); } diff --git a/src/serialize.h b/src/serialize.h index 8bd3ef5d76..2d0cfbbbf0 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -901,10 +901,9 @@ class CSizeComputer protected: size_t nSize; - const int nType; const int nVersion; public: - CSizeComputer(int nTypeIn, int nVersionIn) : nSize(0), nType(nTypeIn), nVersion(nVersionIn) {} + explicit CSizeComputer(int nVersionIn) : nSize(0), nVersion(nVersionIn) {} void write(const char *psz, size_t _nSize) { @@ -929,7 +928,6 @@ class CSizeComputer } int GetVersion() const { return nVersion; } - int GetType() const { return nType; } }; template @@ -980,21 +978,15 @@ inline void WriteCompactSize(CSizeComputer &s, uint64_t nSize) } template -size_t GetSerializeSize(const T& t, int nType, int nVersion = 0) +size_t GetSerializeSize(const T& t, int nVersion = 0) { - return (CSizeComputer(nType, nVersion) << t).size(); + return (CSizeComputer(nVersion) << t).size(); } -template -size_t GetSerializeSize(const S& s, const T& t) +template +size_t GetSerializeSizeMany(int nVersion, const T&... t) { - return (CSizeComputer(s.GetType(), s.GetVersion()) << t).size(); -} - -template -size_t GetSerializeSizeMany(const S& s, const T&... t) -{ - CSizeComputer sc(s.GetType(), s.GetVersion()); + CSizeComputer sc(nVersion); SerializeMany(sc, t...); return sc.size(); } diff --git a/src/streams.h b/src/streams.h index d4a309be3c..dc20f7a9da 100644 --- a/src/streams.h +++ b/src/streams.h @@ -529,7 +529,7 @@ class BitStreamReader explicit BitStreamReader(IStream& istream) : m_istream(istream) {} /** Read the specified number of bits from the stream. The data is returned - * in the nbits least signficant bits of a 64-bit uint. + * in the nbits least significant bits of a 64-bit uint. */ uint64_t Read(int nbits) { if (nbits < 0 || nbits > 64) { diff --git a/src/support/lockedpool.cpp b/src/support/lockedpool.cpp index 070b3ed80e..8d577cf521 100644 --- a/src/support/lockedpool.cpp +++ b/src/support/lockedpool.cpp @@ -75,7 +75,7 @@ void* Arena::alloc(size_t size) // Create the used-chunk, taking its space from the end of the free-chunk const size_t size_remaining = size_ptr_it->first - size; - auto alloced = chunks_used.emplace(size_ptr_it->second + size_remaining, size).first; + auto allocated = chunks_used.emplace(size_ptr_it->second + size_remaining, size).first; chunks_free_end.erase(size_ptr_it->second + size_ptr_it->first); if (size_ptr_it->first == size) { // whole chunk is used up @@ -88,7 +88,7 @@ void* Arena::alloc(size_t size) } size_to_free_chunk.erase(size_ptr_it); - return reinterpret_cast(alloced->first); + return reinterpret_cast(allocated->first); } void Arena::free(void *ptr) diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp index f57d0c6d79..8c2873d916 100644 --- a/src/test/addrman_tests.cpp +++ b/src/test/addrman_tests.cpp @@ -40,22 +40,26 @@ class CAddrManTest : public CAddrMan CAddrInfo* Find(const CNetAddr& addr, int* pnId = nullptr) { + LOCK(cs); return CAddrMan::Find(addr, pnId); } CAddrInfo* Create(const CAddress& addr, const CNetAddr& addrSource, int* pnId = nullptr) { + LOCK(cs); return CAddrMan::Create(addr, addrSource, pnId); } void Delete(int nId) { + LOCK(cs); CAddrMan::Delete(nId); } // Simulates connection failure so that we can test eviction of offline nodes void SimConnFail(CService& addr) { + LOCK(cs); int64_t nLastSuccess = 1; Good_(addr, true, nLastSuccess); // Set last good connection in the deep past. diff --git a/src/test/allocator_tests.cpp b/src/test/allocator_tests.cpp index 1052ada232..c72c062b81 100644 --- a/src/test/allocator_tests.cpp +++ b/src/test/allocator_tests.cpp @@ -163,7 +163,7 @@ class TestLockedPageAllocator: public LockedPageAllocator BOOST_AUTO_TEST_CASE(lockedpool_tests_mock) { // Test over three virtual arenas, of which one will succeed being locked - std::unique_ptr x(new TestLockedPageAllocator(3, 1)); + std::unique_ptr x = MakeUnique(3, 1); LockedPool pool(std::move(x)); BOOST_CHECK(pool.stats().total == 0); BOOST_CHECK(pool.stats().locked == 0); diff --git a/src/test/blockfilter_tests.cpp b/src/test/blockfilter_tests.cpp index 773de343ea..4941ebd483 100644 --- a/src/test/blockfilter_tests.cpp +++ b/src/test/blockfilter_tests.cpp @@ -114,7 +114,8 @@ BOOST_AUTO_TEST_CASE(blockfilters_json_test) unsigned int pos = 0; /*int block_height =*/ test[pos++].get_int(); - /*uint256 block_hash =*/ ParseHashStr(test[pos++].get_str(), "block_hash"); + uint256 block_hash; + BOOST_CHECK(ParseHashStr(test[pos++].get_str(), block_hash)); CBlock block; BOOST_REQUIRE(DecodeHexBlk(block, test[pos++].get_str())); @@ -129,9 +130,11 @@ BOOST_AUTO_TEST_CASE(blockfilters_json_test) tx_undo.vprevout.emplace_back(txout, 0, false); } - uint256 prev_filter_header_basic = ParseHashStr(test[pos++].get_str(), "prev_filter_header_basic"); + uint256 prev_filter_header_basic; + BOOST_CHECK(ParseHashStr(test[pos++].get_str(), prev_filter_header_basic)); std::vector filter_basic = ParseHex(test[pos++].get_str()); - uint256 filter_header_basic = ParseHashStr(test[pos++].get_str(), "filter_header_basic"); + uint256 filter_header_basic; + BOOST_CHECK(ParseHashStr(test[pos++].get_str(), filter_header_basic)); BlockFilter computed_filter_basic(BlockFilterType::BASIC, block, block_undo); BOOST_CHECK(computed_filter_basic.GetFilter().GetEncoded() == filter_basic); diff --git a/src/test/checkqueue_tests.cpp b/src/test/checkqueue_tests.cpp index 39d0061c1c..f4b416c4ca 100644 --- a/src/test/checkqueue_tests.cpp +++ b/src/test/checkqueue_tests.cpp @@ -148,14 +148,14 @@ typedef CCheckQueue FrozenCleanup_Queue; */ static void Correct_Queue_range(std::vector range) { - auto small_queue = std::unique_ptr(new Correct_Queue {QUEUE_BATCH_SIZE}); + auto small_queue = MakeUnique(QUEUE_BATCH_SIZE); boost::thread_group tg; for (auto x = 0; x < nScriptCheckThreads; ++x) { tg.create_thread([&]{small_queue->Thread();}); } // Make vChecks here to save on malloc (this test can be slow...) std::vector vChecks; - for (auto i : range) { + for (const size_t i : range) { size_t total = i; FakeCheckCheckCompletion::n_calls = 0; CCheckQueueControl control(small_queue.get()); @@ -213,7 +213,7 @@ BOOST_AUTO_TEST_CASE(test_CheckQueue_Correct_Random) /** Test that failing checks are caught */ BOOST_AUTO_TEST_CASE(test_CheckQueue_Catches_Failure) { - auto fail_queue = std::unique_ptr(new Failing_Queue {QUEUE_BATCH_SIZE}); + auto fail_queue = MakeUnique(QUEUE_BATCH_SIZE); boost::thread_group tg; for (auto x = 0; x < nScriptCheckThreads; ++x) { @@ -246,14 +246,14 @@ BOOST_AUTO_TEST_CASE(test_CheckQueue_Catches_Failure) // future blocks, ie, the bad state is cleared. BOOST_AUTO_TEST_CASE(test_CheckQueue_Recovers_From_Failure) { - auto fail_queue = std::unique_ptr(new Failing_Queue {QUEUE_BATCH_SIZE}); + auto fail_queue = MakeUnique(QUEUE_BATCH_SIZE); boost::thread_group tg; for (auto x = 0; x < nScriptCheckThreads; ++x) { tg.create_thread([&]{fail_queue->Thread();}); } for (auto times = 0; times < 10; ++times) { - for (bool end_fails : {true, false}) { + for (const bool end_fails : {true, false}) { CCheckQueueControl control(fail_queue.get()); { std::vector vChecks; @@ -274,7 +274,7 @@ BOOST_AUTO_TEST_CASE(test_CheckQueue_Recovers_From_Failure) // more than once as well BOOST_AUTO_TEST_CASE(test_CheckQueue_UniqueCheck) { - auto queue = std::unique_ptr(new Unique_Queue {QUEUE_BATCH_SIZE}); + auto queue = MakeUnique(QUEUE_BATCH_SIZE); boost::thread_group tg; for (auto x = 0; x < nScriptCheckThreads; ++x) { tg.create_thread([&]{queue->Thread();}); @@ -310,7 +310,7 @@ BOOST_AUTO_TEST_CASE(test_CheckQueue_UniqueCheck) // time could leave the data hanging across a sequence of blocks. BOOST_AUTO_TEST_CASE(test_CheckQueue_Memory) { - auto queue = std::unique_ptr(new Memory_Queue {QUEUE_BATCH_SIZE}); + auto queue = MakeUnique(QUEUE_BATCH_SIZE); boost::thread_group tg; for (auto x = 0; x < nScriptCheckThreads; ++x) { tg.create_thread([&]{queue->Thread();}); @@ -341,7 +341,7 @@ BOOST_AUTO_TEST_CASE(test_CheckQueue_Memory) // have been destructed BOOST_AUTO_TEST_CASE(test_CheckQueue_FrozenCleanup) { - auto queue = std::unique_ptr(new FrozenCleanup_Queue {QUEUE_BATCH_SIZE}); + auto queue = MakeUnique(QUEUE_BATCH_SIZE); boost::thread_group tg; bool fails = false; for (auto x = 0; x < nScriptCheckThreads; ++x) { @@ -384,7 +384,7 @@ BOOST_AUTO_TEST_CASE(test_CheckQueue_FrozenCleanup) /** Test that CCheckQueueControl is threadsafe */ BOOST_AUTO_TEST_CASE(test_CheckQueueControl_Locks) { - auto queue = std::unique_ptr(new Standard_Queue{QUEUE_BATCH_SIZE}); + auto queue = MakeUnique(QUEUE_BATCH_SIZE); { boost::thread_group tg; std::atomic nThreads {0}; diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index 63b91b74c0..6f4b5ecd26 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -508,7 +508,7 @@ BOOST_AUTO_TEST_CASE(ccoins_serialization) Coin cc4; ss4 >> cc4; BOOST_CHECK_MESSAGE(false, "We should have thrown"); - } catch (const std::ios_base::failure& e) { + } catch (const std::ios_base::failure&) { } // Very large scriptPubKey (3*10^9 bytes) past the end of the stream @@ -521,7 +521,7 @@ BOOST_AUTO_TEST_CASE(ccoins_serialization) Coin cc5; ss5 >> cc5; BOOST_CHECK_MESSAGE(false, "We should have thrown"); - } catch (const std::ios_base::failure& e) { + } catch (const std::ios_base::failure&) { } } @@ -719,7 +719,7 @@ static void CheckAddCoinBase(CAmount base_value, CAmount cache_value, CAmount mo test.cache.AddCoin(OUTPOINT, Coin(std::move(output), 1, coinbase), coinbase); test.cache.SelfTest(); GetCoinsMapEntry(test.cache.map(), result_value, result_flags); - } catch (std::logic_error& e) { + } catch (std::logic_error&) { result_value = FAIL; result_flags = NO_ENTRY; } @@ -736,7 +736,7 @@ static void CheckAddCoinBase(CAmount base_value, CAmount cache_value, CAmount mo template static void CheckAddCoin(Args&&... args) { - for (CAmount base_value : {ABSENT, PRUNED, VALUE1}) + for (const CAmount base_value : {ABSENT, PRUNED, VALUE1}) CheckAddCoinBase(base_value, std::forward(args)...); } @@ -780,7 +780,7 @@ void CheckWriteCoins(CAmount parent_value, CAmount child_value, CAmount expected WriteCoinsViewEntry(test.cache, child_value, child_flags); test.cache.SelfTest(); GetCoinsMapEntry(test.cache.map(), result_value, result_flags); - } catch (std::logic_error& e) { + } catch (std::logic_error&) { result_value = FAIL; result_flags = NO_ENTRY; } @@ -848,10 +848,10 @@ BOOST_AUTO_TEST_CASE(ccoins_write) // they would be too repetitive (the parent cache is never updated in these // cases). The loop below covers these cases and makes sure the parent cache // is always left unchanged. - for (CAmount parent_value : {ABSENT, PRUNED, VALUE1}) - for (CAmount child_value : {ABSENT, PRUNED, VALUE2}) - for (char parent_flags : parent_value == ABSENT ? ABSENT_FLAGS : FLAGS) - for (char child_flags : child_value == ABSENT ? ABSENT_FLAGS : CLEAN_FLAGS) + for (const CAmount parent_value : {ABSENT, PRUNED, VALUE1}) + for (const CAmount child_value : {ABSENT, PRUNED, VALUE2}) + for (const char parent_flags : parent_value == ABSENT ? ABSENT_FLAGS : FLAGS) + for (const char child_flags : child_value == ABSENT ? ABSENT_FLAGS : CLEAN_FLAGS) CheckWriteCoins(parent_value, child_value, parent_value, parent_flags, child_flags, parent_flags); } diff --git a/src/test/crypto_tests.cpp b/src/test/crypto_tests.cpp index 19521027a9..713e3e2ded 100644 --- a/src/test/crypto_tests.cpp +++ b/src/test/crypto_tests.cpp @@ -200,7 +200,7 @@ static void TestChaCha20(const std::string &hexkey, uint64_t nonce, uint64_t see BOOST_CHECK(out == outres); } -static std::string LongTestString(void) { +static std::string LongTestString() { std::string ret; for (int i=0; i<200000; i++) { ret += (unsigned char)(i); diff --git a/src/test/cuckoocache_tests.cpp b/src/test/cuckoocache_tests.cpp index ec7aba34ca..dbceb9d2e0 100644 --- a/src/test/cuckoocache_tests.cpp +++ b/src/test/cuckoocache_tests.cpp @@ -82,11 +82,11 @@ static double test_cache(size_t megabytes, double load) */ std::vector hashes_insert_copy = hashes; /** Do the insert */ - for (uint256& h : hashes_insert_copy) + for (const uint256& h : hashes_insert_copy) set.insert(h); /** Count the hits */ uint32_t count = 0; - for (uint256& h : hashes) + for (const uint256& h : hashes) count += set.contains(h, false); double hit_rate = ((double)count) / ((double)n_insert); return hit_rate; @@ -323,7 +323,7 @@ static void test_cache_generations() reads.push_back(inserts[i]); for (uint32_t i = n_insert - (n_insert / 4); i < n_insert; ++i) reads.push_back(inserts[i]); - for (auto h : inserts) + for (const auto& h : inserts) c.insert(h); } }; diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp index 4dff1e5c72..9957ac074b 100644 --- a/src/test/dbwrapper_tests.cpp +++ b/src/test/dbwrapper_tests.cpp @@ -26,7 +26,7 @@ BOOST_FIXTURE_TEST_SUITE(dbwrapper_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(dbwrapper) { // Perform tests both obfuscated and non-obfuscated. - for (bool obfuscate : {false, true}) { + for (const bool obfuscate : {false, true}) { fs::path ph = SetDataDir(std::string("dbwrapper").append(obfuscate ? "_true" : "_false")); CDBWrapper dbw(ph, (1 << 20), true, false, obfuscate); char key = 'k'; @@ -46,7 +46,7 @@ BOOST_AUTO_TEST_CASE(dbwrapper) BOOST_AUTO_TEST_CASE(dbwrapper_batch) { // Perform tests both obfuscated and non-obfuscated. - for (bool obfuscate : {false, true}) { + for (const bool obfuscate : {false, true}) { fs::path ph = SetDataDir(std::string("dbwrapper_batch").append(obfuscate ? "_true" : "_false")); CDBWrapper dbw(ph, (1 << 20), true, false, obfuscate); @@ -82,7 +82,7 @@ BOOST_AUTO_TEST_CASE(dbwrapper_batch) BOOST_AUTO_TEST_CASE(dbwrapper_iterator) { // Perform tests both obfuscated and non-obfuscated. - for (bool obfuscate : {false, true}) { + for (const bool obfuscate : {false, true}) { fs::path ph = SetDataDir(std::string("dbwrapper_iterator").append(obfuscate ? "_true" : "_false")); CDBWrapper dbw(ph, (1 << 20), true, false, obfuscate); @@ -216,7 +216,7 @@ BOOST_AUTO_TEST_CASE(iterator_ordering) if (x & 1) BOOST_CHECK(dbw.Write(key, value)); } - for (int seek_start : {0x00, 0x80}) { + for (const int seek_start : {0x00, 0x80}) { it->Seek((uint8_t)seek_start); for (unsigned int x=seek_start; x<255; ++x) { uint8_t key; @@ -262,7 +262,7 @@ struct StringContentsSerializer { try { READWRITE(c); str.push_back(c); - } catch (const std::ios_base::failure& e) { + } catch (const std::ios_base::failure&) { break; } } @@ -291,7 +291,7 @@ BOOST_AUTO_TEST_CASE(iterator_string_ordering) } std::unique_ptr it(const_cast(dbw).NewIterator()); - for (int seek_start : {0, 5}) { + for (const int seek_start : {0, 5}) { snprintf(buf, sizeof(buf), "%d", seek_start); StringContentsSerializer seek_key(buf); it->Seek(seek_key); diff --git a/src/test/gen/crypto_gen.cpp b/src/test/gen/crypto_gen.cpp new file mode 100644 index 0000000000..ca8c65806f --- /dev/null +++ b/src/test/gen/crypto_gen.cpp @@ -0,0 +1,19 @@ +// Copyright (c) 2018 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include + +#include + +#include +#include +#include +#include + +/** Generates 1 to 20 keys for OP_CHECKMULTISIG */ +rc::Gen> MultisigKeys() +{ + return rc::gen::suchThat(rc::gen::arbitrary>(), [](const std::vector& keys) { + return keys.size() >= 1 && keys.size() <= 15; + }); +}; diff --git a/src/test/gen/crypto_gen.h b/src/test/gen/crypto_gen.h new file mode 100644 index 0000000000..7c2fb0350f --- /dev/null +++ b/src/test/gen/crypto_gen.h @@ -0,0 +1,63 @@ +// Copyright (c) 2018 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_TEST_GEN_CRYPTO_GEN_H +#define BITCOIN_TEST_GEN_CRYPTO_GEN_H + +#include +#include +#include +#include +#include +#include +#include + +/** Generates 1 to 15 keys for OP_CHECKMULTISIG */ +rc::Gen> MultisigKeys(); + +namespace rc +{ +/** Generator for a new CKey */ +template <> +struct Arbitrary { + static Gen arbitrary() + { + return rc::gen::map([](int x) { + CKey key; + key.MakeNewKey(true); + return key; + }); + }; +}; + +/** Generator for a CPrivKey */ +template <> +struct Arbitrary { + static Gen arbitrary() + { + return gen::map(gen::arbitrary(), [](const CKey& key) { + return key.GetPrivKey(); + }); + }; +}; + +/** Generator for a new CPubKey */ +template <> +struct Arbitrary { + static Gen arbitrary() + { + return gen::map(gen::arbitrary(), [](const CKey& key) { + return key.GetPubKey(); + }); + }; +}; +/** Generates a arbitrary uint256 */ +template <> +struct Arbitrary { + static Gen arbitrary() + { + return rc::gen::just(GetRandHash()); + }; +}; +} //namespace rc +#endif diff --git a/src/test/getarg_tests.cpp b/src/test/getarg_tests.cpp index eec7b38af7..7592330b10 100644 --- a/src/test/getarg_tests.cpp +++ b/src/test/getarg_tests.cpp @@ -24,7 +24,7 @@ static void ResetArgs(const std::string& strArg) // Convert to char*: std::vector vecChar; - for (std::string& s : vecArg) + for (const std::string& s : vecArg) vecChar.push_back(s.c_str()); std::string error; diff --git a/src/test/key_io_tests.cpp b/src/test/key_io_tests.cpp index 7e475ac610..a0c10d8ddd 100644 --- a/src/test/key_io_tests.cpp +++ b/src/test/key_io_tests.cpp @@ -136,7 +136,7 @@ BOOST_AUTO_TEST_CASE(key_io_invalid) std::string exp_base58string = test[0].get_str(); // must be invalid as public and as private key - for (auto chain : { CBaseChainParams::MAIN, CBaseChainParams::TESTNET, CBaseChainParams::REGTEST }) { + for (const auto& chain : { CBaseChainParams::MAIN, CBaseChainParams::TESTNET, CBaseChainParams::REGTEST }) { SelectParams(chain); destination = DecodeDestination(exp_base58string); BOOST_CHECK_MESSAGE(!IsValidDestination(destination), "IsValid pubkey in mainnet:" + strTest); diff --git a/src/test/key_properties.cpp b/src/test/key_properties.cpp new file mode 100644 index 0000000000..14e3c85359 --- /dev/null +++ b/src/test/key_properties.cpp @@ -0,0 +1,53 @@ +// Copyright (c) 2018 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include + +#include +#include