diff options
285 files changed, 3037 insertions, 4625 deletions
diff --git a/.appveyor.yml b/.appveyor.yml index 0c43e61592..ea587b78d4 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -38,17 +38,6 @@ after_build: - ps: fsutil behavior set disablelastaccess 1 # 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("@PACKAGE_NAME@", "Bitcoin Core") -- 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 -k stdout -e stdout 2> NUL diff --git a/.cirrus.yml b/.cirrus.yml index 9104a0a3d1..ce17a223b1 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -2,15 +2,18 @@ task: name: "FreeBsd 12.0 amd64 [GOAL: install] [no depends, only system libs]" freebsd_instance: image: freebsd-12-0-release-amd64 - ccache_cache: - folder: "/tmp/ccache_dir" + cpu: 8 + memory: 8G + timeout_in: 60m env: - MAKEJOBS: "-j3" + MAKEJOBS: "-j9" CONFIGURE_OPTS: "--disable-dependency-tracking" GOAL: "install" CCACHE_SIZE: "200M" CCACHE_COMPRESS: 1 CCACHE_DIR: "/tmp/ccache_dir" + ccache_cache: + folder: "/tmp/ccache_dir" install_script: - pkg install -y autoconf automake boost-libs git gmake libevent libtool openssl pkgconf python3 ccache - ./contrib/install_db4.sh $(pwd) @@ -23,4 +26,4 @@ task: check_script: - gmake check ${MAKEJOBS} VERBOSE=1 functional_test_script: - - ./test/functional/test_runner.py --ci --combinedlogslen=1000 --quiet --failfast + - ./test/functional/test_runner.py --jobs 9 --ci --extended --exclude feature_dbcrash --combinedlogslen=1000 --quiet --failfast diff --git a/.travis.yml b/.travis.yml index c281d3ed70..adf2140642 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,8 +31,8 @@ language: minimal cache: ccache: true directories: - - depends/built - - depends/sdk-sources + - $TRAVIS_BUILD_DIR/depends/built + - $TRAVIS_BUILD_DIR/depends/sdk-sources - $HOME/.ccache stages: - lint diff --git a/.travis/lint_04_install.sh b/.travis/lint_04_install.sh index 9a22773e57..62174620f2 100755 --- a/.travis/lint_04_install.sh +++ b/.travis/lint_04_install.sh @@ -6,7 +6,7 @@ export LC_ALL=C -travis_retry pip install codespell==1.13.0 +travis_retry pip install codespell==1.15.0 travis_retry pip install flake8==3.5.0 travis_retry pip install vulture==0.29 diff --git a/.travis/test_06_script_b.sh b/.travis/test_06_script_b.sh index 0420acb993..e40055a6ee 100755 --- a/.travis/test_06_script_b.sh +++ b/.travis/test_06_script_b.sh @@ -25,3 +25,5 @@ if [ "$RUN_FUZZ_TESTS" = "true" ]; then DOCKER_EXEC test/fuzz/test_runner.py -l DEBUG ${DIR_FUZZ_IN} END_FOLD fi + +cd ${TRAVIS_BUILD_DIR} || (echo "could not enter travis build dir $TRAVIS_BUILD_DIR"; exit 1) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5df99adba8..a2456f5b8c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -237,24 +237,35 @@ request. Typically reviewers will review the code for obvious errors, as well as test out the patch set and opine on the technical merits of the patch. Project maintainers take into account the peer review when determining if there is consensus to merge a pull request (remember that discussions may have been -spread out over GitHub, mailing list and IRC discussions). The following +spread out over GitHub, mailing list and IRC discussions). + +#### Conceptual Review + +A review can be a conceptual review, where the reviewer leaves a comment + * `Concept (N)ACK`, meaning "I do (not) agree in the general goal of this pull + request", + * `Approach (N)ACK`, meaning `Concept ACK`, but "I do (not) agree with the + approach of this change". + +A `NACK` needs to include a rationale why the change is not worthwhile. +NACKs without accompanying reasoning may be disregarded. + +#### Code Review + +After conceptual agreement on the change, code review can be provided. It is +starting with `ACK BRANCH_COMMIT`, where `BRANCH_COMMIT` is the top of the +topic branch. The review is followed by a description of how the reviewer did +the review. The following language is used within pull-request comments: - - (t)ACK means "I have tested the code and I agree it should be merged", involving + - "I have tested the code", involving change-specific manual testing in addition to running the unit and functional tests, and in case it is not obvious how the manual testing was done, it should be described; - - NACK means "I disagree this should be merged", and must be accompanied by - sound technical justification (or in certain cases of copyright/patent/licensing - issues, legal justification). NACKs without accompanying reasoning may be - disregarded; - - utACK means "I have not tested the code, but I have reviewed it and it looks + - "I have not tested the code, but I have reviewed it and it looks OK, I agree it can be merged"; - - Concept ACK means "I agree in the general principle of this pull request"; - Nit refers to trivial, often non-blocking issues. -Reviewers should include the commit hash which they reviewed in their comments. - Project maintainers reserve the right to weigh the opinions of peer reviewers using common sense judgement and also may weight based on meritocracy: Those that have demonstrated a deeper commitment and understanding towards the project diff --git a/Makefile.am b/Makefile.am index ec0743c3fa..712f2a454d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -198,7 +198,7 @@ test_bitcoin_filtered.info: test_bitcoin.info $(LCOV) -a $@ $(LCOV_OPTS) -o $@ functional_test.info: test_bitcoin_filtered.info - -@TIMEOUT=15 test/functional/test_runner.py $(EXTENDED_FUNCTIONAL_TESTS) + @TIMEOUT=15 test/functional/test_runner.py $(EXTENDED_FUNCTIONAL_TESTS) $(LCOV) -c $(LCOV_OPTS) -d $(abs_builddir)/src --t functional-tests -o $@ $(LCOV) -z $(LCOV_OPTS) -d $(abs_builddir)/src @@ -1,8 +1,6 @@ Bitcoin Core integration/staging tree ===================================== -[](https://travis-ci.org/bitcoin/bitcoin) - https://bitcoincore.org What is Bitcoin? diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000000..7ed96c7cea --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,20 @@ +# Security Policy + +## Supported Versions + +See our website for versions of Bitcoin Core that are currently supported with +security updates: https://bitcoincore.org/en/lifecycle/#schedule + +## Reporting a Vulnerability + +To report security issues send an email to security@bitcoincore.org (not for support). + +The following keys may be used to communicate sensitive information to developers: + +| Name | Fingerprint | +|------|-------------| +| Wladimir van der Laan | 71A3 B167 3540 5025 D447 E8F2 7481 0B01 2346 C9A6 | +| Jonas Schnelli | 32EE 5C4C 3FA1 5CCA DB46 ABE5 29D4 BCB6 416F 53EC | +| Pieter Wuille | 133E AC17 9436 F14A 5CF1 B794 860F EB80 4E66 9320 | + +You can import a key by running the following command with that individual’s fingerprint: `gpg --recv-keys "<fingerprint>"` Ensure that you put quotes around fingerprints containing spaces. diff --git a/build-aux/m4/ax_boost_base.m4 b/build-aux/m4/ax_boost_base.m4 index 650c94fa64..d540395763 100644 --- a/build-aux/m4/ax_boost_base.m4 +++ b/build-aux/m4/ax_boost_base.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_boost_base.html +# https://www.gnu.org/software/autoconf-archive/ax_boost_base.html # =========================================================================== # # SYNOPSIS @@ -33,7 +33,15 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 27 +#serial 45 + +# example boost program (need to pass version) +m4_define([_AX_BOOST_BASE_PROGRAM], + [AC_LANG_PROGRAM([[ +#include <boost/version.hpp> +]],[[ +(void) ((void)sizeof(char[1 - 2*!!((BOOST_VERSION) < ($1))])); +]])]) AC_DEFUN([AX_BOOST_BASE], [ @@ -44,110 +52,121 @@ AC_ARG_WITH([boost], or disable it (ARG=no) @<:@ARG=yes@:>@ ])], [ - if test "$withval" = "no"; then - want_boost="no" - elif test "$withval" = "yes"; then - want_boost="yes" - ac_boost_path="" - else - want_boost="yes" - ac_boost_path="$withval" - fi + AS_CASE([$withval], + [no],[want_boost="no";_AX_BOOST_BASE_boost_path=""], + [yes],[want_boost="yes";_AX_BOOST_BASE_boost_path=""], + [want_boost="yes";_AX_BOOST_BASE_boost_path="$withval"]) ], [want_boost="yes"]) AC_ARG_WITH([boost-libdir], - AS_HELP_STRING([--with-boost-libdir=LIB_DIR], - [Force given directory for boost libraries. Note that this will override library path detection, so use this parameter only if default library detection fails and you know exactly where your boost libraries are located.]), - [ - if test -d "$withval" - then - ac_boost_lib_path="$withval" - else - AC_MSG_ERROR(--with-boost-libdir expected directory name) - fi - ], - [ac_boost_lib_path=""] -) + [AS_HELP_STRING([--with-boost-libdir=LIB_DIR], + [Force given directory for boost libraries. + Note that this will override library path detection, + so use this parameter only if default library detection fails + and you know exactly where your boost libraries are located.])], + [ + AS_IF([test -d "$withval"], + [_AX_BOOST_BASE_boost_lib_path="$withval"], + [AC_MSG_ERROR([--with-boost-libdir expected directory name])]) + ], + [_AX_BOOST_BASE_boost_lib_path=""]) -if test "x$want_boost" = "xyes"; then - boost_lib_version_req=ifelse([$1], ,1.20.0,$1) - boost_lib_version_req_shorten=`expr $boost_lib_version_req : '\([[0-9]]*\.[[0-9]]*\)'` - boost_lib_version_req_major=`expr $boost_lib_version_req : '\([[0-9]]*\)'` - boost_lib_version_req_minor=`expr $boost_lib_version_req : '[[0-9]]*\.\([[0-9]]*\)'` - boost_lib_version_req_sub_minor=`expr $boost_lib_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'` - if test "x$boost_lib_version_req_sub_minor" = "x" ; then - boost_lib_version_req_sub_minor="0" - fi - WANT_BOOST_VERSION=`expr $boost_lib_version_req_major \* 100000 \+ $boost_lib_version_req_minor \* 100 \+ $boost_lib_version_req_sub_minor` - AC_MSG_CHECKING(for boostlib >= $boost_lib_version_req) +BOOST_LDFLAGS="" +BOOST_CPPFLAGS="" +AS_IF([test "x$want_boost" = "xyes"], + [_AX_BOOST_BASE_RUNDETECT([$1],[$2],[$3])]) +AC_SUBST(BOOST_CPPFLAGS) +AC_SUBST(BOOST_LDFLAGS) +]) + + +# convert a version string in $2 to numeric and affect to polymorphic var $1 +AC_DEFUN([_AX_BOOST_BASE_TONUMERICVERSION],[ + AS_IF([test "x$2" = "x"],[_AX_BOOST_BASE_TONUMERICVERSION_req="1.20.0"],[_AX_BOOST_BASE_TONUMERICVERSION_req="$2"]) + _AX_BOOST_BASE_TONUMERICVERSION_req_shorten=`expr $_AX_BOOST_BASE_TONUMERICVERSION_req : '\([[0-9]]*\.[[0-9]]*\)'` + _AX_BOOST_BASE_TONUMERICVERSION_req_major=`expr $_AX_BOOST_BASE_TONUMERICVERSION_req : '\([[0-9]]*\)'` + AS_IF([test "x$_AX_BOOST_BASE_TONUMERICVERSION_req_major" = "x"], + [AC_MSG_ERROR([You should at least specify libboost major version])]) + _AX_BOOST_BASE_TONUMERICVERSION_req_minor=`expr $_AX_BOOST_BASE_TONUMERICVERSION_req : '[[0-9]]*\.\([[0-9]]*\)'` + AS_IF([test "x$_AX_BOOST_BASE_TONUMERICVERSION_req_minor" = "x"], + [_AX_BOOST_BASE_TONUMERICVERSION_req_minor="0"]) + _AX_BOOST_BASE_TONUMERICVERSION_req_sub_minor=`expr $_AX_BOOST_BASE_TONUMERICVERSION_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'` + AS_IF([test "X$_AX_BOOST_BASE_TONUMERICVERSION_req_sub_minor" = "X"], + [_AX_BOOST_BASE_TONUMERICVERSION_req_sub_minor="0"]) + _AX_BOOST_BASE_TONUMERICVERSION_RET=`expr $_AX_BOOST_BASE_TONUMERICVERSION_req_major \* 100000 \+ $_AX_BOOST_BASE_TONUMERICVERSION_req_minor \* 100 \+ $_AX_BOOST_BASE_TONUMERICVERSION_req_sub_minor` + AS_VAR_SET($1,$_AX_BOOST_BASE_TONUMERICVERSION_RET) +]) + +dnl Run the detection of boost should be run only if $want_boost +AC_DEFUN([_AX_BOOST_BASE_RUNDETECT],[ + _AX_BOOST_BASE_TONUMERICVERSION(WANT_BOOST_VERSION,[$1]) succeeded=no + + AC_REQUIRE([AC_CANONICAL_HOST]) dnl On 64-bit systems check for system libraries in both lib64 and lib. dnl The former is specified by FHS, but e.g. Debian does not adhere to dnl this (as it rises problems for generic multi-arch support). dnl The last entry in the list is chosen by default when no libraries dnl are found, e.g. when only header-only libraries are installed! - libsubdirs="lib" - ax_arch=`uname -m` - case $ax_arch in - x86_64) - libsubdirs="lib64 libx32 lib lib64" - ;; - ppc64|s390x|sparc64|aarch64|ppc64le) - libsubdirs="lib64 lib lib64" - ;; - esac + AS_CASE([${host_cpu}], + [x86_64],[libsubdirs="lib64 libx32 lib lib64"], + [ppc64|powerpc64|s390x|sparc64|aarch64|ppc64le|powerpc64le|riscv64],[libsubdirs="lib64 lib lib64"], + [libsubdirs="lib"] + ) dnl allow for real multi-arch paths e.g. /usr/lib/x86_64-linux-gnu. Give dnl them priority over the other paths since, if libs are found there, they dnl are almost assuredly the ones desired. - AC_REQUIRE([AC_CANONICAL_HOST]) - libsubdirs="lib/${host_cpu}-${host_os} $libsubdirs" - - case ${host_cpu} in - i?86) - libsubdirs="lib/i386-${host_os} $libsubdirs" - ;; - esac - - dnl some arches may advertise a cpu type that doesn't line up with their - dnl prefix's cpu type. For example, uname may report armv7l while libs are - dnl installed to /usr/lib/arm-linux-gnueabihf. Try getting the compiler's - dnl value for an extra chance of finding the correct path. - libsubdirs="lib/`$CXX -dumpmachine 2>/dev/null` $libsubdirs" + AS_CASE([${host_cpu}], + [i?86],[multiarch_libsubdir="lib/i386-${host_os}"], + [multiarch_libsubdir="lib/${host_cpu}-${host_os}"] + ) dnl first we check the system location for boost libraries dnl this location ist chosen if boost libraries are installed with the --layout=system option dnl or if you install boost with RPM - if test "$ac_boost_path" != ""; then - BOOST_CPPFLAGS="-I$ac_boost_path/include" - for ac_boost_path_tmp in $libsubdirs; do - if test -d "$ac_boost_path"/"$ac_boost_path_tmp" ; then - BOOST_LDFLAGS="-L$ac_boost_path/$ac_boost_path_tmp" - break - fi - done - elif test "$cross_compiling" != yes; then - for ac_boost_path_tmp in /usr /usr/local /opt /opt/local ; do - if test -d "$ac_boost_path_tmp/include/boost" && test -r "$ac_boost_path_tmp/include/boost"; then - for libsubdir in $libsubdirs ; do - if ls "$ac_boost_path_tmp/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi + AS_IF([test "x$_AX_BOOST_BASE_boost_path" != "x"],[ + AC_MSG_CHECKING([for boostlib >= $1 ($WANT_BOOST_VERSION) includes in "$_AX_BOOST_BASE_boost_path/include"]) + AS_IF([test -d "$_AX_BOOST_BASE_boost_path/include" && test -r "$_AX_BOOST_BASE_boost_path/include"],[ + AC_MSG_RESULT([yes]) + BOOST_CPPFLAGS="-I$_AX_BOOST_BASE_boost_path/include" + for _AX_BOOST_BASE_boost_path_tmp in $multiarch_libsubdir $libsubdirs; do + AC_MSG_CHECKING([for boostlib >= $1 ($WANT_BOOST_VERSION) lib path in "$_AX_BOOST_BASE_boost_path/$_AX_BOOST_BASE_boost_path_tmp"]) + AS_IF([test -d "$_AX_BOOST_BASE_boost_path/$_AX_BOOST_BASE_boost_path_tmp" && test -r "$_AX_BOOST_BASE_boost_path/$_AX_BOOST_BASE_boost_path_tmp" ],[ + AC_MSG_RESULT([yes]) + BOOST_LDFLAGS="-L$_AX_BOOST_BASE_boost_path/$_AX_BOOST_BASE_boost_path_tmp"; + break; + ], + [AC_MSG_RESULT([no])]) + done],[ + AC_MSG_RESULT([no])]) + ],[ + if test X"$cross_compiling" = Xyes; then + search_libsubdirs=$multiarch_libsubdir + else + search_libsubdirs="$multiarch_libsubdir $libsubdirs" + fi + for _AX_BOOST_BASE_boost_path_tmp in /usr /usr/local /opt /opt/local ; do + if test -d "$_AX_BOOST_BASE_boost_path_tmp/include/boost" && test -r "$_AX_BOOST_BASE_boost_path_tmp/include/boost" ; then + for libsubdir in $search_libsubdirs ; do + if ls "$_AX_BOOST_BASE_boost_path_tmp/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi done - BOOST_LDFLAGS="-L$ac_boost_path_tmp/$libsubdir" - BOOST_CPPFLAGS="-I$ac_boost_path_tmp/include" + BOOST_LDFLAGS="-L$_AX_BOOST_BASE_boost_path_tmp/$libsubdir" + BOOST_CPPFLAGS="-I$_AX_BOOST_BASE_boost_path_tmp/include" break; fi done - fi + ]) dnl overwrite ld flags if we have required special directory with dnl --with-boost-libdir parameter - if test "$ac_boost_lib_path" != ""; then - BOOST_LDFLAGS="-L$ac_boost_lib_path" - fi + AS_IF([test "x$_AX_BOOST_BASE_boost_lib_path" != "x"], + [BOOST_LDFLAGS="-L$_AX_BOOST_BASE_boost_lib_path"]) + AC_MSG_CHECKING([for boostlib >= $1 ($WANT_BOOST_VERSION)]) CPPFLAGS_SAVED="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" export CPPFLAGS @@ -158,15 +177,7 @@ if test "x$want_boost" = "xyes"; then AC_REQUIRE([AC_PROG_CXX]) AC_LANG_PUSH(C++) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - @%:@include <boost/version.hpp> - ]], [[ - #if BOOST_VERSION >= $WANT_BOOST_VERSION - // Everything is okay - #else - # error Boost version is too old - #endif - ]])],[ + AC_COMPILE_IFELSE([_AX_BOOST_BASE_PROGRAM($WANT_BOOST_VERSION)],[ AC_MSG_RESULT(yes) succeeded=yes found_system=yes @@ -178,40 +189,50 @@ if test "x$want_boost" = "xyes"; then dnl if we found no boost with system layout we search for boost libraries dnl built and installed without the --layout=system option or for a staged(not installed) version - if test "x$succeeded" != "xyes"; then + if test "x$succeeded" != "xyes" ; then CPPFLAGS="$CPPFLAGS_SAVED" LDFLAGS="$LDFLAGS_SAVED" BOOST_CPPFLAGS= - BOOST_LDFLAGS= + if test -z "$_AX_BOOST_BASE_boost_lib_path" ; then + BOOST_LDFLAGS= + fi _version=0 - if test "$ac_boost_path" != ""; then - if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then - for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do - _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` + if test -n "$_AX_BOOST_BASE_boost_path" ; then + if test -d "$_AX_BOOST_BASE_boost_path" && test -r "$_AX_BOOST_BASE_boost_path"; then + for i in `ls -d $_AX_BOOST_BASE_boost_path/include/boost-* 2>/dev/null`; do + _version_tmp=`echo $i | sed "s#$_AX_BOOST_BASE_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` V_CHECK=`expr $_version_tmp \> $_version` - if test "$V_CHECK" = "1" ; then + if test "x$V_CHECK" = "x1" ; then _version=$_version_tmp fi VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'` - BOOST_CPPFLAGS="-I$ac_boost_path/include/boost-$VERSION_UNDERSCORE" + BOOST_CPPFLAGS="-I$_AX_BOOST_BASE_boost_path/include/boost-$VERSION_UNDERSCORE" done dnl if nothing found search for layout used in Windows distributions if test -z "$BOOST_CPPFLAGS"; then - if test -d "$ac_boost_path/boost" && test -r "$ac_boost_path/boost"; then - BOOST_CPPFLAGS="-I$ac_boost_path" + if test -d "$_AX_BOOST_BASE_boost_path/boost" && test -r "$_AX_BOOST_BASE_boost_path/boost"; then + BOOST_CPPFLAGS="-I$_AX_BOOST_BASE_boost_path" fi fi + dnl if we found something and BOOST_LDFLAGS was unset before + dnl (because "$_AX_BOOST_BASE_boost_lib_path" = ""), set it here. + if test -n "$BOOST_CPPFLAGS" && test -z "$BOOST_LDFLAGS"; then + for libsubdir in $libsubdirs ; do + if ls "$_AX_BOOST_BASE_boost_path/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi + done + BOOST_LDFLAGS="-L$_AX_BOOST_BASE_boost_path/$libsubdir" + fi fi else - if test "$cross_compiling" != yes; then - for ac_boost_path in /usr /usr/local /opt /opt/local ; do - if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then - for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do - _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` + if test "x$cross_compiling" != "xyes" ; then + for _AX_BOOST_BASE_boost_path in /usr /usr/local /opt /opt/local ; do + if test -d "$_AX_BOOST_BASE_boost_path" && test -r "$_AX_BOOST_BASE_boost_path" ; then + for i in `ls -d $_AX_BOOST_BASE_boost_path/include/boost-* 2>/dev/null`; do + _version_tmp=`echo $i | sed "s#$_AX_BOOST_BASE_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` V_CHECK=`expr $_version_tmp \> $_version` - if test "$V_CHECK" = "1" ; then + if test "x$V_CHECK" = "x1" ; then _version=$_version_tmp - best_path=$ac_boost_path + best_path=$_AX_BOOST_BASE_boost_path fi done fi @@ -219,7 +240,7 @@ if test "x$want_boost" = "xyes"; then VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'` BOOST_CPPFLAGS="-I$best_path/include/boost-$VERSION_UNDERSCORE" - if test "$ac_boost_lib_path" = ""; then + if test -z "$_AX_BOOST_BASE_boost_lib_path" ; then for libsubdir in $libsubdirs ; do if ls "$best_path/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi done @@ -227,7 +248,7 @@ if test "x$want_boost" = "xyes"; then fi fi - if test "x$BOOST_ROOT" != "x"; then + if test -n "$BOOST_ROOT" ; then for libsubdir in $libsubdirs ; do if ls "$BOOST_ROOT/stage/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi done @@ -236,7 +257,7 @@ if test "x$want_boost" = "xyes"; then stage_version=`echo $version_dir | sed 's/boost_//' | sed 's/_/./g'` stage_version_shorten=`expr $stage_version : '\([[0-9]]*\.[[0-9]]*\)'` V_CHECK=`expr $stage_version_shorten \>\= $_version` - if test "$V_CHECK" = "1" -a "$ac_boost_lib_path" = "" ; then + if test "x$V_CHECK" = "x1" && test -z "$_AX_BOOST_BASE_boost_lib_path" ; then AC_MSG_NOTICE(We will use a staged boost library from $BOOST_ROOT) BOOST_CPPFLAGS="-I$BOOST_ROOT" BOOST_LDFLAGS="-L$BOOST_ROOT/stage/$libsubdir" @@ -251,15 +272,7 @@ if test "x$want_boost" = "xyes"; then export LDFLAGS AC_LANG_PUSH(C++) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - @%:@include <boost/version.hpp> - ]], [[ - #if BOOST_VERSION >= $WANT_BOOST_VERSION - // Everything is okay - #else - # error Boost version is too old - #endif - ]])],[ + AC_COMPILE_IFELSE([_AX_BOOST_BASE_PROGRAM($WANT_BOOST_VERSION)],[ AC_MSG_RESULT(yes) succeeded=yes found_system=yes @@ -268,17 +281,15 @@ if test "x$want_boost" = "xyes"; then AC_LANG_POP([C++]) fi - if test "$succeeded" != "yes" ; then - if test "$_version" = "0" ; then - AC_MSG_NOTICE([[We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in <boost/version.hpp>. See http://randspringer.de/boost for more documentation.]]) + if test "x$succeeded" != "xyes" ; then + if test "x$_version" = "x0" ; then + AC_MSG_NOTICE([[We could not detect the boost libraries (version $1 or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in <boost/version.hpp>. See http://randspringer.de/boost for more documentation.]]) else AC_MSG_NOTICE([Your boost libraries seems to old (version $_version).]) fi # execute ACTION-IF-NOT-FOUND (if present): ifelse([$3], , :, [$3]) else - AC_SUBST(BOOST_CPPFLAGS) - AC_SUBST(BOOST_LDFLAGS) AC_DEFINE(HAVE_BOOST,,[define if the Boost library is available]) # execute ACTION-IF-FOUND (if present): ifelse([$2], , :, [$2]) @@ -286,6 +297,5 @@ if test "x$want_boost" = "xyes"; then CPPFLAGS="$CPPFLAGS_SAVED" LDFLAGS="$LDFLAGS_SAVED" -fi ]) diff --git a/build-aux/m4/ax_boost_system.m4 b/build-aux/m4/ax_boost_system.m4 index 1c05450cbe..207d7be8de 100644 --- a/build-aux/m4/ax_boost_system.m4 +++ b/build-aux/m4/ax_boost_system.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_boost_system.html +# https://www.gnu.org/software/autoconf-archive/ax_boost_system.html # =========================================================================== # # SYNOPSIS @@ -31,7 +31,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 18 +#serial 19 AC_DEFUN([AX_BOOST_SYSTEM], [ @@ -84,7 +84,6 @@ AC_DEFUN([AX_BOOST_SYSTEM], LDFLAGS_SAVE=$LDFLAGS if test "x$ax_boost_user_system_lib" = "x"; then - ax_lib= for libextension in `ls -r $BOOSTLIBDIR/libboost_system* 2>/dev/null | sed 's,.*/lib,,' | sed 's,\..*,,'` ; do ax_lib=${libextension} AC_CHECK_LIB($ax_lib, exit, @@ -109,7 +108,7 @@ AC_DEFUN([AX_BOOST_SYSTEM], fi if test "x$ax_lib" = "x"; then - AC_MSG_ERROR(Could not find a version of the boost_system library!) + AC_MSG_ERROR(Could not find a version of the library!) fi if test "x$link_system" = "xno"; then AC_MSG_ERROR(Could not link against $ax_lib !) diff --git a/build_msvc/.gitignore b/build_msvc/.gitignore index d5aa22c05e..8ba65dda8f 100644 --- a/build_msvc/.gitignore +++ b/build_msvc/.gitignore @@ -9,3 +9,4 @@ packages/* */x64 *.vcxproj.user *.vcxproj +*/Win32 diff --git a/build_msvc/README.md b/build_msvc/README.md index 63c5babf35..d6543e6d67 100644 --- a/build_msvc/README.md +++ b/build_msvc/README.md @@ -17,16 +17,17 @@ Options for installing the dependencies in a Visual Studio compatible manner are - Download the source code, build each dependency, add the required include paths, link libraries and binary tools to the Visual Studio project files. - Use [nuget](https://www.nuget.org/) packages with the understanding that any binary files have been compiled by an untrusted third party. -The external dependencies required for the Visual Studio build are (see the [dependencies doc](https://github.com/bitcoin/bitcoin/blob/master/doc/dependencies.md) for versions): +The external dependencies required for the Visual Studio build are (see [dependencies.md](https://github.com/bitcoin/bitcoin/blob/master/doc/dependencies.md) for more info): -- Berkeley DB, -- OpenSSL, -- Boost, -- libevent, +- Berkeley DB +- OpenSSL +- Boost +- libevent - ZeroMQ +- RapidCheck -Additional dependencies required from the [bitcoin-core](https://github.com/bitcoin-core) github repository are: -- SECP256K1, +Additional dependencies required from the [bitcoin-core](https://github.com/bitcoin-core) GitHub repository are: +- libsecp256k1 - LevelDB Building @@ -37,7 +38,7 @@ The instructions below use `vcpkg` to install the dependencies. - Install the required packages (replace x64 with x86 as required): ``` - PS >.\vcpkg install --triplet x64-windows-static boost-filesystem boost-signals2 boost-test libevent openssl zeromq berkeleydb secp256k1 leveldb + PS >.\vcpkg install --triplet x64-windows-static boost-filesystem boost-signals2 boost-test libevent openssl zeromq berkeleydb secp256k1 leveldb rapidcheck ``` - Use Python to generate *.vcxproj from Makefile diff --git a/build_msvc/bench_bitcoin/bench_bitcoin.vcxproj b/build_msvc/bench_bitcoin/bench_bitcoin.vcxproj index 723e230d3a..6ded6895cd 100644 --- a/build_msvc/bench_bitcoin/bench_bitcoin.vcxproj +++ b/build_msvc/bench_bitcoin/bench_bitcoin.vcxproj @@ -1,28 +1,15 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Label="configInitTarget" Project="..\common.init.vcxproj" /> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="..\common.init.vcxproj" /> + <PropertyGroup Label="Globals"> + <ProjectGuid>{1125654E-E1B2-4431-8B5C-62EA9A2FEECB}</ProjectGuid> + </PropertyGroup> + <PropertyGroup> + <ConfigurationType>Application</ConfigurationType> + <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> + </PropertyGroup> <ItemGroup> - <ClCompile Include="..\..\src\test\util.h" /> <ClCompile Include="..\..\src\test\util.cpp" /> - <ClCompile Include="..\..\src\test\setup_common.h" /> <ClCompile Include="..\..\src\test\setup_common.cpp" /> <ClCompile Include="..\..\src\bench\base58.cpp" /> <ClCompile Include="..\..\src\bench\bech32.cpp" /> @@ -74,143 +61,6 @@ <Project>{18430fef-6b61-4c53-b396-718e02850f1b}</Project> </ProjectReference> </ItemGroup> - <PropertyGroup Label="Globals"> - <VCProjectVersion>15.0</VCProjectVersion> - <ProjectGuid>{1125654E-E1B2-4431-8B5C-62EA9A2FEECB}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>bench_bitcoin</RootNamespace> - <VcpkgTriplet Condition="'$(Platform)'=='Win32'">x86-windows-static</VcpkgTriplet> - <VcpkgTriplet Condition="'$(Platform)'=='x64'">x64-windows-static</VcpkgTriplet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="Shared"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - <Linkage-secp256k1>static</Linkage-secp256k1> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - <Linkage-secp256k1>static</Linkage-secp256k1> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <LinkIncremental>true</LinkIncremental> - <Linkage-secp256k1>static</Linkage-secp256k1> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> - <Linkage-secp256k1>static</Linkage-secp256k1> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>NOMINMAX;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>NOMINMAX;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>NOMINMAX;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>NOMINMAX;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> <Target Name="RawBenchHeaderGen" BeforeTargets="PrepareForBuild"> <PropertyGroup> <ErrorText>There was an error executing the raw bench header generation task.</ErrorText> @@ -220,6 +70,7 @@ </ItemGroup> <HeaderFromHexdump RawFilePath="%(RawBenchFile.FullPath)" HeaderFilePath="%(RawBenchFile.FullPath).h" SourceHeader="static unsigned const char %(RawBenchFile.Filename)[] = {" SourceFooter="};" /> </Target> - <Import Label="configTarget" Project="..\common.vcxproj" /> <Import Label="hexdumpTarget" Project="..\msbuild\tasks\hexdump.targets" /> -</Project> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> +</Project>
\ No newline at end of file diff --git a/build_msvc/bitcoin-cli/bitcoin-cli.vcxproj b/build_msvc/bitcoin-cli/bitcoin-cli.vcxproj index 6b668054a3..72c55e47cc 100644 --- a/build_msvc/bitcoin-cli/bitcoin-cli.vcxproj +++ b/build_msvc/bitcoin-cli/bitcoin-cli.vcxproj @@ -1,31 +1,17 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Label="configInitTarget" Project="..\common.init.vcxproj" /> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="..\common.init.vcxproj" /> + <PropertyGroup Label="Globals"> + <ProjectGuid>{0B2D7431-F876-4A58-87BF-F748338CD3BF}</ProjectGuid> + </PropertyGroup> + <PropertyGroup> + <ConfigurationType>Application</ConfigurationType> + <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> + </PropertyGroup> <ItemGroup> <ClCompile Include="..\..\src\bitcoin-cli.cpp" /> </ItemGroup> <ItemGroup> - <None Include="packages.config" /> - </ItemGroup> - <ItemGroup> <ProjectReference Include="..\libbitcoin_cli\libbitcoin_cli.vcxproj"> <Project>{0667528c-d734-4009-adf9-c0d6c4a5a5a6}</Project> </ProjectReference> @@ -39,138 +25,6 @@ <Project>{5724ba7d-a09a-4ba8-800b-c4c1561b3d69}</Project> </ProjectReference> </ItemGroup> - <PropertyGroup Label="Globals"> - <VCProjectVersion>15.0</VCProjectVersion> - <ProjectGuid>{0B2D7431-F876-4A58-87BF-F748338CD3BF}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>bitcoincli</RootNamespace> - <VcpkgTriplet Condition="'$(Platform)'=='Win32'">x86-windows-static</VcpkgTriplet> - <VcpkgTriplet Condition="'$(Platform)'=='x64'">x64-windows-static</VcpkgTriplet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="Shared"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <Import Label="configTarget" Project="..\common.vcxproj" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> </Project> diff --git a/build_msvc/bitcoin-tx/bitcoin-tx.vcxproj b/build_msvc/bitcoin-tx/bitcoin-tx.vcxproj index 1d0174e319..6891a3e5ad 100644 --- a/build_msvc/bitcoin-tx/bitcoin-tx.vcxproj +++ b/build_msvc/bitcoin-tx/bitcoin-tx.vcxproj @@ -1,24 +1,13 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Label="configInitTarget" Project="..\common.init.vcxproj" /> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="..\common.init.vcxproj" /> + <PropertyGroup Label="Globals"> + <ProjectGuid>{D3022AF6-AD33-4CE3-B358-87CB6A1B29CF}</ProjectGuid> + </PropertyGroup> + <PropertyGroup Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> + </PropertyGroup> <ItemGroup> <ClCompile Include="..\..\src\bitcoin-tx.cpp" /> </ItemGroup> @@ -42,138 +31,6 @@ <Project>{bb493552-3b8c-4a8c-bf69-a6e7a51d2ea6}</Project> </ProjectReference> </ItemGroup> - <PropertyGroup Label="Globals"> - <VCProjectVersion>15.0</VCProjectVersion> - <ProjectGuid>{D3022AF6-AD33-4CE3-B358-87CB6A1B29CF}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>bitcointx</RootNamespace> - <VcpkgTriplet Condition="'$(Platform)'=='Win32'">x86-windows-static</VcpkgTriplet> - <VcpkgTriplet Condition="'$(Platform)'=='x64'">x64-windows-static</VcpkgTriplet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="Shared"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <Import Label="configTarget" Project="..\common.vcxproj" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> </Project> diff --git a/build_msvc/bitcoin-wallet/bitcoin-wallet.vcxproj b/build_msvc/bitcoin-wallet/bitcoin-wallet.vcxproj index fa86da7bae..996676baf9 100644 --- a/build_msvc/bitcoin-wallet/bitcoin-wallet.vcxproj +++ b/build_msvc/bitcoin-wallet/bitcoin-wallet.vcxproj @@ -1,24 +1,13 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Label="configInitTarget" Project="..\common.init.vcxproj" /> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="..\common.init.vcxproj" /> + <PropertyGroup Label="Globals"> + <ProjectGuid>{84DE8790-EDE3-4483-81AC-C32F15E861F4}</ProjectGuid> + </PropertyGroup> + <PropertyGroup Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> + </PropertyGroup> <ItemGroup> <ClCompile Include="..\..\src\bitcoin-wallet.cpp" /> </ItemGroup> @@ -60,138 +49,6 @@ <Project>{18430fef-6b61-4c53-b396-718e02850f1b}</Project> </ProjectReference> </ItemGroup> - <PropertyGroup Label="Globals"> - <VCProjectVersion>15.0</VCProjectVersion> - <ProjectGuid>{84DE8790-EDE3-4483-81AC-C32F15E861F4}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>bitcointx</RootNamespace> - <VcpkgTriplet Condition="'$(Platform)'=='Win32'">x86-windows-static</VcpkgTriplet> - <VcpkgTriplet Condition="'$(Platform)'=='x64'">x64-windows-static</VcpkgTriplet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="Shared"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <Import Label="configTarget" Project="..\common.vcxproj" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> </Project> diff --git a/build_msvc/bitcoin.sln b/build_msvc/bitcoin.sln index 45bc934d77..5a6eaf54ad 100644 --- a/build_msvc/bitcoin.sln +++ b/build_msvc/bitcoin.sln @@ -1,10 +1,10 @@ Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27130.2027 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.28803.452 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbitcoin_consensus", "libbitcoinconsensus\libbitcoinconsensus.vcxproj", "{2B384FA8-9EE1-4544-93CB-0D733C25E8CE}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbitcoinconsensus", "libbitcoinconsensus\libbitcoinconsensus.vcxproj", "{2B384FA8-9EE1-4544-93CB-0D733C25E8CE}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_libbitcoinconsensus", "testconsensus\testconsensus.vcxproj", "{E78473E9-B850-456C-9120-276301E04C06}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testconsensus", "testconsensus\testconsensus.vcxproj", "{E78473E9-B850-456C-9120-276301E04C06}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bitcoind", "bitcoind\bitcoind.vcxproj", "{D4513DDF-6013-44DC-ADCC-12EAF6D1F038}" EndProject @@ -205,9 +205,6 @@ Global HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {4ABD1207-9A90-4EC9-A8EB-203638A2605D} - SolutionGuid = {2FB733C9-24CB-4BA5-A26B-F43DAD7996B7} - SolutionGuid = {D0CAE2D0-8DB1-4A0B-80EE-800AA6C64323} SolutionGuid = {DA7D16A6-E5F0-45B3-B194-C3FE64F1BFCD} EndGlobalSection EndGlobal diff --git a/build_msvc/bitcoind/bitcoind.vcxproj b/build_msvc/bitcoind/bitcoind.vcxproj index bb212af52e..c5cddfdbb2 100644 --- a/build_msvc/bitcoind/bitcoind.vcxproj +++ b/build_msvc/bitcoind/bitcoind.vcxproj @@ -1,153 +1,13 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Label="configInitTarget" Project="..\common.init.vcxproj" /> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="..\common.init.vcxproj" /> <PropertyGroup Label="Globals"> - <VCProjectVersion>15.0</VCProjectVersion> <ProjectGuid>{D4513DDF-6013-44DC-ADCC-12EAF6D1F038}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>bitcoind</RootNamespace> - <VcpkgTriplet Condition="'$(Platform)'=='Win32'">x86-windows-static</VcpkgTriplet> - <VcpkgTriplet Condition="'$(Platform)'=='x64'">x64-windows-static</VcpkgTriplet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <PropertyGroup Label="Configuration"> <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> + <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="Shared"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> - <SuppressStartupBanner>false</SuppressStartupBanner> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> - <SuppressStartupBanner>false</SuppressStartupBanner> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalLibraryDirectories> - </AdditionalLibraryDirectories> - <AdditionalDependencies>crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> - <SuppressStartupBanner>false</SuppressStartupBanner> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalLibraryDirectories> - </AdditionalLibraryDirectories> - <AdditionalDependencies>crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> - <SuppressStartupBanner>false</SuppressStartupBanner> - </Link> - </ItemDefinitionGroup> <ItemGroup> <ClCompile Include="..\..\src\bitcoind.cpp" /> </ItemGroup> @@ -183,5 +43,32 @@ <Project>{18430fef-6b61-4c53-b396-718e02850f1b}</Project> </ProjectReference> </ItemGroup> - <Import Label="configTarget" Project="..\common.vcxproj" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <Import Label="ReplaceInFile" Project="..\msbuild\tasks\replaceinfile.targets" /> + <PropertyGroup> + <ConfigIniIn>..\..\test\config.ini.in</ConfigIniIn> + <ConfigIniOut>..\..\test\config.ini</ConfigIniOut> + </PropertyGroup> + <Target Name="AfterBuild"> + <Copy SourceFiles="$(ConfigIniIn)" DestinationFiles="$(ConfigIniOut)" ></Copy> + <ReplaceInFile FilePath="$(ConfigIniOut)" + Replace="@PACKAGE_NAME@" By="Bitcoin Core"></ReplaceInFile> + <ReplaceInFile FilePath="$(ConfigIniOut)" + Replace="@abs_top_srcdir@" By="..\.." ToFullPath="true"></ReplaceInFile> + <ReplaceInFile FilePath="$(ConfigIniOut)" + Replace="@abs_top_builddir@" By="..\.." ToFullPath="true"></ReplaceInFile> + <ReplaceInFile FilePath="$(ConfigIniOut)" + Replace="@EXEEXT@" By=".exe"></ReplaceInFile> + <ReplaceInFile FilePath="$(ConfigIniOut)" + Replace="@ENABLE_WALLET_TRUE@" By=""></ReplaceInFile> + <ReplaceInFile FilePath="$(ConfigIniOut)" + Replace="@BUILD_BITCOIN_CLI_TRUE@" By=""></ReplaceInFile> + <ReplaceInFile FilePath="$(ConfigIniOut)" + Replace="@BUILD_BITCOIND_TRUE@" By=""></ReplaceInFile> + <ReplaceInFile FilePath="$(ConfigIniOut)" + Replace="@ENABLE_FUZZ_TRUE@" By=""></ReplaceInFile> + <ReplaceInFile FilePath="$(ConfigIniOut)" + Replace="@ENABLE_ZMQ_TRUE@" By=""></ReplaceInFile> + </Target> </Project> diff --git a/build_msvc/common.init.vcxproj b/build_msvc/common.init.vcxproj index c3c0f665c2..f08ac78b21 100644 --- a/build_msvc/common.init.vcxproj +++ b/build_msvc/common.init.vcxproj @@ -1,14 +1,119 @@ <?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <PropertyGroup Condition="'$(WindowsTargetPlatformVersion)'=='' and !Exists('$(WindowsSdkDir)\DesignTime\CommonConfiguration\Neutral\Windows.props')"> - <WindowsTargetPlatformVersion_10 Condition="'$(WindowsTargetPlatformVersion_10)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0@ProductVersion)</WindowsTargetPlatformVersion_10> - <WindowsTargetPlatformVersion_10 Condition="'$(WindowsTargetPlatformVersion_10)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v10.0@ProductVersion)</WindowsTargetPlatformVersion_10> - <!-- Sometimes the version in the registry has to .0 suffix, and sometimes it doesn't. Check and add it --> - <WindowsTargetPlatformVersion_10 Condition="'$(WindowsTargetPlatformVersion_10)' != '' and !$(WindowsTargetPlatformVersion_10.EndsWith('.0'))">$(WindowsTargetPlatformVersion_10).0</WindowsTargetPlatformVersion_10> - - <WindowsTargetPlatformVersion>$(WindowsTargetPlatformVersion_10)</WindowsTargetPlatformVersion> - </PropertyGroup> - <PropertyGroup> - <Platform Condition="'$(Platform)' == ''">Win32</Platform> - </PropertyGroup> -</Project>
\ No newline at end of file +<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + + <PropertyGroup Label="Globals"> + <VCProjectVersion>16.0</VCProjectVersion> + <VcpkgTriplet Condition="'$(Platform)'=='Win32'">x86-windows-static</VcpkgTriplet> + <VcpkgTriplet Condition="'$(Platform)'=='x64'">x64-windows-static</VcpkgTriplet> +</PropertyGroup> + + <PropertyGroup Condition="'$(WindowsTargetPlatformVersion)'=='' and !Exists('$(WindowsSdkDir)\DesignTime\CommonConfiguration\Neutral\Windows.props')"> + <WindowsTargetPlatformVersion_10 Condition="'$(WindowsTargetPlatformVersion_10)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0@ProductVersion)</WindowsTargetPlatformVersion_10> + <WindowsTargetPlatformVersion_10 Condition="'$(WindowsTargetPlatformVersion_10)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v10.0@ProductVersion)</WindowsTargetPlatformVersion_10> + <!-- Sometimes the version in the registry has to .0 suffix, and sometimes it doesn't. Check and add it --> + <WindowsTargetPlatformVersion_10 Condition="'$(WindowsTargetPlatformVersion_10)' != '' and !$(WindowsTargetPlatformVersion_10.EndsWith('.0'))">$(WindowsTargetPlatformVersion_10).0</WindowsTargetPlatformVersion_10> + <WindowsTargetPlatformVersion>$(WindowsTargetPlatformVersion_10)</WindowsTargetPlatformVersion> + </PropertyGroup> + + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + + <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration"> + <LinkIncremental>true</LinkIncremental> + <WholeProgramOptimization>false</WholeProgramOptimization> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\</OutDir> + <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration"> + <LinkIncremental>false</LinkIncremental> + <WholeProgramOptimization>true</WholeProgramOptimization> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\</OutDir> + <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir> + </PropertyGroup> + +<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions> + </ClCompile> + </ItemDefinitionGroup> + + <ItemDefinitionGroup> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> + <DisableSpecificWarnings>4018;4221;4244;4267;4715;4805;</DisableSpecificWarnings> + <TreatWarningAsError>true</TreatWarningAsError> + <PreprocessorDefinitions>ZMQ_STATIC;NOMINMAX;WIN32;HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_CONSOLE;_WIN32_WINNT=0x0601;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>..\..\src;..\..\src\univalue\include;..\..\src\secp256k1\include;..\..\src\leveldb\include;..\..\src\leveldb\helpers\memenv;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <Import Project="common.init.vcxproj.user" Condition="Exists('common.init.vcxproj.user')" /> +</Project> diff --git a/build_msvc/common.vcxproj b/build_msvc/common.vcxproj deleted file mode 100644 index 889dc6c2ad..0000000000 --- a/build_msvc/common.vcxproj +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <PropertyGroup> - <BuildDependsOn> - CopyBitcoinConfig; - CopySecp256k1Config; - $(BuildDependsOn); - </BuildDependsOn> - </PropertyGroup> - <Target Name="CopyBitcoinConfig" - Inputs="$(MSBuildThisFileDirectory)bitcoin_config.h" - Outputs="$(MSBuildThisFileDirectory)..\src\config\bitcoin-config.h"> - <Copy SourceFiles="$(MSBuildThisFileDirectory)bitcoin_config.h" DestinationFiles="$(MSBuildThisFileDirectory)..\src\config\bitcoin-config.h" /> - </Target> - <Target Name="CopySecp256k1Config" - Inputs="$(MSBuildThisFileDirectory)libsecp256k1_config.h" - Outputs="$(MSBuildThisFileDirectory)..\src\secp256k1\src\libsecp256k1-config.h"> - <Copy SourceFiles="$(MSBuildThisFileDirectory)libsecp256k1_config.h" DestinationFiles="$(MSBuildThisFileDirectory)..\src\secp256k1\src\libsecp256k1-config.h" /> - </Target> - <ItemDefinitionGroup> - <ClCompile> - <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> - <DisableSpecificWarnings>4018;4244;4267;4715;4805;</DisableSpecificWarnings> - <TreatWarningAsError>true</TreatWarningAsError> - <PreprocessorDefinitions>_WIN32_WINNT=0x0601;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>..\..\src;..\..\src\univalue\include;..\..\src\secp256k1\include;..\..\src\leveldb\include;..\..\src\leveldb\helpers\memenv;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - </ClCompile> - </ItemDefinitionGroup> -</Project> diff --git a/build_msvc/libbitcoin_cli/libbitcoin_cli.vcxproj.in b/build_msvc/libbitcoin_cli/libbitcoin_cli.vcxproj.in index 5849e463a6..5f6cf608af 100644 --- a/build_msvc/libbitcoin_cli/libbitcoin_cli.vcxproj.in +++ b/build_msvc/libbitcoin_cli/libbitcoin_cli.vcxproj.in @@ -1,158 +1,15 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Label="configInitTarget" Project="..\common.init.vcxproj" /> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <ItemGroup> -@SOURCE_FILES@ - </ItemGroup> - <ItemGroup> - <None Include="packages.config" /> - </ItemGroup> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="..\common.init.vcxproj" /> <PropertyGroup Label="Globals"> - <VCProjectVersion>15.0</VCProjectVersion> <ProjectGuid>{0667528C-D734-4009-ADF9-C0D6C4A5A5A6}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>libbitcoin_cli</RootNamespace> - <VcpkgTriplet Condition="'$(Platform)'=='Win32'">x86-windows-static</VcpkgTriplet> - <VcpkgTriplet Condition="'$(Platform)'=='x64'">x64-windows-static</VcpkgTriplet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <PropertyGroup> <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> </PropertyGroup> + <ItemGroup> +@SOURCE_FILES@ + </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="Shared"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <Import Label="configTarget" Project="..\common.vcxproj" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> </Project> diff --git a/build_msvc/libbitcoin_common/libbitcoin_common.vcxproj.in b/build_msvc/libbitcoin_common/libbitcoin_common.vcxproj.in index 292e193f5d..0bd9b3cd89 100644 --- a/build_msvc/libbitcoin_common/libbitcoin_common.vcxproj.in +++ b/build_msvc/libbitcoin_common/libbitcoin_common.vcxproj.in @@ -1,170 +1,15 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Label="configInitTarget" Project="..\common.init.vcxproj" /> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="..\common.init.vcxproj" /> <PropertyGroup Label="Globals"> - <VCProjectVersion>15.0</VCProjectVersion> <ProjectGuid>{7C87E378-DF58-482E-AA2F-1BC129BC19CE}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>libbitcoin_common</RootNamespace> - <VcpkgTriplet Condition="'$(Platform)'=='Win32'">x86-windows-static</VcpkgTriplet> - <VcpkgTriplet Condition="'$(Platform)'=='x64'">x64-windows-static</VcpkgTriplet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <PropertyGroup Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="Shared"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <SuppressStartupBanner>false</SuppressStartupBanner> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalLibraryDirectories> - </AdditionalLibraryDirectories> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <SuppressStartupBanner>false</SuppressStartupBanner> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalLibraryDirectories> - </AdditionalLibraryDirectories> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <SuppressStartupBanner>false</SuppressStartupBanner> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalLibraryDirectories> - </AdditionalLibraryDirectories> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <SuppressStartupBanner>false</SuppressStartupBanner> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalLibraryDirectories> - </AdditionalLibraryDirectories> - </Link> - </ItemDefinitionGroup> <ItemGroup> @SOURCE_FILES@ </ItemGroup> - <ItemGroup> - <None Include="packages.config" /> - </ItemGroup> - <Import Label="configTarget" Project="..\common.vcxproj" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> </Project> diff --git a/build_msvc/libbitcoin_crypto/libbitcoin_crypto.vcxproj.in b/build_msvc/libbitcoin_crypto/libbitcoin_crypto.vcxproj.in index e7002036ad..abf1a7ac02 100644 --- a/build_msvc/libbitcoin_crypto/libbitcoin_crypto.vcxproj.in +++ b/build_msvc/libbitcoin_crypto/libbitcoin_crypto.vcxproj.in @@ -1,153 +1,15 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Label="configInitTarget" Project="..\common.init.vcxproj" /> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="..\common.init.vcxproj" /> <PropertyGroup Label="Globals"> - <VCProjectVersion>15.0</VCProjectVersion> <ProjectGuid>{6190199C-6CF4-4DAD-BFBD-93FA72A760C1}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>libbitcoin_crypto</RootNamespace> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <PropertyGroup Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="Shared"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> <ItemGroup> @SOURCE_FILES@ </ItemGroup> - <Import Label="configTarget" Project="..\common.vcxproj" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> </Project> diff --git a/build_msvc/libbitcoin_server/libbitcoin_server.vcxproj.in b/build_msvc/libbitcoin_server/libbitcoin_server.vcxproj.in index 0b4aa1e407..8e2ed394f8 100644 --- a/build_msvc/libbitcoin_server/libbitcoin_server.vcxproj.in +++ b/build_msvc/libbitcoin_server/libbitcoin_server.vcxproj.in @@ -1,165 +1,18 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Label="configInitTarget" Project="..\common.init.vcxproj" /> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="..\common.init.vcxproj" /> <PropertyGroup Label="Globals"> - <VCProjectVersion>15.0</VCProjectVersion> <ProjectGuid>{460FEE33-1FE1-483F-B3BF-931FF8E969A5}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>libbitcoin_server</RootNamespace> - <VcpkgTriplet Condition="'$(Platform)'=='Win32'">x86-windows-static</VcpkgTriplet> - <VcpkgTriplet Condition="'$(Platform)'=='x64'">x64-windows-static</VcpkgTriplet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <PropertyGroup Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="Shared"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - <SuppressStartupBanner>false</SuppressStartupBanner> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemGroup> + <ItemGroup> @SOURCE_FILES@ <ClCompile Include="..\..\src\wallet\init.cpp"> <ObjectFileName>$(IntDir)wallet_init.obj</ObjectFileName> </ClCompile> </ItemGroup> - <ItemGroup> - <None Include="packages.config" /> - </ItemGroup> - <ItemGroup> - <ClInclude Include="..\..\srcpcegister.h" /> - </ItemGroup> - <Import Label="configTarget" Project="..\common.vcxproj" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> </Project>
\ No newline at end of file diff --git a/build_msvc/libbitcoin_util/libbitcoin_util.vcxproj.in b/build_msvc/libbitcoin_util/libbitcoin_util.vcxproj.in index dbd91cf4db..71364d96b1 100644 --- a/build_msvc/libbitcoin_util/libbitcoin_util.vcxproj.in +++ b/build_msvc/libbitcoin_util/libbitcoin_util.vcxproj.in @@ -1,176 +1,15 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Label="configInitTarget" Project="..\common.init.vcxproj" /> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="..\common.init.vcxproj" /> <PropertyGroup Label="Globals"> - <VCProjectVersion>15.0</VCProjectVersion> <ProjectGuid>{B53A5535-EE9D-4C6F-9A26-F79EE3BC3754}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>libbitcoin_util</RootNamespace> - <ProjectName>libbitcoin_util</ProjectName> - <VcpkgTriplet Condition="'$(Platform)'=='Win32'">x86-windows-static</VcpkgTriplet> - <VcpkgTriplet Condition="'$(Platform)'=='x64'">x64-windows-static</VcpkgTriplet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <PropertyGroup Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="Shared"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalLibraryDirectories> - </AdditionalLibraryDirectories> - </Link> - <ProjectReference> - <LinkLibraryDependencies>false</LinkLibraryDependencies> - </ProjectReference> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalLibraryDirectories> - </AdditionalLibraryDirectories> - </Link> - <ProjectReference> - <LinkLibraryDependencies>false</LinkLibraryDependencies> - </ProjectReference> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalLibraryDirectories> - </AdditionalLibraryDirectories> - </Link> - <ProjectReference> - <LinkLibraryDependencies>false</LinkLibraryDependencies> - </ProjectReference> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalLibraryDirectories> - </AdditionalLibraryDirectories> - </Link> - <ProjectReference> - <LinkLibraryDependencies>false</LinkLibraryDependencies> - </ProjectReference> - </ItemDefinitionGroup> <ItemGroup> @SOURCE_FILES@ </ItemGroup> - <Import Label="configTarget" Project="..\common.vcxproj" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> </Project> diff --git a/build_msvc/libbitcoin_wallet/libbitcoin_wallet.vcxproj.in b/build_msvc/libbitcoin_wallet/libbitcoin_wallet.vcxproj.in index 33f4054546..b67f3904a4 100644 --- a/build_msvc/libbitcoin_wallet/libbitcoin_wallet.vcxproj.in +++ b/build_msvc/libbitcoin_wallet/libbitcoin_wallet.vcxproj.in @@ -1,162 +1,15 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Label="configInitTarget" Project="..\common.init.vcxproj" /> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <ItemGroup> -@SOURCE_FILES@ - </ItemGroup> - <ItemGroup> - <None Include="packages.config" /> - </ItemGroup> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="..\common.init.vcxproj" /> <PropertyGroup Label="Globals"> - <VCProjectVersion>15.0</VCProjectVersion> <ProjectGuid>{93B86837-B543-48A5-A89B-7C87ABB77DF2}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>libbitcoin_wallet</RootNamespace> - <VcpkgTriplet Condition="'$(Platform)'=='Win32'">x86-windows-static</VcpkgTriplet> - <VcpkgTriplet Condition="'$(Platform)'=='x64'">x64-windows-static</VcpkgTriplet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <PropertyGroup Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> </PropertyGroup> + <ItemGroup> +@SOURCE_FILES@ + </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="Shared"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <Import Label="configTarget" Project="..\common.vcxproj" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> </Project> diff --git a/build_msvc/libbitcoin_wallet_tool/libbitcoin_wallet_tool.vcxproj.in b/build_msvc/libbitcoin_wallet_tool/libbitcoin_wallet_tool.vcxproj.in index 187d955687..b8d0f4b442 100644 --- a/build_msvc/libbitcoin_wallet_tool/libbitcoin_wallet_tool.vcxproj.in +++ b/build_msvc/libbitcoin_wallet_tool/libbitcoin_wallet_tool.vcxproj.in @@ -1,162 +1,15 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Label="configInitTarget" Project="..\common.init.vcxproj" /> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <ItemGroup> -@SOURCE_FILES@ - </ItemGroup> - <ItemGroup> - <None Include="packages.config" /> - </ItemGroup> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="..\common.init.vcxproj" /> <PropertyGroup Label="Globals"> - <VCProjectVersion>15.0</VCProjectVersion> <ProjectGuid>{F91AC55E-6F5E-4C58-9AC5-B40DB7DEEF93}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>libbitcoin_zmq</RootNamespace> - <VcpkgTriplet Condition="'$(Platform)'=='Win32'">x86-windows-static</VcpkgTriplet> - <VcpkgTriplet Condition="'$(Platform)'=='x64'">x64-windows-static</VcpkgTriplet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <PropertyGroup Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> </PropertyGroup> + <ItemGroup> +@SOURCE_FILES@ + </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="Shared"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>NOMINMAX;ZMQ_STATIC;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - <SuppressStartupBanner>false</SuppressStartupBanner> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>NOMINMAX;ZMQ_STATIC;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - <SuppressStartupBanner>false</SuppressStartupBanner> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>NOMINMAX;ZMQ_STATIC;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <SuppressStartupBanner>false</SuppressStartupBanner> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>NOMINMAX;ZMQ_STATIC;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <SuppressStartupBanner>false</SuppressStartupBanner> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <Import Label="configTarget" Project="..\common.vcxproj" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> </Project> diff --git a/build_msvc/libbitcoin_zmq/libbitcoin_zmq.vcxproj.in b/build_msvc/libbitcoin_zmq/libbitcoin_zmq.vcxproj.in index c877a280c0..1b2c27e53f 100644 --- a/build_msvc/libbitcoin_zmq/libbitcoin_zmq.vcxproj.in +++ b/build_msvc/libbitcoin_zmq/libbitcoin_zmq.vcxproj.in @@ -1,162 +1,15 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Label="configInitTarget" Project="..\common.init.vcxproj" /> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <ItemGroup> -@SOURCE_FILES@ - </ItemGroup> - <ItemGroup> - <None Include="packages.config" /> - </ItemGroup> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="..\common.init.vcxproj" /> <PropertyGroup Label="Globals"> - <VCProjectVersion>15.0</VCProjectVersion> <ProjectGuid>{792D487F-F14C-49FC-A9DE-3FC150F31C3F}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>libbitcoin_zmq</RootNamespace> - <VcpkgTriplet Condition="'$(Platform)'=='Win32'">x86-windows-static</VcpkgTriplet> - <VcpkgTriplet Condition="'$(Platform)'=='x64'">x64-windows-static</VcpkgTriplet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <PropertyGroup Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> </PropertyGroup> + <ItemGroup> +@SOURCE_FILES@ + </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="Shared"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>NOMINMAX;ZMQ_STATIC;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - <SuppressStartupBanner>false</SuppressStartupBanner> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>NOMINMAX;ZMQ_STATIC;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - <SuppressStartupBanner>false</SuppressStartupBanner> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>NOMINMAX;ZMQ_STATIC;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <SuppressStartupBanner>false</SuppressStartupBanner> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>NOMINMAX;ZMQ_STATIC;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <SuppressStartupBanner>false</SuppressStartupBanner> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <Import Label="configTarget" Project="..\common.vcxproj" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> </Project> diff --git a/build_msvc/libbitcoinconsensus/libbitcoinconsensus.vcxproj b/build_msvc/libbitcoinconsensus/libbitcoinconsensus.vcxproj index 227b1ebcd2..9c8931021b 100644 --- a/build_msvc/libbitcoinconsensus/libbitcoinconsensus.vcxproj +++ b/build_msvc/libbitcoinconsensus/libbitcoinconsensus.vcxproj @@ -1,24 +1,12 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Label="configInitTarget" Project="..\common.init.vcxproj" /> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="..\common.init.vcxproj" /> + <PropertyGroup Label="Globals"> + <ProjectGuid>{2B384FA8-9EE1-4544-93CB-0D733C25E8CE}</ProjectGuid> + </PropertyGroup> + <PropertyGroup Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + </PropertyGroup> <ItemGroup> <ClCompile Include="..\..\src\arith_uint256.cpp" /> <ClCompile Include="..\..\src\consensus\merkle.cpp" /> @@ -43,154 +31,6 @@ <ClCompile Include="..\..\src\uint256.cpp" /> <ClCompile Include="..\..\src\util\strencodings.cpp" /> </ItemGroup> - <ItemGroup> - <None Include="packages.config" /> - </ItemGroup> - <PropertyGroup Label="Globals"> - <VCProjectVersion>15.0</VCProjectVersion> - <ProjectGuid>{2B384FA8-9EE1-4544-93CB-0D733C25E8CE}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>bitcoind</RootNamespace> - <ProjectName>libbitcoin_consensus</ProjectName> - <VcpkgTriplet Condition="'$(Platform)'=='Win32'">x86-windows-static</VcpkgTriplet> - <VcpkgTriplet Condition="'$(Platform)'=='x64'">x64-windows-static</VcpkgTriplet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="Shared"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - <Linkage-secp256k1> - </Linkage-secp256k1> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <LinkIncremental>true</LinkIncremental> - <Linkage-secp256k1> - </Linkage-secp256k1> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>true</LinkIncremental> - <Linkage-secp256k1> - </Linkage-secp256k1> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>true</LinkIncremental> - <Linkage-secp256k1> - </Linkage-secp256k1> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>false</SDLCheck> - <ExceptionHandling>Sync</ExceptionHandling> - <SuppressStartupBanner>false</SuppressStartupBanner> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>false</SDLCheck> - <ExceptionHandling>Sync</ExceptionHandling> - <SuppressStartupBanner>false</SuppressStartupBanner> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>false</SDLCheck> - <ExceptionHandling>Sync</ExceptionHandling> - <SuppressStartupBanner>false</SuppressStartupBanner> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>false</SDLCheck> - <ExceptionHandling>Sync</ExceptionHandling> - <SuppressStartupBanner>false</SuppressStartupBanner> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <Import Label="configTarget" Project="..\common.vcxproj" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> </Project>
\ No newline at end of file diff --git a/build_msvc/libleveldb/libleveldb.vcxproj b/build_msvc/libleveldb/libleveldb.vcxproj index 545508001e..4689bdc45e 100644 --- a/build_msvc/libleveldb/libleveldb.vcxproj +++ b/build_msvc/libleveldb/libleveldb.vcxproj @@ -1,24 +1,12 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Label="configInitTarget" Project="..\common.init.vcxproj" /> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="..\common.init.vcxproj" /> + <PropertyGroup Label="Globals"> + <ProjectGuid>{18430FEF-6B61-4C53-B396-718E02850F1B}</ProjectGuid> + </PropertyGroup> + <PropertyGroup Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + </PropertyGroup> <ItemGroup> <ClCompile Include="..\..\src\leveldb\db\builder.cc" /> <ClCompile Include="..\..\src\leveldb\db\c.cc" /> @@ -62,141 +50,13 @@ <ClCompile Include="..\..\src\leveldb\util\options.cc" /> <ClCompile Include="..\..\src\leveldb\util\status.cc" /> </ItemGroup> - <PropertyGroup Label="Globals"> - <VCProjectVersion>15.0</VCProjectVersion> - <ProjectGuid>{18430FEF-6B61-4C53-B396-718E02850F1B}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>libunivalue</RootNamespace> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="Shared"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;NOMINMAX;LEVELDB_PLATFORM_WINDOWS;LEVELDB_ATOMIC_PRESENT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <AdditionalIncludeDirectories>..\..\src\leveldb;..\..\src\leveldb\include;</AdditionalIncludeDirectories> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;NOMINMAX;LEVELDB_PLATFORM_WINDOWS;LEVELDB_ATOMIC_PRESENT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <AdditionalIncludeDirectories>..\..\src\leveldb;..\..\src\leveldb\include;</AdditionalIncludeDirectories> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;NOMINMAX;LEVELDB_PLATFORM_WINDOWS;LEVELDB_ATOMIC_PRESENT;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <AdditionalIncludeDirectories>..\..\src\leveldb;..\..\src\leveldb\include;</AdditionalIncludeDirectories> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;NOMINMAX;LEVELDB_PLATFORM_WINDOWS;LEVELDB_ATOMIC_PRESENT;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <AdditionalIncludeDirectories>..\..\src\leveldb;..\..\src\leveldb\include;</AdditionalIncludeDirectories> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <Import Label="configTarget" Project="..\common.vcxproj" /> <ItemDefinitionGroup> <ClCompile> - <TreatWarningAsError>false</TreatWarningAsError> - </ClCompile> + <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;LEVELDB_PLATFORM_WINDOWS;LEVELDB_ATOMIC_PRESENT;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <DisableSpecificWarnings>4244;4267;4312;</DisableSpecificWarnings> + <AdditionalIncludeDirectories>..\..\src\leveldb;..\..\src\leveldb\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> </ItemDefinitionGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> </Project> diff --git a/build_msvc/libsecp256k1/libsecp256k1.vcxproj b/build_msvc/libsecp256k1/libsecp256k1.vcxproj index b4c9ec28ee..644f44350e 100644 --- a/build_msvc/libsecp256k1/libsecp256k1.vcxproj +++ b/build_msvc/libsecp256k1/libsecp256k1.vcxproj @@ -1,157 +1,21 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Label="configInitTarget" Project="..\common.init.vcxproj" /> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\..\src\secp256k1\src\secp256k1.c" /> - </ItemGroup> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="..\common.init.vcxproj" /> <PropertyGroup Label="Globals"> - <VCProjectVersion>15.0</VCProjectVersion> <ProjectGuid>{BB493552-3B8C-4A8C-BF69-A6E7A51D2EA6}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>libunivalue</RootNamespace> </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <PropertyGroup Label="Configuration"> <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="Shared"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <LinkIncremental>true</LinkIncremental> </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>ENABLE_MODULE_ECDH;ENABLE_MODULE_RECOVERY;HAVE_CONFIG_H;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <AdditionalIncludeDirectories>..\..\src\secp256k1;</AdditionalIncludeDirectories> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>ENABLE_MODULE_ECDH;ENABLE_MODULE_RECOVERY;HAVE_CONFIG_H;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <AdditionalIncludeDirectories>..\..\src\secp256k1;</AdditionalIncludeDirectories> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>ENABLE_MODULE_ECDH;ENABLE_MODULE_RECOVERY;HAVE_CONFIG_H;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <AdditionalIncludeDirectories>..\..\src\secp256k1;</AdditionalIncludeDirectories> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ItemGroup> + <ClCompile Include="..\..\src\secp256k1\src\secp256k1.c" /> + </ItemGroup> + <ItemDefinitionGroup> <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>ENABLE_MODULE_ECDH;ENABLE_MODULE_RECOVERY;HAVE_CONFIG_H;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <AdditionalIncludeDirectories>..\..\src\secp256k1;</AdditionalIncludeDirectories> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> + <PreprocessorDefinitions>ENABLE_MODULE_ECDH;ENABLE_MODULE_RECOVERY;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>..\..\src\secp256k1;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> </ItemDefinitionGroup> - <Import Label="configTarget" Project="..\common.vcxproj" /> -</Project> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> +</Project>
\ No newline at end of file diff --git a/build_msvc/libunivalue/libunivalue.vcxproj b/build_msvc/libunivalue/libunivalue.vcxproj index c3799b6408..92a9115711 100644 --- a/build_msvc/libunivalue/libunivalue.vcxproj +++ b/build_msvc/libunivalue/libunivalue.vcxproj @@ -1,160 +1,18 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Label="configInitTarget" Project="..\common.init.vcxproj" /> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="..\common.init.vcxproj" /> + <PropertyGroup Label="Globals"> + <ProjectGuid>{5724BA7D-A09A-4BA8-800B-C4C1561B3D69}</ProjectGuid> + </PropertyGroup> + <PropertyGroup Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + </PropertyGroup> <ItemGroup> <ClCompile Include="..\..\src\univalue\lib\univalue.cpp" /> <ClCompile Include="..\..\src\univalue\lib\univalue_get.cpp" /> <ClCompile Include="..\..\src\univalue\lib\univalue_read.cpp" /> <ClCompile Include="..\..\src\univalue\lib\univalue_write.cpp" /> </ItemGroup> - <PropertyGroup Label="Globals"> - <VCProjectVersion>15.0</VCProjectVersion> - <ProjectGuid>{5724BA7D-A09A-4BA8-800B-C4C1561B3D69}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>libunivalue</RootNamespace> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="Shared"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <AdditionalIncludeDirectories>..\..\src\univalue\include;</AdditionalIncludeDirectories> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <AdditionalIncludeDirectories>..\..\src\univalue\include;</AdditionalIncludeDirectories> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <AdditionalIncludeDirectories>..\..\src\univalue\include;</AdditionalIncludeDirectories> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <AdditionalIncludeDirectories>..\..\src\univalue\include;</AdditionalIncludeDirectories> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <Import Label="configTarget" Project="..\common.vcxproj" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> </Project> diff --git a/build_msvc/msbuild/tasks/replaceinfile.targets b/build_msvc/msbuild/tasks/replaceinfile.targets new file mode 100644 index 0000000000..2ccb8b30e0 --- /dev/null +++ b/build_msvc/msbuild/tasks/replaceinfile.targets @@ -0,0 +1,35 @@ +<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <UsingTask + TaskName="ReplaceInFile" + TaskFactory="CodeTaskFactory" + AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll" > + <ParameterGroup> + <FilePath Required="true" /> + <Replace Required="true" /> + <By Required="false" /> + <ToFullPath Required="false" /> + </ParameterGroup> + <Task> + <Using Namespace="System"/> + <Using Namespace="System.IO"/> + <Code Type="Fragment" Language="cs"> +<![CDATA[ +if(File.Exists(FilePath) == false) { + Log.LogError("replaceinfile task could not locate " + FilePath + "."); +} +else { + var data = File.ReadAllText(FilePath); + var by = By; + if (ToFullPath == "true") + { + by = Path.GetFullPath(by); + } + data = data.Replace(Replace, by); + Log.LogMessage("Replace '" + Replace + "' by '" + by + "' in " + FilePath); + File.WriteAllText(FilePath, data, new System.Text.UTF8Encoding(false)); +} +]]> + </Code> + </Task> + </UsingTask> +</Project>
\ No newline at end of file diff --git a/build_msvc/msvc-autogen.py b/build_msvc/msvc-autogen.py index c8df29eecb..b612467bf3 100644 --- a/build_msvc/msvc-autogen.py +++ b/build_msvc/msvc-autogen.py @@ -2,8 +2,11 @@ import os import re +import argparse +from shutil import copyfile SOURCE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'src')) +DEFAULT_PLATFORM_TOOLSET = R'v141' libs = [ 'libbitcoin_cli', @@ -42,8 +45,21 @@ def parse_makefile(makefile): lib_sources[current_lib] = [] break +def set_common_properties(toolset): + with open(os.path.join(SOURCE_DIR, '../build_msvc/common.init.vcxproj'), 'r', encoding='utf-8') as rfile: + s = rfile.read() + s = re.sub('<PlatformToolset>.*?</PlatformToolset>', '<PlatformToolset>'+toolset+'</PlatformToolset>', s) + with open(os.path.join(SOURCE_DIR, '../build_msvc/common.init.vcxproj'), 'w', encoding='utf-8',newline='\n') as wfile: + wfile.write(s) def main(): + parser = argparse.ArgumentParser(description='Bitcoin-core msbuild configuration initialiser.') + parser.add_argument('-toolset', nargs='?',help='Optionally sets the msbuild platform toolset, e.g. v142 for Visual Studio 2019.' + ' default is %s.'%DEFAULT_PLATFORM_TOOLSET) + args = parser.parse_args() + if args.toolset: + set_common_properties(args.toolset) + for makefile_name in os.listdir(SOURCE_DIR): if 'Makefile' in makefile_name: parse_makefile(os.path.join(SOURCE_DIR, makefile_name)) @@ -58,7 +74,8 @@ def main(): with open(vcxproj_filename, 'w', encoding='utf-8') as vcxproj_file: vcxproj_file.write(vcxproj_in_file.read().replace( '@SOURCE_FILES@\n', content)) - + copyfile(os.path.join(SOURCE_DIR,'../build_msvc/bitcoin_config.h'), os.path.join(SOURCE_DIR, 'config/bitcoin-config.h')) + copyfile(os.path.join(SOURCE_DIR,'../build_msvc/libsecp256k1_config.h'), os.path.join(SOURCE_DIR, 'secp256k1/src/libsecp256k1-config.h')) if __name__ == '__main__': main() diff --git a/build_msvc/test_bitcoin/test_bitcoin.vcxproj b/build_msvc/test_bitcoin/test_bitcoin.vcxproj index 92fe95bddc..64bdb5f492 100644 --- a/build_msvc/test_bitcoin/test_bitcoin.vcxproj +++ b/build_msvc/test_bitcoin/test_bitcoin.vcxproj @@ -1,24 +1,13 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Label="configInitTarget" Project="..\common.init.vcxproj" /> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="..\common.init.vcxproj" /> + <PropertyGroup Label="Globals"> + <ProjectGuid>{A56B73DB-D46D-4882-8374-1FE3FFA08F07}</ProjectGuid> + </PropertyGroup> + <PropertyGroup Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> + </PropertyGroup> <ItemGroup> <ClCompile Include="..\..\src\test\*_tests.cpp" /> <ClCompile Include="..\..\src\test\*_properties.cpp" /> @@ -63,140 +52,6 @@ <Project>{18430fef-6b61-4c53-b396-718e02850f1b}</Project> </ProjectReference> </ItemGroup> - <PropertyGroup Label="Globals"> - <VCProjectVersion>15.0</VCProjectVersion> - <ProjectGuid>{A56B73DB-D46D-4882-8374-1FE3FFA08F07}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>test_bitcoin</RootNamespace> - <VcpkgTriplet Condition="'$(Platform)'=='Win32'">x86-windows-static</VcpkgTriplet> - <VcpkgTriplet Condition="'$(Platform)'=='x64'">x64-windows-static</VcpkgTriplet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="Shared"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NOMINMAX;WIN32;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <SuppressStartupBanner>false</SuppressStartupBanner> - <AdditionalDependencies>boost_test_exec_monitor-vc140-mt-gd.lib;crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NOMINMAX;WIN32;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>boost_test_exec_monitor-vc140-mt-gd.lib;crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NOMINMAX;WIN32;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>boost_test_exec_monitor-vc140-mt.lib;crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NOMINMAX;WIN32;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>boost_test_exec_monitor-vc140-mt.lib;crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> <Target Name="RawBenchHeaderGen" BeforeTargets="PrepareForBuild"> <PropertyGroup> <ErrorText>There was an error executing the JSON test header generation task.</ErrorText> @@ -206,6 +61,7 @@ </ItemGroup> <HeaderFromHexdump RawFilePath="%(JsonTestFile.FullPath)" HeaderFilePath="%(JsonTestFile.FullPath).h" SourceHeader="namespace json_tests{ static unsigned const char %(JsonTestFile.Filename)[] = {" SourceFooter="};}" /> </Target> - <Import Label="configTarget" Project="..\common.vcxproj" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Label="hexdumpTarget" Project="..\msbuild\tasks\hexdump.targets" /> </Project> diff --git a/build_msvc/testconsensus/testconsensus.vcxproj b/build_msvc/testconsensus/testconsensus.vcxproj index a2f5659049..9a6da3ecae 100644 --- a/build_msvc/testconsensus/testconsensus.vcxproj +++ b/build_msvc/testconsensus/testconsensus.vcxproj @@ -1,172 +1,27 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Label="configInitTarget" Project="..\common.init.vcxproj" /> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="..\common.init.vcxproj" /> <PropertyGroup Label="Globals"> - <VCProjectVersion>15.0</VCProjectVersion> <ProjectGuid>{E78473E9-B850-456C-9120-276301E04C06}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>testconsensus</RootNamespace> - <ProjectName>test_libbitcoinconsensus</ProjectName> - <VcpkgTriplet Condition="'$(Platform)'=='Win32'">x86-windows-static</VcpkgTriplet> - <VcpkgTriplet Condition="'$(Platform)'=='x64'">x64-windows-static</VcpkgTriplet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <PropertyGroup Label="Configuration"> <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> + <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="Shared"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <LinkIncremental>true</LinkIncremental> - <Linkage-secp256k1>static</Linkage-secp256k1> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - <Linkage-secp256k1>static</Linkage-secp256k1> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - <Linkage-secp256k1>static</Linkage-secp256k1> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_SCL_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <DataExecutionPrevention>true</DataExecutionPrevention> - <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> <ItemGroup> <ClCompile Include="testconsensus.cpp" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\libbitcoinconsensus\libbitcoinconsensus.vcxproj"> - <Project>{2b384fa8-9ee1-4544-93cb-0d733c25e8ce}</Project> + <Project>{2B384FA8-9EE1-4544-93CB-0D733C25E8CE}</Project> </ProjectReference> <ProjectReference Include="..\libbitcoin_util\libbitcoin_util.vcxproj"> - <Project>{b53a5535-ee9d-4c6f-9a26-f79ee3bc3754}</Project> + <Project>{B53A5535-EE9D-4C6F-9A26-F79EE3BC3754}</Project> </ProjectReference> <ProjectReference Include="..\libsecp256k1\libsecp256k1.vcxproj"> - <Project>{bb493552-3b8c-4a8c-bf69-a6e7a51d2ea6}</Project> + <Project>{BB493552-3B8C-4A8C-BF69-A6E7A51D2EA6}</Project> </ProjectReference> </ItemGroup> - <Import Label="configTarget" Project="..\common.vcxproj" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> </Project> diff --git a/contrib/devtools/README.md b/contrib/devtools/README.md index 0c8c396503..4994d7f0a5 100644 --- a/contrib/devtools/README.md +++ b/contrib/devtools/README.md @@ -144,7 +144,7 @@ Then do: Create and verify timestamps of merge commits --------------------------------------------- To create or verify timestamps on the merge commits, install the OpenTimestamps -client via `pip3 install opentimestamps-client`. Then, dowload the gpg wrapper +client via `pip3 install opentimestamps-client`. Then, download the gpg wrapper `ots-git-gpg-wrapper.sh` and set it as git's `gpg.program`. See [the ots git integration documentation](https://github.com/opentimestamps/opentimestamps-client/blob/master/doc/git-integration.md#usage) for further details. diff --git a/contrib/devtools/copyright_header.py b/contrib/devtools/copyright_header.py index f2987f2260..fc01e570aa 100755 --- a/contrib/devtools/copyright_header.py +++ b/contrib/devtools/copyright_header.py @@ -34,7 +34,7 @@ EXCLUDE_DIRS = [ "src/univalue/", ] -INCLUDE = ['*.h', '*.cpp', '*.cc', '*.c', '*.py'] +INCLUDE = ['*.h', '*.cpp', '*.cc', '*.c', '*.mm', '*.py'] INCLUDE_COMPILED = re.compile('|'.join([fnmatch.translate(m) for m in INCLUDE])) def applies_to_file(filename): @@ -90,14 +90,12 @@ def compile_copyright_regex(copyright_style, year_style, name): EXPECTED_HOLDER_NAMES = [ "Satoshi Nakamoto\n", "The Bitcoin Core developers\n", - "Bitcoin Core Developers\n", "BitPay Inc\.\n", "University of Illinois at Urbana-Champaign\.\n", "Pieter Wuille\n", "Wladimir J. van der Laan\n", "Jeff Garzik\n", "Jan-Klaas Kollhof\n", - "Sam Rushing\n", "ArtForz -- public domain half-a-node\n", "Intel Corporation", "The Zcash developers", diff --git a/contrib/devtools/github-merge.py b/contrib/devtools/github-merge.py index a57ecf9818..78ac671bfe 100755 --- a/contrib/devtools/github-merge.py +++ b/contrib/devtools/github-merge.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2016-2017 Bitcoin Core Developers +# Copyright (c) 2016-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -32,11 +32,15 @@ BASH = os.getenv('BASH','bash') # OS specific configuration for terminal attributes ATTR_RESET = '' ATTR_PR = '' -COMMIT_FORMAT = '%h %s (%an)%d' +ATTR_NAME = '' +ATTR_WARN = '' +COMMIT_FORMAT = '%H %s (%an)%d' if os.name == 'posix': # if posix, assume we can use basic terminal escapes ATTR_RESET = '\033[0m' ATTR_PR = '\033[1;36m' - COMMIT_FORMAT = '%C(bold blue)%h%Creset %s %C(cyan)(%an)%Creset%C(green)%d%Creset' + ATTR_NAME = '\033[0;36m' + ATTR_WARN = '\033[1;31m' + COMMIT_FORMAT = '%C(bold blue)%H%Creset %s %C(cyan)(%an)%Creset%C(green)%d%Creset' def git_config_get(option, default=None): ''' @@ -164,18 +168,36 @@ def tree_sha512sum(commit='HEAD'): return overall.hexdigest() def get_acks_from_comments(head_commit, comments): - assert len(head_commit) == 6 - ack_str ='\n\nACKs for commit {}:\n'.format(head_commit) + # Look for abbreviated commit id, because not everyone wants to type/paste + # the whole thing and the chance of collisions within a PR is small enough + head_abbrev = head_commit[0:6] + acks = [] for c in comments: - review = [l for l in c['body'].split('\r\n') if 'ACK' in l and head_commit in l] + review = [l for l in c['body'].split('\r\n') if 'ACK' in l and head_abbrev in l] if review: - ack_str += ' {}:\n'.format(c['user']['login']) - ack_str += ' {}\n'.format(review[0]) + acks.append((c['user']['login'], review[0])) + return acks + +def make_acks_message(head_commit, acks): + if acks: + ack_str ='\n\nACKs for top commit:\n'.format(head_commit) + for name, msg in acks: + ack_str += ' {}:\n'.format(name) + ack_str += ' {}\n'.format(msg) + else: + ack_str ='\n\nTop commit has no ACKs.\n' return ack_str -def print_merge_details(pull, title, branch, base_branch, head_branch): +def print_merge_details(pull, title, branch, base_branch, head_branch, acks): print('%s#%s%s %s %sinto %s%s' % (ATTR_RESET+ATTR_PR,pull,ATTR_RESET,title,ATTR_RESET+ATTR_PR,branch,ATTR_RESET)) subprocess.check_call([GIT,'log','--graph','--topo-order','--pretty=format:'+COMMIT_FORMAT,base_branch+'..'+head_branch]) + if acks is not None: + if acks: + print('{}ACKs:{}'.format(ATTR_PR, ATTR_RESET)) + for (name, message) in acks: + print('* {} {}({}){}'.format(message, ATTR_NAME, name, ATTR_RESET)) + else: + print('{}Top commit has no ACKs!{}'.format(ATTR_WARN, ATTR_RESET)) def parse_arguments(): epilog = ''' @@ -225,9 +247,6 @@ def main(): info = retrieve_pr_info(repo,pull,ghtoken) if info is None: sys.exit(1) - comments = retrieve_pr_comments(repo,pull,ghtoken) + retrieve_pr_reviews(repo,pull,ghtoken) - if comments is None: - sys.exit(1) title = info['title'].strip() body = info['body'].strip() # precedence order for destination branch argument: @@ -257,6 +276,8 @@ def main(): sys.exit(3) try: subprocess.check_call([GIT,'log','-q','-1','refs/heads/'+head_branch], stdout=devnull, stderr=stdout) + head_commit = subprocess.check_output([GIT,'log','-1','--pretty=format:%H',head_branch]).decode('utf-8') + assert len(head_commit) == 40 except subprocess.CalledProcessError: print("ERROR: Cannot find head of pull request #%s on %s." % (pull,host_repo), file=stderr) sys.exit(3) @@ -279,11 +300,10 @@ def main(): else: firstline = 'Merge #%s' % (pull,) message = firstline + '\n\n' - message += subprocess.check_output([GIT,'log','--no-merges','--topo-order','--pretty=format:%h %s (%an)',base_branch+'..'+head_branch]).decode('utf-8') + message += subprocess.check_output([GIT,'log','--no-merges','--topo-order','--pretty=format:%H %s (%an)',base_branch+'..'+head_branch]).decode('utf-8') message += '\n\nPull request description:\n\n ' + body.replace('\n', '\n ') + '\n' - message += get_acks_from_comments(head_commit=subprocess.check_output([GIT,'log','-1','--pretty=format:%H',head_branch]).decode('utf-8')[:6], comments=comments) try: - subprocess.check_call([GIT,'merge','-q','--commit','--no-edit','--no-ff','-m',message.encode('utf-8'),head_branch]) + subprocess.check_call([GIT,'merge','-q','--commit','--no-edit','--no-ff','--no-gpg-sign','-m',message.encode('utf-8'),head_branch]) except subprocess.CalledProcessError: print("ERROR: Cannot be merged cleanly.",file=stderr) subprocess.check_call([GIT,'merge','--abort']) @@ -299,20 +319,14 @@ def main(): if len(symlink_files) > 0: sys.exit(4) - # Put tree SHA512 into the message + # Compute SHA512 of git tree (to be able to detect changes before sign-off) try: first_sha512 = tree_sha512sum() - message += '\n\nTree-SHA512: ' + first_sha512 except subprocess.CalledProcessError: print("ERROR: Unable to compute tree hash") sys.exit(4) - try: - subprocess.check_call([GIT,'commit','--amend','-m',message.encode('utf-8')]) - except subprocess.CalledProcessError: - print("ERROR: Cannot update message.", file=stderr) - sys.exit(4) - print_merge_details(pull, title, branch, base_branch, head_branch) + print_merge_details(pull, title, branch, base_branch, head_branch, None) print() # Run test command if configured. @@ -345,8 +359,24 @@ def main(): print("ERROR: Tree hash changed unexpectedly",file=stderr) sys.exit(8) + # Retrieve PR comments and ACKs and add to commit message, store ACKs to print them with commit + # description + comments = retrieve_pr_comments(repo,pull,ghtoken) + retrieve_pr_reviews(repo,pull,ghtoken) + if comments is None: + print("ERROR: Could not fetch PR comments and reviews",file=stderr) + sys.exit(1) + acks = get_acks_from_comments(head_commit=head_commit, comments=comments) + message += make_acks_message(head_commit=head_commit, acks=acks) + # end message with SHA512 tree hash, then update message + message += '\n\nTree-SHA512: ' + first_sha512 + try: + subprocess.check_call([GIT,'commit','--amend','--no-gpg-sign','-m',message.encode('utf-8')]) + except subprocess.CalledProcessError: + print("ERROR: Cannot update message.", file=stderr) + sys.exit(4) + # Sign the merge commit. - print_merge_details(pull, title, branch, base_branch, head_branch) + print_merge_details(pull, title, branch, base_branch, head_branch, acks) while True: reply = ask_prompt("Type 's' to sign off on the above merge, or 'x' to reject and exit.").lower() if reply == 's': @@ -381,4 +411,3 @@ def main(): if __name__ == '__main__': main() - diff --git a/contrib/devtools/test_deterministic_coverage.sh b/contrib/devtools/test_deterministic_coverage.sh index 16d03e1fff..88ac850021 100755 --- a/contrib/devtools/test_deterministic_coverage.sh +++ b/contrib/devtools/test_deterministic_coverage.sh @@ -14,6 +14,7 @@ GCOV_EXECUTABLE="gcov" # Disable tests known to cause non-deterministic behaviour and document the source or point of non-determinism. NON_DETERMINISTIC_TESTS=( + "blockfilter_index_tests/blockfilter_index_initial_sync" # src/checkqueue.h: In CCheckQueue::Loop(): while (queue.empty()) { ... } "coinselector_tests/knapsack_solver_test" # coinselector_tests.cpp: if (equal_sets(setCoinsRet, setCoinsRet2)) "denialofservice_tests/DoS_mapOrphans" # denialofservice_tests.cpp: it = mapOrphanTransactions.lower_bound(InsecureRand256()); "fs_tests/fsbridge_fstream" # deterministic test failure? diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index 5845d8fd89..c50750ed44 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -50,8 +50,6 @@ script: | export QT_RCC_TEST=1 export QT_RCC_SOURCE_DATE_OVERRIDE=1 - export GZIP="-9n" - export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME"" export TZ="UTC" export BUILD_DIR=`pwd` mkdir -p ${WRAP_DIR} @@ -150,8 +148,8 @@ script: | # Correct tar file order mkdir -p temp pushd temp - tar xf ../$SOURCEDIST - find bitcoin-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST + tar -xf ../$SOURCEDIST + find bitcoin-* | sort | tar --mtime="$REFERENCE_DATETIME" --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST popd # Workaround for tarball not building with the bare tag version (prep) @@ -184,8 +182,8 @@ script: | find ${DISTNAME}/bin -type f -executable -print0 | xargs -0 -n1 -I{} ../contrib/devtools/split-debug.sh {} {} {}.dbg find ${DISTNAME}/lib -type f -print0 | xargs -0 -n1 -I{} ../contrib/devtools/split-debug.sh {} {} {}.dbg cp ../doc/README.md ${DISTNAME}/ - find ${DISTNAME} -not -name "*.dbg" | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz - find ${DISTNAME} -name "*.dbg" | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}-debug.tar.gz + find ${DISTNAME} -not -name "*.dbg" | sort | tar --mtime="$REFERENCE_DATETIME" --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz + find ${DISTNAME} -name "*.dbg" | sort | tar --mtime="$REFERENCE_DATETIME" --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}-debug.tar.gz cd ../../ rm -rf distsrc-${i} done diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index 24292d089a..8c51ce7159 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -44,8 +44,6 @@ script: | export QT_RCC_TEST=1 export QT_RCC_SOURCE_DATE_OVERRIDE=1 - export GZIP="-9n" - export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME"" export TZ="UTC" export BUILD_DIR=`pwd` mkdir -p ${WRAP_DIR} @@ -114,8 +112,8 @@ script: | # Correct tar file order mkdir -p temp pushd temp - tar xf ../$SOURCEDIST - find bitcoin-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST + tar -xf ../$SOURCEDIST + find bitcoin-* | sort | tar --mtime="$REFERENCE_DATETIME" --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST popd # Workaround for tarball not building with the bare tag version (prep) @@ -152,7 +150,7 @@ script: | cp ${BASEPREFIX}/${i}/native/bin/${i}-pagestuff unsigned-app-${i}/pagestuff mv dist unsigned-app-${i} pushd unsigned-app-${i} - find . | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-osx-unsigned.tar.gz + find . | sort | tar --mtime="$REFERENCE_DATETIME" --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-osx-unsigned.tar.gz popd make deploy @@ -162,7 +160,7 @@ script: | find . -name "lib*.la" -delete find . -name "lib*.a" -delete rm -rf ${DISTNAME}/lib/pkgconfig - find ${DISTNAME} | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz + find ${DISTNAME} | sort | tar --mtime="$REFERENCE_DATETIME" --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz cd ../../ done mkdir -p $OUTDIR/src diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index c055109715..f227c6ad92 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -40,8 +40,6 @@ script: | export QT_RCC_TEST=1 export QT_RCC_SOURCE_DATE_OVERRIDE=1 - export GZIP="-9n" - export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME"" export TZ="UTC" export BUILD_DIR=`pwd` mkdir -p ${WRAP_DIR} @@ -130,8 +128,8 @@ script: | # Correct tar file order mkdir -p temp pushd temp - tar xf ../$SOURCEDIST - find bitcoin-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST + tar -xf ../$SOURCEDIST + find bitcoin-* | sort | tar --mtime="$REFERENCE_DATETIME" --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST mkdir -p $OUTDIR/src cp ../$SOURCEDIST $OUTDIR/src popd @@ -177,6 +175,6 @@ script: | cd $BUILD_DIR/windeploy mkdir unsigned cp $OUTDIR/bitcoin-*setup-unsigned.exe unsigned/ - find . | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-win-unsigned.tar.gz + find . | sort | tar --mtime="$REFERENCE_DATETIME" --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-win-unsigned.tar.gz mv ${OUTDIR}/${DISTNAME}-x86_64-*-debug.zip ${OUTDIR}/${DISTNAME}-win64-debug.zip mv ${OUTDIR}/${DISTNAME}-x86_64-*.zip ${OUTDIR}/${DISTNAME}-win64.zip diff --git a/contrib/verify-commits/trusted-keys b/contrib/verify-commits/trusted-keys index a10da9d822..27fede6277 100644 --- a/contrib/verify-commits/trusted-keys +++ b/contrib/verify-commits/trusted-keys @@ -3,3 +3,4 @@ 32EE5C4C3FA15CCADB46ABE529D4BCB6416F53EC B8B3F1C0E58C15DB6A81D30C3648A882F4316B9B CA03882CB1FC067B5D3ACFE4D300116E1C875A3D +E777299FC265DD04793070EB944D35F9AC3DB76A diff --git a/depends/packages.md b/depends/packages.md index 7d2bd4670d..2c592885b6 100644 --- a/depends/packages.md +++ b/depends/packages.md @@ -5,6 +5,10 @@ The package "mylib" will be used here as an example General tips: - mylib_foo is written as $(package)_foo in order to make recipes more similar. +- Secondary dependency packages relative to the bitcoin binaries/libraries (i.e. + those not in `ALLOWED_LIBRARIES` in `contrib/devtools/symbol-check.py`) don't + need to be shared and should be built statically whenever possible. See + [below](#secondary-dependencies) for more details. ## Identifiers Each package is required to define at least these variables: @@ -146,3 +150,34 @@ $($(package)_config_opts) will be appended. Most autotools projects can be properly staged using: $(MAKE) DESTDIR=$($(package)_staging_dir) install + +## Build outputs: + +In general, the output of a depends package should not contain any libtool +archives. Instead, the package should output `.pc` (`pkg-config`) files where +possible. + +From the [Gentoo Wiki entry](https://wiki.gentoo.org/wiki/Project:Quality_Assurance/Handling_Libtool_Archives): + +> Libtool pulls in all direct and indirect dependencies into the .la files it +> creates. This leads to massive overlinking, which is toxic to the Gentoo +> ecosystem, as it leads to a massive number of unnecessary rebuilds. + +## Secondary dependencies: + +Secondary dependency packages relative to the bitcoin binaries/libraries (i.e. +those not in `ALLOWED_LIBRARIES` in `contrib/devtools/symbol-check.py`) don't +need to be shared and should be built statically whenever possible. This +improves general build reliability as illustrated by the following example: + +When linking an executable against a shared library `libprimary` that has its +own shared dependency `libsecondary`, we may need to specify the path to +`libsecondary` on the link command using the `-rpath/-rpath-link` options, it is +not sufficient to just say `libprimary`. + +For us, it's much easier to just link a static `libsecondary` into a shared +`libprimary`. Especially because in our case, we are linking against a dummy +`libprimary` anyway that we'll throw away. We don't care if the end-user has a +static or dynamic `libseconday`, that's not our concern. With a static +`libseconday`, when we need to link `libprimary` into our executable, there's no +dependency chain to worry about as `libprimary` has all the symbols. diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk index 61806c7509..5df49b2af8 100644 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -1,8 +1,8 @@ package=boost -$(package)_version=1_64_0 -$(package)_download_path=https://dl.bintray.com/boostorg/release/1.64.0/source/ +$(package)_version=1_70_0 +$(package)_download_path=https://dl.bintray.com/boostorg/release/1.70.0/source/ $(package)_file_name=$(package)_$($(package)_version).tar.bz2 -$(package)_sha256_hash=7bcc5caace97baa948931d712ea5f37038dbb1c5d89b43ad4def4ed7cb683332 +$(package)_sha256_hash=430ae8354789de4fd19ee52f3b1f739e1fba576f0aded0897c3c2bc00fb38778 define $(package)_set_vars $(package)_config_opts_release=variant=release diff --git a/depends/packages/dbus.mk b/depends/packages/dbus.mk index bbe0375409..ad10b0fdd7 100644 --- a/depends/packages/dbus.mk +++ b/depends/packages/dbus.mk @@ -6,7 +6,7 @@ $(package)_sha256_hash=6049ddd5f3f3e2618f615f1faeda0a115104423a7996b7aa73e2f36e3 $(package)_dependencies=expat define $(package)_set_vars - $(package)_config_opts=--disable-tests --disable-doxygen-docs --disable-xml-docs --disable-static --without-x + $(package)_config_opts=--disable-tests --disable-doxygen-docs --disable-xml-docs --disable-shared --without-x endef define $(package)_config_cmds @@ -21,3 +21,7 @@ define $(package)_stage_cmds $(MAKE) -C dbus DESTDIR=$($(package)_staging_dir) install-libLTLIBRARIES install-dbusincludeHEADERS install-nodist_dbusarchincludeHEADERS && \ $(MAKE) DESTDIR=$($(package)_staging_dir) install-pkgconfigDATA endef + +define $(package)_postprocess_cmds + rm lib/*.la +endef diff --git a/depends/packages/expat.mk b/depends/packages/expat.mk index 8d06882cdb..b811f84a38 100644 --- a/depends/packages/expat.mk +++ b/depends/packages/expat.mk @@ -5,7 +5,8 @@ $(package)_file_name=$(package)-$($(package)_version).tar.bz2 $(package)_sha256_hash=17b43c2716d521369f82fc2dc70f359860e90fa440bea65b3b85f0b246ea81f2 define $(package)_set_vars -$(package)_config_opts=--disable-static --without-docbook + $(package)_config_opts=--disable-shared --without-docbook + $(package)_config_opts_linux=--with-pic endef define $(package)_config_cmds @@ -19,3 +20,7 @@ endef define $(package)_stage_cmds $(MAKE) DESTDIR=$($(package)_staging_dir) install endef + +define $(package)_postprocess_cmds + rm lib/*.la +endef diff --git a/depends/packages/fontconfig.mk b/depends/packages/fontconfig.mk index d0996b4534..293631739d 100644 --- a/depends/packages/fontconfig.mk +++ b/depends/packages/fontconfig.mk @@ -26,3 +26,7 @@ endef define $(package)_stage_cmds $(MAKE) DESTDIR=$($(package)_staging_dir) install endef + +define $(package)_postprocess_cmds + rm lib/*.la +endef diff --git a/depends/packages/freetype.mk b/depends/packages/freetype.mk index a98e82ed16..f24fc69d81 100644 --- a/depends/packages/freetype.mk +++ b/depends/packages/freetype.mk @@ -20,3 +20,7 @@ endef define $(package)_stage_cmds $(MAKE) DESTDIR=$($(package)_staging_dir) install endef + +define $(package)_postprocess_cmds + rm lib/*.la +endef diff --git a/depends/packages/libX11.mk b/depends/packages/libX11.mk index a013da5192..f46bd9219e 100644 --- a/depends/packages/libX11.mk +++ b/depends/packages/libX11.mk @@ -6,8 +6,9 @@ $(package)_sha256_hash=2aa027e837231d2eeea90f3a4afe19948a6eb4c8b2bec0241eba7dbc8 $(package)_dependencies=libxcb xtrans xextproto xproto define $(package)_set_vars -$(package)_config_opts=--disable-xkb --disable-static -$(package)_config_opts_linux=--with-pic + # See libXext for --disable-malloc0returnsnull rationale. + $(package)_config_opts=--disable-xkb --disable-static --disable-malloc0returnsnull + $(package)_config_opts_linux=--with-pic endef define $(package)_preprocess_cmds @@ -25,3 +26,7 @@ endef define $(package)_stage_cmds $(MAKE) DESTDIR=$($(package)_staging_dir) install endef + +define $(package)_postprocess_cmds + rm lib/*.la +endef diff --git a/depends/packages/libXau.mk b/depends/packages/libXau.mk index ce42140689..0e4a60ad25 100644 --- a/depends/packages/libXau.mk +++ b/depends/packages/libXau.mk @@ -25,3 +25,7 @@ endef define $(package)_stage_cmds $(MAKE) DESTDIR=$($(package)_staging_dir) install endef + +define $(package)_postprocess_cmds + rm lib/*.la +endef diff --git a/depends/packages/libXext.mk b/depends/packages/libXext.mk index 458b967784..77f32a340e 100644 --- a/depends/packages/libXext.mk +++ b/depends/packages/libXext.mk @@ -1,12 +1,35 @@ package=libXext -$(package)_version=1.3.2 +$(package)_version=1.3.3 $(package)_download_path=https://xorg.freedesktop.org/releases/individual/lib/ $(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=f829075bc646cdc085fa25d98d5885d83b1759ceb355933127c257e8e50432e0 +$(package)_sha256_hash=b518d4d332231f313371fdefac59e3776f4f0823bcb23cf7c7305bfb57b16e35 $(package)_dependencies=xproto xextproto libX11 libXau define $(package)_set_vars - $(package)_config_opts=--disable-static + # A number of steps in the autoconfig process implicitly assume that the build + # system and the host system are the same. For example, library components + # want to build and run test programs to determine the behavior of certain + # host system elements. This is clearly impossible when crosscompiling. To + # work around these issues, the --enable-malloc0returnsnull (or + # --disable-malloc0returnsnull, depending on the host system) must be passed + # to configure. + # -- https://www.x.org/wiki/CrossCompilingXorg/ + # + # Concretely, between the releases of libXext 1.3.2 and 1.3.3, + # XORG_CHECK_MALLOC_ZERO from xorg-macros was changed to use the autoconf + # cache, expecting cross-compilation environments to seed this cache as there + # is no single correct value when cross compiling (think uclibc, musl, etc.). + # You can see the actual change in commit 72fdc868b56fe2b7bdc9a69872651baeca72 + # in the freedesktop/xorg-macros repo. + # + # As a result of this change, if we don't seed the cache and we don't use + # either --{en,dis}able-malloc0returnsnull, the AC_RUN_IFELSE block has no + # optional action-if-cross-compiling argument and configure prints an error + # message and exits as documented in the autoconf manual. Prior to this + # commit, the AC_RUN_IFELSE block had an action-if-cross-compiling argument + # which set the more pessimistic default value MALLOC_ZERO_RETURNS_NULL=yes. + # This is why the flag was not required prior to libXext 1.3.3. + $(package)_config_opts=--disable-static --disable-malloc0returnsnull endef define $(package)_preprocess_cmds @@ -24,3 +47,7 @@ endef define $(package)_stage_cmds $(MAKE) DESTDIR=$($(package)_staging_dir) install endef + +define $(package)_postprocess_cmds + rm lib/*.la +endef diff --git a/depends/packages/libevent.mk b/depends/packages/libevent.mk index 5f622f8e6e..a3ade899b7 100644 --- a/depends/packages/libevent.mk +++ b/depends/packages/libevent.mk @@ -27,4 +27,5 @@ define $(package)_stage_cmds endef define $(package)_postprocess_cmds + rm lib/*.la endef diff --git a/depends/packages/libxcb.mk b/depends/packages/libxcb.mk index 3ddd5a7dd9..9402951826 100644 --- a/depends/packages/libxcb.mk +++ b/depends/packages/libxcb.mk @@ -32,5 +32,5 @@ define $(package)_stage_cmds endef define $(package)_postprocess_cmds - rm -rf share/man share/doc + rm -rf share/man share/doc lib/*.la endef diff --git a/depends/packages/protobuf.mk b/depends/packages/protobuf.mk index d201d1183f..52975b14ec 100644 --- a/depends/packages/protobuf.mk +++ b/depends/packages/protobuf.mk @@ -30,5 +30,5 @@ define $(package)_stage_cmds endef define $(package)_postprocess_cmds - rm lib/libprotoc.a + rm lib/libprotoc.a lib/*.la endef diff --git a/depends/packages/qrencode.mk b/depends/packages/qrencode.mk index 313e4adf2a..56681b52a1 100644 --- a/depends/packages/qrencode.mk +++ b/depends/packages/qrencode.mk @@ -24,3 +24,7 @@ endef define $(package)_stage_cmds $(MAKE) DESTDIR=$($(package)_staging_dir) install endef + +define $(package)_postprocess_cmds + rm lib/*.la +endef diff --git a/depends/packages/rapidcheck.mk b/depends/packages/rapidcheck.mk index a35e091c80..fa4fb3c782 100644 --- a/depends/packages/rapidcheck.mk +++ b/depends/packages/rapidcheck.mk @@ -8,6 +8,10 @@ define $(package)_config_cmds cmake -DCMAKE_INSTALL_PREFIX=$($(package)_staging_dir)$(host_prefix) -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=true -DRC_INSTALL_ALL_EXTRAS=ON endef +define $(package)_preprocess_cmds + sed -i.old 's/ -Wall//' CMakeLists.txt +endef + define $(package)_build_cmds $(MAKE) rapidcheck endef diff --git a/depends/packages/xtrans.mk b/depends/packages/xtrans.mk index 67d2d976c4..6201d1d270 100644 --- a/depends/packages/xtrans.mk +++ b/depends/packages/xtrans.mk @@ -6,7 +6,7 @@ $(package)_sha256_hash=054d4ee3efd52508c753e9f7bc655ef185a29bd2850dd9e2fc2ccc335 $(package)_dependencies= define $(package)_set_vars -$(package)_config_opts_linux=--with-pic --disable-static + $(package)_config_opts_linux=--disable-docs --without-xmlto --without-fop --without-xsltproc endef define $(package)_preprocess_cmds diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index dfbc50580c..e69a37e093 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -31,5 +31,5 @@ endef define $(package)_postprocess_cmds sed -i.old "s/ -lstdc++//" lib/pkgconfig/libzmq.pc && \ - rm -rf bin share + rm -rf bin share lib/*.la endef diff --git a/doc/build-osx.md b/doc/build-osx.md index d28a3d97aa..65cfce6b15 100644 --- a/doc/build-osx.md +++ b/doc/build-osx.md @@ -1,33 +1,37 @@ -macOS Build Instructions and Notes -==================================== +# macOS Build Instructions and Notes + The commands in this guide should be executed in a Terminal application. -The built-in one is located in `/Applications/Utilities/Terminal.app`. +The built-in one is located in +``` +/Applications/Utilities/Terminal.app +``` -Preparation ------------ +## Preparation Install the macOS command line tools: -`xcode-select --install` +```shell +xcode-select --install +``` When the popup appears, click `Install`. Then install [Homebrew](https://brew.sh). -Dependencies ----------------------- - - brew install automake berkeley-db4 libtool boost miniupnpc openssl pkg-config protobuf python qt libevent qrencode +## Dependencies +```shell +brew install automake berkeley-db4 libtool boost miniupnpc openssl pkg-config protobuf python qt libevent qrencode +``` See [dependencies.md](dependencies.md) for a complete overview. If you want to build the disk image with `make deploy` (.dmg / optional), you need RSVG: +```shell +brew install librsvg +``` - brew install librsvg - -Berkeley DB ------------ +## Berkeley DB It is recommended to use Berkeley DB 4.8. If you have to build it yourself, -you can use [the installation script included in contrib/](/contrib/install_db4.sh) +you can use [this](/contrib/install_db4.sh) script to install it like so: ```shell @@ -38,172 +42,167 @@ from the root of the repository. **Note**: You only need Berkeley DB if the wallet is enabled (see [*Disable-wallet mode*](/doc/build-osx.md#disable-wallet-mode)). -Build Bitcoin Core ------------------------- +## Build Bitcoin Core 1. Clone the Bitcoin Core source code: - - git clone https://github.com/bitcoin/bitcoin - cd bitcoin + ```shell + git clone https://github.com/bitcoin/bitcoin + cd bitcoin + ``` 2. Build Bitcoin Core: Configure and build the headless Bitcoin Core binaries as well as the GUI (if Qt is found). You can disable the GUI build by passing `--without-gui` to configure. - - ./autogen.sh - ./configure - make + ```shell + ./autogen.sh + ./configure + make + ``` 3. It is recommended to build and run the unit tests: - - make check - -4. You can also create a .dmg that contains the .app bundle (optional): - - 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 + ```shell + make check + ``` + +4. You can also create a `.dmg` that contains the `.app` bundle (optional): + ```shell + 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: +```shell +./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 -------- - +## Running Bitcoin Core is now available at `./src/bitcoind` Before running, you may create an empty configuration file: +```shell +mkdir -p "/Users/${USER}/Library/Application Support/Bitcoin" - mkdir -p "/Users/${USER}/Library/Application Support/Bitcoin" - - touch "/Users/${USER}/Library/Application Support/Bitcoin/bitcoin.conf" +touch "/Users/${USER}/Library/Application Support/Bitcoin/bitcoin.conf" - chmod 600 "/Users/${USER}/Library/Application Support/Bitcoin/bitcoin.conf" +chmod 600 "/Users/${USER}/Library/Application Support/Bitcoin/bitcoin.conf" +``` -The first time you run bitcoind, it will start downloading the blockchain. This process could take many hours, or even days on slower than average systems. +The first time you run bitcoind, it will start downloading the blockchain. This process could +take many hours, or even days on slower than average systems. You can monitor the download process by looking at the debug.log file: +```shell +tail -f $HOME/Library/Application\ Support/Bitcoin/debug.log +``` - tail -f $HOME/Library/Application\ Support/Bitcoin/debug.log - -Other commands: -------- - - ./src/bitcoind -daemon # Starts the bitcoin daemon. - ./src/bitcoin-cli --help # Outputs a list of command-line options. - ./src/bitcoin-cli help # Outputs a list of RPC commands when the daemon is running. - -Notes ------ - -* Tested on OS X 10.10 Yosemite through macOS 10.13 High Sierra on 64-bit Intel processors only. - -* Building with downloaded Qt binaries is not officially supported. See the notes in [#7714](https://github.com/bitcoin/bitcoin/issues/7714) +## Other commands: +```shell +./src/bitcoind -daemon # Starts the bitcoin daemon. +./src/bitcoin-cli --help # Outputs a list of command-line options. +./src/bitcoin-cli help # Outputs a list of RPC commands when the daemon is running. +``` -Deterministic macOS DMG Notes ------------------------------ +## Notes +* Tested on OS X 10.10 Yosemite through macOS 10.14 Mojave on 64-bit Intel +processors only. +* Building with downloaded Qt binaries is not officially supported. See the notes in [#7714](https://github.com/bitcoin/bitcoin/issues/7714). -Working macOS DMGs are created in Linux by combining a recent clang, -the Apple binutils (ld, ar, etc) and DMG authoring tools. +## Deterministic macOS DMG Notes +Working macOS DMGs are created in Linux by combining a recent `clang`, the Apple +`binutils` (`ld`, `ar`, etc) and DMG authoring tools. -Apple uses clang extensively for development and has upstreamed the necessary -functionality so that a vanilla clang can take advantage. It supports the use -of -F, -target, -mmacosx-version-min, and --sysroot, which are all necessary -when building for macOS. +Apple uses `clang` extensively for development and has upstreamed the necessary +functionality so that a vanilla clang can take advantage. It supports the use of `-F`, +`-target`, `-mmacosx-version-min`, and `--sysroot`, which are all necessary when +building for macOS. -Apple's version of binutils (called cctools) contains lots of functionality -missing in the FSF's binutils. In addition to extra linker options for -frameworks and sysroots, several other tools are needed as well such as -install_name_tool, lipo, and nmedit. These do not build under linux, so they -have been patched to do so. The work here was used as a starting point: -[mingwandroid/toolchain4](https://github.com/mingwandroid/toolchain4). +Apple's version of `binutils` (called `cctools`) contains lots of functionality missing in the +FSF's `binutils`. In addition to extra linker options for frameworks and sysroots, several +other tools are needed as well such as `install_name_tool`, `lipo`, and `nmedit`. These +do not build under Linux, so they have been patched to do so. The work here was used as +a starting point: [mingwandroid/toolchain4](https://github.com/mingwandroid/toolchain4). -In order to build a working toolchain, the following source packages are needed -from Apple: cctools, dyld, and ld64. +In order to build a working toolchain, the following source packages are needed from +Apple: `cctools`, `dyld`, and `ld64`. -These tools inject timestamps by default, which produce non-deterministic -binaries. The ZERO_AR_DATE environment variable is used to disable that. +These tools inject timestamps by default, which produce non-deterministic binaries. The +`ZERO_AR_DATE` environment variable is used to disable that. -This version of cctools has been patched to use the current version of clang's -headers and its libLTO.so rather than those from llvmgcc, as it was -originally done in toolchain4. +This version of `cctools` has been patched to use the current version of `clang`'s headers +and its `libLTO.so` rather than those from `llvmgcc`, as it was originally done in `toolchain4`. -To complicate things further, all builds must target an Apple SDK. These SDKs -are free to download, but not redistributable. -To obtain it, register for a developer account, then download the [Xcode 7.3.1 dmg](https://developer.apple.com/devcenter/download.action?path=/Developer_Tools/Xcode_7.3.1/Xcode_7.3.1.dmg). +To complicate things further, all builds must target an Apple SDK. These SDKs are free to +download, but not redistributable. To obtain it, register for an Apple Developer Account, +then download the [Xcode 7.3.1 dmg](https://developer.apple.com/devcenter/download.action?path=/Developer_Tools/Xcode_7.3.1/Xcode_7.3.1.dmg). -This file is several gigabytes in size, but only a single directory inside is -needed: +This file is several gigabytes in size, but only a single directory inside is needed: ``` Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk ``` -Unfortunately, the usual linux tools (7zip, hpmount, loopback mount) are incapable of opening this file. -To create a tarball suitable for Gitian input, there are two options: +Unfortunately, the usual Linux tools (7zip, hpmount, loopback mount) are incapable of +opening this file. To create a tarball suitable for Gitian input, there are two options: -Using macOS, you can mount the dmg, and then create it with: -``` - $ hdiutil attach Xcode_7.3.1.dmg - $ tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.11.sdk.tar.gz MacOSX10.11.sdk +Using macOS, you can mount the DMG, and then create it with: +```shell +hdiutil attach Xcode_7.3.1.dmg +tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.11.sdk.tar.gz MacOSX10.11.sdk ``` -Alternatively, you can use 7zip and SleuthKit to extract the files one by one. -The script contrib/macdeploy/extract-osx-sdk.sh automates this. First ensure -the dmg file is in the current directory, and then run the script. You may wish -to delete the intermediate 5.hfs file and MacOSX10.11.sdk (the directory) when -you've confirmed the extraction succeeded. +Alternatively, you can use 7zip and SleuthKit to extract the files one by one. The script +[`extract-osx-sdk.sh`](./../contrib/macdeploy/extract-osx-sdk.sh) automates this. First +ensure the DMG file is in the current directory, and then run the script. You may wish to +delete the `intermediate 5.hfs` file and `MacOSX10.11.sdk` (the directory) when you've +confirmed the extraction succeeded. -```bash +```shell apt-get install p7zip-full sleuthkit contrib/macdeploy/extract-osx-sdk.sh rm -rf 5.hfs MacOSX10.11.sdk ``` -The Gitian descriptors build 2 sets of files: Linux tools, then Apple binaries -which are created using these tools. The build process has been designed to -avoid including the SDK's files in Gitian's outputs. All interim tarballs are -fully deterministic and may be freely redistributed. +The Gitian descriptors build 2 sets of files: Linux tools, then Apple binaries which are +created using these tools. The build process has been designed to avoid including the +SDK's files in Gitian's outputs. All interim tarballs are fully deterministic and may be freely +redistributed. -genisoimage is used to create the initial DMG. It is not deterministic as-is, -so it has been patched. A system genisoimage will work fine, but it will not -be deterministic because the file-order will change between invocations. -The patch can be seen here: [theuni/osx-cross-depends](https://raw.githubusercontent.com/theuni/osx-cross-depends/master/patches/cdrtools/genisoimage.diff). -No effort was made to fix this cleanly, so it likely leaks memory badly. But -it's only used for a single invocation, so that's no real concern. +`genisoimage` is used to create the initial DMG. It is not deterministic as-is, so it has been +patched. A system `genisoimage` will work fine, but it will not be deterministic because +the file-order will change between invocations. The patch can be seen here: [theuni/osx-cross-depends](https://raw.githubusercontent.com/theuni/osx-cross-depends/master/patches/cdrtools/genisoimage.diff). +No effort was made to fix this cleanly, so it likely leaks memory badly. But it's only used for +a single invocation, so that's no real concern. -genisoimage cannot compress DMGs, so afterwards, the 'dmg' tool from the -libdmg-hfsplus project is used to compress it. There are several bugs in this -tool and its maintainer has seemingly abandoned the project. It has been forked -and is available (with fixes) here: [theuni/libdmg-hfsplus](https://github.com/theuni/libdmg-hfsplus). +`genisoimage` cannot compress DMGs, so afterwards, the DMG tool from the +`libdmg-hfsplus` project is used to compress it. There are several bugs in this tool and its +maintainer has seemingly abandoned the project. It has been forked and is available +(with fixes) here: [theuni/libdmg-hfsplus](https://github.com/theuni/libdmg-hfsplus). -The 'dmg' tool has the ability to create DMGs from scratch as well, but this -functionality is broken. Only the compression feature is currently used. -Ideally, the creation could be fixed and genisoimage would no longer be necessary. +The DMG tool has the ability to create DMGs from scratch as well, but this functionality is +broken. Only the compression feature is currently used. Ideally, the creation could be fixed +and `genisoimage` would no longer be necessary. Background images and other features can be added to DMG files by inserting a -.DS_Store before creation. This is generated by the script -contrib/macdeploy/custom_dsstore.py. - -As of OS X 10.9 Mavericks, using an Apple-blessed key to sign binaries is a -requirement in order to satisfy the new Gatekeeper requirements. Because this -private key cannot be shared, we'll have to be a bit creative in order for the -build process to remain somewhat deterministic. Here's how it works: - -- Builders use Gitian to create an unsigned release. This outputs an unsigned - dmg which users may choose to bless and run. It also outputs an unsigned app - structure in the form of a tarball, which also contains all of the tools - that have been previously (deterministically) built in order to create a - final dmg. -- The Apple keyholder uses this unsigned app to create a detached signature, - using the script that is also included there. Detached signatures are available from this [repository](https://github.com/bitcoin-core/bitcoin-detached-sigs). -- Builders feed the unsigned app + detached signature back into Gitian. It - uses the pre-built tools to recombine the pieces into a deterministic dmg. +`.DS_Store` before creation. This is generated by the script +`contrib/macdeploy/custom_dsstore.py`. + +As of OS X 10.9 Mavericks, using an Apple-blessed key to sign binaries is a requirement in +order to satisfy the new Gatekeeper requirements. Because this private key cannot be +shared, we'll have to be a bit creative in order for the build process to remain somewhat +deterministic. Here's how it works: + +- Builders use Gitian to create an unsigned release. This outputs an unsigned DMG which + users may choose to bless and run. It also outputs an unsigned app structure in the form + of a tarball, which also contains all of the tools that have been previously (deterministically) + built in order to create a final DMG. +- The Apple keyholder uses this unsigned app to create a detached signature, using the + script that is also included there. Detached signatures are available from this [repository](https://github.com/bitcoin-core/bitcoin-detached-sigs). +- Builders feed the unsigned app + detached signature back into Gitian. It uses the + pre-built tools to recombine the pieces into a deterministic DMG. diff --git a/doc/dependencies.md b/doc/dependencies.md index 1b3df62867..4c0e8d2567 100644 --- a/doc/dependencies.md +++ b/doc/dependencies.md @@ -6,7 +6,7 @@ These are the dependencies currently used by Bitcoin Core. You can find instruct | Dependency | Version used | Minimum required | CVEs | Shared | [Bundled Qt library](https://doc.qt.io/qt-5/configure-options.html#third-party-libraries) | | --- | --- | --- | --- | --- | --- | | Berkeley DB | [4.8.30](https://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html) | 4.8.x | No | | | -| Boost | [1.64.0](https://www.boost.org/users/download/) | [1.47.0](https://github.com/bitcoin/bitcoin/pull/8920) | No | | | +| Boost | [1.70.0](https://www.boost.org/users/download/) | [1.47.0](https://github.com/bitcoin/bitcoin/pull/8920) | No | | | | Clang | | [3.3+](https://llvm.org/releases/download.html) (C++11 support) | | | | | D-Bus | [1.10.18](https://cgit.freedesktop.org/dbus/dbus/tree/NEWS?h=dbus-1.10) | | No | Yes | | | Expat | [2.2.6](https://libexpat.github.io/) | | No | Yes | | diff --git a/doc/developer-notes.md b/doc/developer-notes.md index 45e55b7c40..ecd720539e 100644 --- a/doc/developer-notes.md +++ b/doc/developer-notes.md @@ -34,7 +34,6 @@ Developer Notes - [Source code organization](#source-code-organization) - [GUI](#gui) - [Subtrees](#subtrees) - - [Git and GitHub tips](#git-and-github-tips) - [Scripted diffs](#scripted-diffs) - [Release notes](#release-notes) - [RPC interface guidelines](#rpc-interface-guidelines) @@ -280,7 +279,7 @@ thread](https://askubuntu.com/questions/50145/how-to-install-perf-monitoring-too for specific instructions. Certain kernel parameters may need to be set for perf to be able to inspect the -running process' stack. +running process's stack. ```sh $ sudo sysctl -w kernel.perf_event_paranoid=-1 diff --git a/doc/man/bitcoin-qt.1 b/doc/man/bitcoin-qt.1 index 052d420608..1e8443b1d3 100644 --- a/doc/man/bitcoin-qt.1 +++ b/doc/man/bitcoin-qt.1 @@ -488,9 +488,6 @@ Relay and mine data carrier transactions (default: 1) Maximum size of data in data carrier transactions we relay and mine (default: 83) .HP -\fB\-mempoolreplacement\fR -.IP -Enable transaction replacement in the memory pool (default: 1) .HP \fB\-minrelaytxfee=\fR<amt> .IP diff --git a/doc/man/bitcoind.1 b/doc/man/bitcoind.1 index 5e057d923f..2a79b6cb46 100644 --- a/doc/man/bitcoind.1 +++ b/doc/man/bitcoind.1 @@ -488,10 +488,6 @@ Relay and mine data carrier transactions (default: 1) Maximum size of data in data carrier transactions we relay and mine (default: 83) .HP -\fB\-mempoolreplacement\fR -.IP -Enable transaction replacement in the memory pool (default: 1) -.HP \fB\-minrelaytxfee=\fR<amt> .IP Fees (in BTC/kB) smaller than this are considered zero fee for relaying, diff --git a/doc/release-notes-0.18.1-16257.md b/doc/release-notes-0.18.1-16257.md new file mode 100644 index 0000000000..21867b7fb2 --- /dev/null +++ b/doc/release-notes-0.18.1-16257.md @@ -0,0 +1,6 @@ +Wallet changes +-------------- +When creating a transaction with a fee above `-maxtxfee` (default 0.1 BTC), +the RPC commands `walletcreatefundedpsbt` and `fundrawtransaction` will now fail +instead of rounding down the fee. Beware that the `feeRate` argument is specified +in BTC per kilobyte, not satoshi per byte. diff --git a/doc/release-notes-13756.md b/doc/release-notes-13756.md new file mode 100644 index 0000000000..a500aceb0f --- /dev/null +++ b/doc/release-notes-13756.md @@ -0,0 +1,41 @@ +Coin selection +-------------- + +### Reuse Avoidance + +A new wallet flag `avoid_reuse` has been added (default off). When enabled, +a wallet will distinguish between used and unused addresses, and default to not +use the former in coin selection. + +Rescanning the blockchain is required, to correctly mark previously +used destinations. + +Together with "avoid partial spends" (present as of Bitcoin v0.17), this +addresses a serious privacy issue where a malicious user can track spends by +peppering a previously paid to address with near-dust outputs, which would then +be inadvertently included in future payments. + +New RPCs +-------- + +- A new `setwalletflag` RPC sets/unsets flags for an existing wallet. + + +Updated RPCs +------------ + +Several RPCs have been updated to include an "avoid_reuse" flag, used to control +whether already used addresses should be left out or included in the operation. +These include: + +- createwallet +- getbalance +- getbalances +- sendtoaddress + +In addition, `sendtoaddress` has been changed to avoid partial spends when `avoid_reuse` +is enabled (if not already enabled via the `-avoidpartialspends` command line flag), +as it would otherwise risk using up the "wrong" UTXO for an address reuse case. + +The listunspent RPC has also been updated to now include a "reused" bool, for nodes +with "avoid_reuse" enabled. diff --git a/doc/release-notes.md b/doc/release-notes.md index 4a86469ccf..9efb6cbabb 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -90,7 +90,7 @@ Updated RPCs Note: some low-level RPC changes mainly useful for testing are described in the Low-level Changes section below. -* The `sendmany` RPC had an argument `minconf` that was not well specified and +- The `sendmany` RPC had an argument `minconf` that was not well specified and would lead to RPC errors even when the wallet's coin selection would succeed. The `sendtoaddress` RPC never had this check, so to normalize the behavior, `minconf` is now ignored in `sendmany`. If the coin selection does not @@ -106,11 +106,22 @@ Low-level changes Configuration ------------ -* An error is issued where previously a warning was issued when a setting in +- An error is issued where previously a warning was issued when a setting in the config file was specified in the default section, but not overridden for the selected network. This change takes only effect if the selected network is not mainnet. +Network +------- + +- When fetching a transaction announced by multiple peers, previous versions of + Bitcoin Core would sequentially attempt to download the transaction from each + announcing peer until the transaction is received, in the order that those + peers' announcements were received. In this release, the download logic has + changed to randomize the fetch order across peers and to prefer sending + download requests to outbound peers over inbound peers. This fixes an issue + where inbound peers can prevent a node from getting a transaction. + Wallet ------ diff --git a/doc/release-notes/release-notes-0.12.0.md b/doc/release-notes/release-notes-0.12.0.md index cf74a17975..bc0d5ea3b0 100644 --- a/doc/release-notes/release-notes-0.12.0.md +++ b/doc/release-notes/release-notes-0.12.0.md @@ -127,7 +127,7 @@ minimum relay feerate. The initial minimum relay feerate is set to Bitcoin Core 0.12 also introduces new default policy limits on the length and size of unconfirmed transaction chains that are allowed in the mempool (generally limiting the length of unconfirmed chains to 25 transactions, with a -total size of 101 KB). These limits can be overriden using command line +total size of 101 KB). These limits can be overridden using command line arguments; see the extended help (`--help -help-debug`) for more information. Opt-in Replace-by-fee transactions diff --git a/doc/release-process.md b/doc/release-process.md index 2e712bf58e..480b09ee11 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -323,6 +323,9 @@ bitcoin.org (see below for bitcoin.org update instructions). - bitcoincore.org blog post + - bitcoincore.org maintained versions update: + [table](https://github.com/bitcoin-core/bitcoincore.org/commits/master/_includes/posts/maintenance-table.md) + - bitcoincore.org RPC documentation update - Update packaging repo diff --git a/src/Makefile.am b/src/Makefile.am index ec3d81b76f..39e8d3d689 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -181,7 +181,6 @@ BITCOIN_CORE_H = \ rpc/util.h \ scheduler.h \ script/descriptor.h \ - script/ismine.h \ script/sigcache.h \ script/sign.h \ script/standard.h \ @@ -223,6 +222,7 @@ BITCOIN_CORE_H = \ wallet/db.h \ wallet/feebumper.h \ wallet/fees.h \ + wallet/ismine.h \ wallet/load.h \ wallet/psbtwallet.h \ wallet/rpcwallet.h \ @@ -328,6 +328,7 @@ libbitcoin_wallet_a_SOURCES = \ wallet/db.cpp \ wallet/feebumper.cpp \ wallet/fees.cpp \ + wallet/ismine.cpp \ wallet/load.cpp \ wallet/psbtwallet.cpp \ wallet/rpcdump.cpp \ @@ -458,7 +459,6 @@ libbitcoin_common_a_SOURCES = \ rpc/util.cpp \ scheduler.cpp \ script/descriptor.cpp \ - script/ismine.cpp \ script/sign.cpp \ script/standard.cpp \ versionbitsinfo.cpp \ diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 1144ca8a78..d3fe138133 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -97,6 +97,7 @@ BITCOIN_TESTS =\ test/bswap_tests.cpp \ test/checkqueue_tests.cpp \ test/coins_tests.cpp \ + test/compilerbug_tests.cpp \ test/compress_tests.cpp \ test/crypto_tests.cpp \ test/cuckoocache_tests.cpp \ @@ -166,7 +167,8 @@ BITCOIN_TESTS += \ wallet/test/wallet_tests.cpp \ wallet/test/wallet_crypto_tests.cpp \ wallet/test/coinselector_tests.cpp \ - wallet/test/init_tests.cpp + wallet/test/init_tests.cpp \ + wallet/test/ismine_tests.cpp BITCOIN_TEST_SUITE += \ wallet/test/wallet_test_fixture.cpp \ diff --git a/src/addrdb.cpp b/src/addrdb.cpp index c6083f5554..db936486b6 100644 --- a/src/addrdb.cpp +++ b/src/addrdb.cpp @@ -44,18 +44,30 @@ bool SerializeFileDB(const std::string& prefix, const fs::path& path, const Data fs::path pathTmp = GetDataDir() / tmpfn; FILE *file = fsbridge::fopen(pathTmp, "wb"); CAutoFile fileout(file, SER_DISK, CLIENT_VERSION); - if (fileout.IsNull()) + if (fileout.IsNull()) { + fileout.fclose(); + remove(pathTmp); return error("%s: Failed to open file %s", __func__, pathTmp.string()); + } // Serialize - if (!SerializeDB(fileout, data)) return false; - if (!FileCommit(fileout.Get())) + if (!SerializeDB(fileout, data)) { + fileout.fclose(); + remove(pathTmp); + return false; + } + if (!FileCommit(fileout.Get())) { + fileout.fclose(); + remove(pathTmp); return error("%s: Failed to flush file %s", __func__, pathTmp.string()); + } fileout.fclose(); // replace existing file, if any, with new file - if (!RenameOver(pathTmp, path)) + if (!RenameOver(pathTmp, path)) { + remove(pathTmp); return error("%s: Rename-into-place failed", __func__); + } return true; } diff --git a/src/addrman.cpp b/src/addrman.cpp index 8a5f78d1c5..32676f8fa5 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -7,7 +7,6 @@ #include <hash.h> #include <serialize.h> -#include <streams.h> int CAddrInfo::GetTriedBucket(const uint256& nKey) const { diff --git a/src/arith_uint256.cpp b/src/arith_uint256.cpp index aa66d13102..be145a0e63 100644 --- a/src/arith_uint256.cpp +++ b/src/arith_uint256.cpp @@ -6,7 +6,6 @@ #include <arith_uint256.h> #include <uint256.h> -#include <util/strencodings.h> #include <crypto/common.h> #include <stdio.h> diff --git a/src/bench/base58.cpp b/src/bench/base58.cpp index e7702ec461..0f4b52cf79 100644 --- a/src/bench/base58.cpp +++ b/src/bench/base58.cpp @@ -4,7 +4,6 @@ #include <bench/bench.h> -#include <validation.h> #include <base58.h> #include <array> diff --git a/src/bench/bech32.cpp b/src/bench/bech32.cpp index 3c4b453a23..80f13eeb3b 100644 --- a/src/bench/bech32.cpp +++ b/src/bench/bech32.cpp @@ -4,7 +4,6 @@ #include <bench/bench.h> -#include <validation.h> #include <bech32.h> #include <util/strencodings.h> diff --git a/src/bench/bench_bitcoin.cpp b/src/bench/bench_bitcoin.cpp index 3cf0bf9530..8eea96d930 100644 --- a/src/bench/bench_bitcoin.cpp +++ b/src/bench/bench_bitcoin.cpp @@ -4,8 +4,6 @@ #include <bench/bench.h> -#include <crypto/sha256.h> -#include <key.h> #include <util/strencodings.h> #include <util/system.h> @@ -38,7 +36,7 @@ int main(int argc, char** argv) SetupBenchArgs(); std::string error; if (!gArgs.ParseParameters(argc, argv, error)) { - fprintf(stderr, "Error parsing command line arguments: %s\n", error.c_str()); + tfm::format(std::cerr, "Error parsing command line arguments: %s\n", error.c_str()); return EXIT_FAILURE; } @@ -55,7 +53,7 @@ int main(int argc, char** argv) double scaling_factor; if (!ParseDouble(scaling_str, &scaling_factor)) { - fprintf(stderr, "Error parsing scaling factor as double: %s\n", scaling_str.c_str()); + tfm::format(std::cerr, "Error parsing scaling factor as double: %s\n", scaling_str.c_str()); return EXIT_FAILURE; } diff --git a/src/bench/chacha20.cpp b/src/bench/chacha20.cpp index 69d8c96ec0..030067aca5 100644 --- a/src/bench/chacha20.cpp +++ b/src/bench/chacha20.cpp @@ -5,7 +5,6 @@ #include <iostream> #include <bench/bench.h> -#include <hash.h> #include <crypto/chacha20.h> /* Number of bytes to process per iteration */ diff --git a/src/bench/checkqueue.cpp b/src/bench/checkqueue.cpp index 6ab542067a..000a0259bb 100644 --- a/src/bench/checkqueue.cpp +++ b/src/bench/checkqueue.cpp @@ -4,7 +4,6 @@ #include <bench/bench.h> #include <util/system.h> -#include <validation.h> #include <checkqueue.h> #include <prevector.h> #include <vector> diff --git a/src/bench/crypto_hash.cpp b/src/bench/crypto_hash.cpp index dc0b054420..fb2bab9dee 100644 --- a/src/bench/crypto_hash.cpp +++ b/src/bench/crypto_hash.cpp @@ -5,11 +5,9 @@ #include <iostream> #include <bench/bench.h> -#include <bloom.h> #include <hash.h> #include <random.h> #include <uint256.h> -#include <util/time.h> #include <crypto/ripemd160.h> #include <crypto/sha1.h> #include <crypto/sha256.h> diff --git a/src/bench/duplicate_inputs.cpp b/src/bench/duplicate_inputs.cpp index 80ff13612c..2440341287 100644 --- a/src/bench/duplicate_inputs.cpp +++ b/src/bench/duplicate_inputs.cpp @@ -7,13 +7,9 @@ #include <coins.h> #include <consensus/merkle.h> #include <consensus/validation.h> -#include <miner.h> -#include <policy/policy.h> #include <pow.h> -#include <test/util.h> #include <txmempool.h> #include <validation.h> -#include <validationinterface.h> #include <list> #include <vector> diff --git a/src/bench/examples.cpp b/src/bench/examples.cpp index e7ddd5a938..3595249559 100644 --- a/src/bench/examples.cpp +++ b/src/bench/examples.cpp @@ -3,7 +3,6 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <bench/bench.h> -#include <validation.h> #include <util/time.h> // Sanity test: this should loop ten times, and diff --git a/src/bench/rpc_mempool.cpp b/src/bench/rpc_mempool.cpp index 67d8a25564..b35a744055 100644 --- a/src/bench/rpc_mempool.cpp +++ b/src/bench/rpc_mempool.cpp @@ -3,7 +3,6 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <bench/bench.h> -#include <policy/policy.h> #include <rpc/blockchain.h> #include <txmempool.h> diff --git a/src/bench/verify_script.cpp b/src/bench/verify_script.cpp index 312b66e38a..4891c57b3a 100644 --- a/src/bench/verify_script.cpp +++ b/src/bench/verify_script.cpp @@ -8,7 +8,6 @@ #include <script/bitcoinconsensus.h> #endif #include <script/script.h> -#include <script/sign.h> #include <script/standard.h> #include <streams.h> diff --git a/src/bench/wallet_balance.cpp b/src/bench/wallet_balance.cpp index 46ca12826b..313b5a3ba0 100644 --- a/src/bench/wallet_balance.cpp +++ b/src/bench/wallet_balance.cpp @@ -4,7 +4,6 @@ #include <bench/bench.h> #include <interfaces/chain.h> -#include <key_io.h> #include <optional.h> #include <test/util.h> #include <validationinterface.h> diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 1009a771f8..38010c461e 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -101,7 +101,7 @@ static int AppInitRPC(int argc, char* argv[]) SetupCliArgs(); std::string error; if (!gArgs.ParseParameters(argc, argv, error)) { - fprintf(stderr, "Error parsing command line arguments: %s\n", error.c_str()); + tfm::format(std::cerr, "Error parsing command line arguments: %s\n", error.c_str()); return EXIT_FAILURE; } if (argc < 2 || HelpRequested(gArgs) || gArgs.IsArgSet("-version")) { @@ -115,26 +115,26 @@ static int AppInitRPC(int argc, char* argv[]) strUsage += "\n" + gArgs.GetHelpMessage(); } - fprintf(stdout, "%s", strUsage.c_str()); + tfm::format(std::cout, "%s", strUsage.c_str()); if (argc < 2) { - fprintf(stderr, "Error: too few parameters\n"); + tfm::format(std::cerr, "Error: too few parameters\n"); return EXIT_FAILURE; } return EXIT_SUCCESS; } if (!fs::is_directory(GetDataDir(false))) { - fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", gArgs.GetArg("-datadir", "").c_str()); + tfm::format(std::cerr, "Error: Specified data directory \"%s\" does not exist.\n", gArgs.GetArg("-datadir", "").c_str()); return EXIT_FAILURE; } if (!gArgs.ReadConfigFiles(error, true)) { - fprintf(stderr, "Error reading configuration file: %s\n", error.c_str()); + tfm::format(std::cerr, "Error reading configuration file: %s\n", error.c_str()); return EXIT_FAILURE; } // Check for -testnet or -regtest parameter (BaseParams() calls are only valid after this clause) try { SelectBaseParams(gArgs.GetChainName()); } catch (const std::exception& e) { - fprintf(stderr, "Error: %s\n", e.what()); + tfm::format(std::cerr, "Error: %s\n", e.what()); return EXIT_FAILURE; } return CONTINUE_EXECUTION; @@ -495,7 +495,7 @@ static int CommandLineRPC(int argc, char *argv[]) } if (strPrint != "") { - fprintf((nRet == 0 ? stdout : stderr), "%s\n", strPrint.c_str()); + tfm::format(nRet == 0 ? std::cout : std::cerr, "%s\n", strPrint.c_str()); } return nRet; } @@ -508,7 +508,7 @@ int main(int argc, char* argv[]) #endif SetupEnvironment(); if (!SetupNetworking()) { - fprintf(stderr, "Error: Initializing networking failed\n"); + tfm::format(std::cerr, "Error: Initializing networking failed\n"); return EXIT_FAILURE; } event_set_log_callback(&libevent_log_cb); diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index ac1d62a8f4..933b34744d 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -82,7 +82,7 @@ static int AppInitRawTx(int argc, char* argv[]) SetupBitcoinTxArgs(); std::string error; if (!gArgs.ParseParameters(argc, argv, error)) { - fprintf(stderr, "Error parsing command line arguments: %s\n", error.c_str()); + tfm::format(std::cerr, "Error parsing command line arguments: %s\n", error.c_str()); return EXIT_FAILURE; } @@ -90,7 +90,7 @@ static int AppInitRawTx(int argc, char* argv[]) try { SelectParams(gArgs.GetChainName()); } catch (const std::exception& e) { - fprintf(stderr, "Error: %s\n", e.what()); + tfm::format(std::cerr, "Error: %s\n", e.what()); return EXIT_FAILURE; } @@ -104,10 +104,10 @@ static int AppInitRawTx(int argc, char* argv[]) "\n"; strUsage += gArgs.GetHelpMessage(); - fprintf(stdout, "%s", strUsage.c_str()); + tfm::format(std::cout, "%s", strUsage.c_str()); if (argc < 2) { - fprintf(stderr, "Error: too few parameters\n"); + tfm::format(std::cerr, "Error: too few parameters\n"); return EXIT_FAILURE; } return EXIT_SUCCESS; @@ -723,21 +723,21 @@ static void OutputTxJSON(const CTransaction& tx) TxToUniv(tx, uint256(), entry); std::string jsonOutput = entry.write(4); - fprintf(stdout, "%s\n", jsonOutput.c_str()); + tfm::format(std::cout, "%s\n", jsonOutput.c_str()); } static void OutputTxHash(const CTransaction& tx) { std::string strHexHash = tx.GetHash().GetHex(); // the hex-encoded transaction hash (aka the transaction id) - fprintf(stdout, "%s\n", strHexHash.c_str()); + tfm::format(std::cout, "%s\n", strHexHash.c_str()); } static void OutputTxHex(const CTransaction& tx) { std::string strHex = EncodeHexTx(tx); - fprintf(stdout, "%s\n", strHex.c_str()); + tfm::format(std::cout, "%s\n", strHex.c_str()); } static void OutputTx(const CTransaction& tx) @@ -828,7 +828,7 @@ static int CommandLineRawTx(int argc, char* argv[]) } if (strPrint != "") { - fprintf((nRet == 0 ? stdout : stderr), "%s\n", strPrint.c_str()); + tfm::format(nRet == 0 ? std::cout : std::cerr, "%s\n", strPrint.c_str()); } return nRet; } diff --git a/src/bitcoin-wallet.cpp b/src/bitcoin-wallet.cpp index 32a539aac6..cbb4ea750c 100644 --- a/src/bitcoin-wallet.cpp +++ b/src/bitcoin-wallet.cpp @@ -8,7 +8,6 @@ #include <chainparams.h> #include <chainparamsbase.h> -#include <consensus/consensus.h> #include <logging.h> #include <util/system.h> #include <util/strencodings.h> @@ -37,7 +36,7 @@ static bool WalletAppInit(int argc, char* argv[]) SetupWalletToolArgs(); std::string error_message; if (!gArgs.ParseParameters(argc, argv, error_message)) { - fprintf(stderr, "Error parsing command line arguments: %s\n", error_message.c_str()); + tfm::format(std::cerr, "Error parsing command line arguments: %s\n", error_message.c_str()); return false; } if (argc < 2 || HelpRequested(gArgs)) { @@ -49,7 +48,7 @@ static bool WalletAppInit(int argc, char* argv[]) " bitcoin-wallet [options] <command>\n\n" + gArgs.GetHelpMessage(); - fprintf(stdout, "%s", usage.c_str()); + tfm::format(std::cout, "%s", usage.c_str()); return false; } @@ -57,7 +56,7 @@ static bool WalletAppInit(int argc, char* argv[]) LogInstance().m_print_to_console = gArgs.GetBoolArg("-printtoconsole", gArgs.GetBoolArg("-debug", false)); if (!fs::is_directory(GetDataDir(false))) { - fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", gArgs.GetArg("-datadir", "").c_str()); + tfm::format(std::cerr, "Error: Specified data directory \"%s\" does not exist.\n", gArgs.GetArg("-datadir", "").c_str()); return false; } // Check for -testnet or -regtest parameter (Params() calls are only valid after this clause) @@ -88,7 +87,7 @@ int main(int argc, char* argv[]) for(int i = 1; i < argc; ++i) { if (!IsSwitchChar(argv[i][0])) { if (!method.empty()) { - fprintf(stderr, "Error: two methods provided (%s and %s). Only one method should be provided.\n", method.c_str(), argv[i]); + tfm::format(std::cerr, "Error: two methods provided (%s and %s). Only one method should be provided.\n", method.c_str(), argv[i]); return EXIT_FAILURE; } method = argv[i]; @@ -96,13 +95,13 @@ int main(int argc, char* argv[]) } if (method.empty()) { - fprintf(stderr, "No method provided. Run `bitcoin-wallet -help` for valid methods.\n"); + tfm::format(std::cerr, "No method provided. Run `bitcoin-wallet -help` for valid methods.\n"); return EXIT_FAILURE; } // A name must be provided when creating a file if (method == "create" && !gArgs.IsArgSet("-wallet")) { - fprintf(stderr, "Wallet name must be provided when creating a new wallet.\n"); + tfm::format(std::cerr, "Wallet name must be provided when creating a new wallet.\n"); return EXIT_FAILURE; } diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index b31f86cdd9..ba6de702e0 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -12,16 +12,12 @@ #include <compat.h> #include <fs.h> #include <interfaces/chain.h> -#include <rpc/server.h> #include <init.h> #include <noui.h> #include <shutdown.h> #include <util/system.h> -#include <httpserver.h> -#include <httprpc.h> #include <util/threadnames.h> #include <util/strencodings.h> -#include <walletinitinterface.h> #include <stdio.h> @@ -74,7 +70,7 @@ static bool AppInit(int argc, char* argv[]) SetupServerArgs(); std::string error; if (!gArgs.ParseParameters(argc, argv, error)) { - fprintf(stderr, "Error parsing command line arguments: %s\n", error.c_str()); + tfm::format(std::cerr, "Error parsing command line arguments: %s\n", error.c_str()); return false; } @@ -92,7 +88,7 @@ static bool AppInit(int argc, char* argv[]) strUsage += "\n" + gArgs.GetHelpMessage(); } - fprintf(stdout, "%s", strUsage.c_str()); + tfm::format(std::cout, "%s", strUsage.c_str()); return true; } @@ -100,25 +96,25 @@ static bool AppInit(int argc, char* argv[]) { if (!fs::is_directory(GetDataDir(false))) { - fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", gArgs.GetArg("-datadir", "").c_str()); + tfm::format(std::cerr, "Error: Specified data directory \"%s\" does not exist.\n", gArgs.GetArg("-datadir", "").c_str()); return false; } if (!gArgs.ReadConfigFiles(error, true)) { - fprintf(stderr, "Error reading configuration file: %s\n", error.c_str()); + tfm::format(std::cerr, "Error reading configuration file: %s\n", error.c_str()); return false; } // Check for -testnet or -regtest parameter (Params() calls are only valid after this clause) try { SelectParams(gArgs.GetChainName()); } catch (const std::exception& e) { - fprintf(stderr, "Error: %s\n", e.what()); + tfm::format(std::cerr, "Error: %s\n", e.what()); return false; } // Error out when loose non-argument tokens are encountered on command line for (int i = 1; i < argc; i++) { if (!IsSwitchChar(argv[i][0])) { - fprintf(stderr, "Error: Command line contains unexpected token '%s', see bitcoind -h for a list of options.\n", argv[i]); + tfm::format(std::cerr, "Error: Command line contains unexpected token '%s', see bitcoind -h for a list of options.\n", argv[i]); return false; } } @@ -150,18 +146,18 @@ static bool AppInit(int argc, char* argv[]) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif - fprintf(stdout, "Bitcoin server starting\n"); + tfm::format(std::cout, "Bitcoin server starting\n"); // Daemonize if (daemon(1, 0)) { // don't chdir (1), do close FDs (0) - fprintf(stderr, "Error: daemon() failed: %s\n", strerror(errno)); + tfm::format(std::cerr, "Error: daemon() failed: %s\n", strerror(errno)); return false; } #if defined(MAC_OSX) #pragma GCC diagnostic pop #endif #else - fprintf(stderr, "Error: -daemon is not supported on this operating system\n"); + tfm::format(std::cerr, "Error: -daemon is not supported on this operating system\n"); return false; #endif // HAVE_DECL_DAEMON } diff --git a/src/consensus/merkle.cpp b/src/consensus/merkle.cpp index b47d9774ca..f87612edef 100644 --- a/src/consensus/merkle.cpp +++ b/src/consensus/merkle.cpp @@ -4,7 +4,6 @@ #include <consensus/merkle.h> #include <hash.h> -#include <util/strencodings.h> /* WARNING! If you're reading this because you're learning about crypto and/or designing a new system that will use merkle trees, keep in mind diff --git a/src/core_read.cpp b/src/core_read.cpp index a879a375ce..a3c9cf0159 100644 --- a/src/core_read.cpp +++ b/src/core_read.cpp @@ -11,7 +11,6 @@ #include <serialize.h> #include <streams.h> #include <univalue.h> -#include <util/system.h> #include <util/strencodings.h> #include <version.h> diff --git a/src/core_write.cpp b/src/core_write.cpp index 765a170307..4d64446d7b 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -13,7 +13,6 @@ #include <streams.h> #include <univalue.h> #include <util/system.h> -#include <util/moneystr.h> #include <util/strencodings.h> UniValue ValueFromAmount(const CAmount& amount) diff --git a/src/crypto/aes.cpp b/src/crypto/aes.cpp index 2dc2133434..b3fb927760 100644 --- a/src/crypto/aes.cpp +++ b/src/crypto/aes.cpp @@ -3,7 +3,6 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <crypto/aes.h> -#include <crypto/common.h> #include <assert.h> #include <string.h> diff --git a/src/crypto/sha256_avx2.cpp b/src/crypto/sha256_avx2.cpp index 068e0e5ff6..90a72516a4 100644 --- a/src/crypto/sha256_avx2.cpp +++ b/src/crypto/sha256_avx2.cpp @@ -3,7 +3,6 @@ #include <stdint.h> #include <immintrin.h> -#include <crypto/sha256.h> #include <crypto/common.h> namespace sha256d64_avx2 { diff --git a/src/crypto/sha256_sse41.cpp b/src/crypto/sha256_sse41.cpp index adca870e2d..fc79f46f7f 100644 --- a/src/crypto/sha256_sse41.cpp +++ b/src/crypto/sha256_sse41.cpp @@ -3,7 +3,6 @@ #include <stdint.h> #include <immintrin.h> -#include <crypto/sha256.h> #include <crypto/common.h> namespace sha256d64_sse41 { diff --git a/src/httprpc.cpp b/src/httprpc.cpp index fcf760a4c6..c7a119440b 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -9,7 +9,6 @@ #include <key_io.h> #include <rpc/protocol.h> #include <rpc/server.h> -#include <random.h> #include <sync.h> #include <util/system.h> #include <util/strencodings.h> diff --git a/src/init.cpp b/src/init.cpp index f9723196b0..6625080c6e 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -51,7 +51,6 @@ #include <util/moneystr.h> #include <util/validation.h> #include <validationinterface.h> -#include <warnings.h> #include <walletinitinterface.h> #include <stdint.h> #include <stdio.h> @@ -109,14 +108,13 @@ static fs::path GetPidFile() NODISCARD static bool CreatePidFile() { - FILE* file = fsbridge::fopen(GetPidFile(), "w"); + fsbridge::ofstream file{GetPidFile()}; if (file) { #ifdef WIN32 - fprintf(file, "%d\n", GetCurrentProcessId()); + tfm::format(file, "%d\n", GetCurrentProcessId()); #else - fprintf(file, "%d\n", getpid()); + tfm::format(file, "%d\n", getpid()); #endif - fclose(file); return true; } else { return InitError(strprintf(_("Unable to create the PID file '%s': %s"), GetPidFile().string(), std::strerror(errno))); @@ -525,7 +523,6 @@ void SetupServerArgs() gArgs.AddArg("-bytespersigop", strprintf("Equivalent bytes per sigop in transactions for relay and mining (default: %u)", DEFAULT_BYTES_PER_SIGOP), false, OptionsCategory::NODE_RELAY); gArgs.AddArg("-datacarrier", strprintf("Relay and mine data carrier transactions (default: %u)", DEFAULT_ACCEPT_DATACARRIER), false, OptionsCategory::NODE_RELAY); gArgs.AddArg("-datacarriersize", strprintf("Maximum size of data in data carrier transactions we relay and mine (default: %u)", MAX_OP_RETURN_RELAY), false, OptionsCategory::NODE_RELAY); - gArgs.AddArg("-mempoolreplacement", strprintf("Enable transaction replacement in the memory pool (default: %u)", DEFAULT_ENABLE_REPLACEMENT), false, OptionsCategory::NODE_RELAY); gArgs.AddArg("-minrelaytxfee=<amt>", strprintf("Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)", CURRENCY_UNIT, FormatMoney(DEFAULT_MIN_RELAY_TX_FEE)), false, OptionsCategory::NODE_RELAY); gArgs.AddArg("-whitelistforcerelay", strprintf("Force relay of transactions from whitelisted peers even if the transactions were already in the mempool or violate local relay policy (default: %d)", DEFAULT_WHITELISTFORCERELAY), false, OptionsCategory::NODE_RELAY); @@ -855,12 +852,6 @@ void InitLogging() { LogInstance().m_print_to_file = !gArgs.IsArgNegated("-debuglogfile"); LogInstance().m_file_path = AbsPathForConfigVal(gArgs.GetArg("-debuglogfile", DEFAULT_DEBUGLOGFILE)); - - // Add newlines to the logfile to distinguish this execution from the last - // one; called before console logging is set up, so this is only sent to - // debug.log. - LogPrintf("\n\n\n\n\n"); - LogInstance().m_print_to_console = gArgs.GetBoolArg("-printtoconsole", !gArgs.GetBoolArg("-daemon", false)); LogInstance().m_log_timestamps = gArgs.GetBoolArg("-logtimestamps", DEFAULT_LOGTIMESTAMPS); LogInstance().m_log_time_micros = gArgs.GetBoolArg("-logtimemicros", DEFAULT_LOGTIMEMICROS); @@ -1177,15 +1168,6 @@ bool AppInitParameterInteraction() nMaxTipAge = gArgs.GetArg("-maxtipage", DEFAULT_MAX_TIP_AGE); - fEnableReplacement = gArgs.GetBoolArg("-mempoolreplacement", DEFAULT_ENABLE_REPLACEMENT); - if ((!fEnableReplacement) && gArgs.IsArgSet("-mempoolreplacement")) { - // Minimal effort at forwards compatibility - std::string strReplacementModeList = gArgs.GetArg("-mempoolreplacement", ""); // default is impossible - std::vector<std::string> vstrReplacementModes; - boost::split(vstrReplacementModes, strReplacementModeList, boost::is_any_of(",")); - fEnableReplacement = (std::find(vstrReplacementModes.begin(), vstrReplacementModes.end(), "fee") != vstrReplacementModes.end()); - } - return true; } @@ -1249,10 +1231,10 @@ bool AppInitMain(InitInterfaces& interfaces) // and because this needs to happen before any other debug.log printing LogInstance().ShrinkDebugFile(); } - if (!LogInstance().OpenDebugLog()) { + } + if (!LogInstance().StartLogging()) { return InitError(strprintf("Could not open debug log file %s", LogInstance().m_file_path.string())); - } } if (!LogInstance().m_log_timestamps) diff --git a/src/interfaces/node.cpp b/src/interfaces/node.cpp index 15646b0ff4..584d218dba 100644 --- a/src/interfaces/node.cpp +++ b/src/interfaces/node.cpp @@ -23,7 +23,6 @@ #include <policy/settings.h> #include <primitives/block.h> #include <rpc/server.h> -#include <scheduler.h> #include <shutdown.h> #include <sync.h> #include <txmempool.h> diff --git a/src/interfaces/wallet.cpp b/src/interfaces/wallet.cpp index b57299d78d..34c982e1e6 100644 --- a/src/interfaces/wallet.cpp +++ b/src/interfaces/wallet.cpp @@ -5,29 +5,21 @@ #include <interfaces/wallet.h> #include <amount.h> -#include <chain.h> #include <consensus/validation.h> -#include <init.h> #include <interfaces/chain.h> #include <interfaces/handler.h> -#include <net.h> #include <policy/feerate.h> #include <policy/fees.h> -#include <policy/policy.h> #include <primitives/transaction.h> -#include <rpc/server.h> -#include <scheduler.h> -#include <script/ismine.h> #include <script/standard.h> #include <support/allocators/secure.h> #include <sync.h> -#include <timedata.h> #include <ui_interface.h> #include <uint256.h> #include <util/system.h> -#include <validation.h> #include <wallet/feebumper.h> #include <wallet/fees.h> +#include <wallet/ismine.h> #include <wallet/rpcwallet.h> #include <wallet/load.h> #include <wallet/wallet.h> diff --git a/src/interfaces/wallet.h b/src/interfaces/wallet.h index 7096f54047..9c9b29a813 100644 --- a/src/interfaces/wallet.h +++ b/src/interfaces/wallet.h @@ -7,7 +7,6 @@ #include <amount.h> // For CAmount #include <pubkey.h> // For CKeyID and CScriptID (definitions needed in CTxDestination instantiation) -#include <script/ismine.h> // For isminefilter, isminetype #include <script/standard.h> // For CTxDestination #include <support/allocators/secure.h> // For SecureString #include <ui_interface.h> // For ChangeType @@ -25,7 +24,10 @@ class CCoinControl; class CFeeRate; class CKey; class CWallet; +enum isminetype : unsigned int; enum class FeeReason; +typedef uint8_t isminefilter; + enum class OutputType; struct CRecipient; diff --git a/src/key.cpp b/src/key.cpp index c17f6a0ae2..3ba21753a2 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -5,7 +5,6 @@ #include <key.h> -#include <arith_uint256.h> #include <crypto/common.h> #include <crypto/hmac_sha512.h> #include <random.h> diff --git a/src/logging.cpp b/src/logging.cpp index 3eda4995db..dc2d130a2a 100644 --- a/src/logging.cpp +++ b/src/logging.cpp @@ -39,28 +39,50 @@ static int FileWriteStr(const std::string &str, FILE *fp) return fwrite(str.data(), 1, str.size(), fp); } -bool BCLog::Logger::OpenDebugLog() +bool BCLog::Logger::StartLogging() { - std::lock_guard<std::mutex> scoped_lock(m_file_mutex); + std::lock_guard<std::mutex> scoped_lock(m_cs); + assert(m_buffering); assert(m_fileout == nullptr); - assert(!m_file_path.empty()); - m_fileout = fsbridge::fopen(m_file_path, "a"); - if (!m_fileout) { - return false; + if (m_print_to_file) { + assert(!m_file_path.empty()); + m_fileout = fsbridge::fopen(m_file_path, "a"); + if (!m_fileout) { + return false; + } + + setbuf(m_fileout, nullptr); // unbuffered + + // Add newlines to the logfile to distinguish this execution from the + // last one. + FileWriteStr("\n\n\n\n\n", m_fileout); } - setbuf(m_fileout, nullptr); // unbuffered // dump buffered messages from before we opened the log + m_buffering = false; while (!m_msgs_before_open.empty()) { - FileWriteStr(m_msgs_before_open.front(), m_fileout); + const std::string& s = m_msgs_before_open.front(); + + if (m_print_to_file) FileWriteStr(s, m_fileout); + if (m_print_to_console) fwrite(s.data(), 1, s.size(), stdout); + m_msgs_before_open.pop_front(); } + if (m_print_to_console) fflush(stdout); return true; } +void BCLog::Logger::DisconnectTestLogger() +{ + std::lock_guard<std::mutex> scoped_lock(m_cs); + m_buffering = true; + if (m_fileout != nullptr) fclose(m_fileout); + m_fileout = nullptr; +} + void BCLog::Logger::EnableCategory(BCLog::LogFlags flag) { m_categories |= flag; @@ -202,8 +224,9 @@ std::string BCLog::Logger::LogTimestampStr(const std::string& str) return strStamped; } -void BCLog::Logger::LogPrintStr(const std::string &str) +void BCLog::Logger::LogPrintStr(const std::string& str) { + std::lock_guard<std::mutex> scoped_lock(m_cs); std::string str_prefixed = str; if (m_log_threadnames && m_started_new_line) { @@ -214,32 +237,31 @@ void BCLog::Logger::LogPrintStr(const std::string &str) m_started_new_line = !str.empty() && str[str.size()-1] == '\n'; + if (m_buffering) { + // buffer if we haven't started logging yet + m_msgs_before_open.push_back(str_prefixed); + return; + } + if (m_print_to_console) { // print to console fwrite(str_prefixed.data(), 1, str_prefixed.size(), stdout); fflush(stdout); } if (m_print_to_file) { - std::lock_guard<std::mutex> scoped_lock(m_file_mutex); - - // buffer if we haven't opened the log yet - if (m_fileout == nullptr) { - m_msgs_before_open.push_back(str_prefixed); - } - else - { - // reopen the log file, if requested - if (m_reopen_file) { - m_reopen_file = false; - FILE* new_fileout = fsbridge::fopen(m_file_path, "a"); - if (new_fileout) { - setbuf(new_fileout, nullptr); // unbuffered - fclose(m_fileout); - m_fileout = new_fileout; - } + assert(m_fileout != nullptr); + + // reopen the log file, if requested + if (m_reopen_file) { + m_reopen_file = false; + FILE* new_fileout = fsbridge::fopen(m_file_path, "a"); + if (new_fileout) { + setbuf(new_fileout, nullptr); // unbuffered + fclose(m_fileout); + m_fileout = new_fileout; } - FileWriteStr(str_prefixed, m_fileout); } + FileWriteStr(str_prefixed, m_fileout); } } diff --git a/src/logging.h b/src/logging.h index e399d4c307..75cd5353c0 100644 --- a/src/logging.h +++ b/src/logging.h @@ -60,9 +60,10 @@ namespace BCLog { class Logger { private: - FILE* m_fileout = nullptr; - std::mutex m_file_mutex; - std::list<std::string> m_msgs_before_open; + mutable std::mutex m_cs; // Can not use Mutex from sync.h because in debug mode it would cause a deadlock when a potential deadlock was detected + FILE* m_fileout = nullptr; // GUARDED_BY(m_cs) + std::list<std::string> m_msgs_before_open; // GUARDED_BY(m_cs) + bool m_buffering{true}; //!< Buffer messages before logging can be started. GUARDED_BY(m_cs) /** * m_started_new_line is a state variable that will suppress printing of @@ -88,12 +89,20 @@ namespace BCLog { std::atomic<bool> m_reopen_file{false}; /** Send a string to the log output */ - void LogPrintStr(const std::string &str); + void LogPrintStr(const std::string& str); /** Returns whether logs will be written to any output */ - bool Enabled() const { return m_print_to_console || m_print_to_file; } + bool Enabled() const + { + std::lock_guard<std::mutex> scoped_lock(m_cs); + return m_buffering || m_print_to_console || m_print_to_file; + } + + /** Start logging (and flush all buffered messages) */ + bool StartLogging(); + /** Only for testing */ + void DisconnectTestLogger(); - bool OpenDebugLog(); void ShrinkDebugFile(); uint32_t GetCategoryMask() const { return m_categories.load(); } diff --git a/src/merkleblock.cpp b/src/merkleblock.cpp index a54268d655..052aebbc80 100644 --- a/src/merkleblock.cpp +++ b/src/merkleblock.cpp @@ -7,7 +7,6 @@ #include <hash.h> #include <consensus/consensus.h> -#include <util/strencodings.h> CMerkleBlock::CMerkleBlock(const CBlock& block, CBloomFilter* filter, const std::set<uint256>* txids) diff --git a/src/miner.cpp b/src/miner.cpp index 3d53515435..015645c9c6 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -13,8 +13,6 @@ #include <consensus/merkle.h> #include <consensus/tx_verify.h> #include <consensus/validation.h> -#include <hash.h> -#include <net.h> #include <policy/feerate.h> #include <policy/policy.h> #include <pow.h> @@ -24,7 +22,6 @@ #include <util/moneystr.h> #include <util/system.h> #include <util/validation.h> -#include <validationinterface.h> #include <algorithm> #include <queue> diff --git a/src/net.cpp b/src/net.cpp index 3c6f5a05f3..75a47d7ad2 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2287,8 +2287,8 @@ public: WSACleanup(); #endif } -} -instance_of_cnetcleanup; +}; +static CNetCleanup instance_of_cnetcleanup; void CConnman::Interrupt() { diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 3d0a9b192d..4b43b2cdf2 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -25,9 +25,7 @@ #include <scheduler.h> #include <tinyformat.h> #include <txmempool.h> -#include <ui_interface.h> #include <util/system.h> -#include <util/moneystr.h> #include <util/strencodings.h> #include <util/validation.h> @@ -70,11 +68,13 @@ static constexpr int32_t MAX_PEER_TX_IN_FLIGHT = 100; /** Maximum number of announced transactions from a peer */ static constexpr int32_t MAX_PEER_TX_ANNOUNCEMENTS = 2 * MAX_INV_SZ; /** How many microseconds to delay requesting transactions from inbound peers */ -static constexpr int64_t INBOUND_PEER_TX_DELAY = 2 * 1000000; +static constexpr int64_t INBOUND_PEER_TX_DELAY = 2 * 1000000; // 2 seconds /** How long to wait (in microseconds) before downloading a transaction from an additional peer */ -static constexpr int64_t GETDATA_TX_INTERVAL = 60 * 1000000; +static constexpr int64_t GETDATA_TX_INTERVAL = 60 * 1000000; // 1 minute /** Maximum delay (in microseconds) for transaction requests to avoid biasing some peers over others. */ -static constexpr int64_t MAX_GETDATA_RANDOM_DELAY = 2 * 1000000; +static constexpr int64_t MAX_GETDATA_RANDOM_DELAY = 2 * 1000000; // 2 seconds +/** How long to wait (in microseconds) before expiring an in-flight getdata request to a peer */ +static constexpr int64_t TX_EXPIRY_INTERVAL = 10 * GETDATA_TX_INTERVAL; static_assert(INBOUND_PEER_TX_DELAY >= MAX_GETDATA_RANDOM_DELAY, "To preserve security, MAX_GETDATA_RANDOM_DELAY should not exceed INBOUND_PEER_DELAY"); /** Limit to avoid sending big packets. Not used in processing incoming GETDATA for compatibility */ @@ -345,8 +345,11 @@ struct CNodeState { //! Store all the transactions a peer has recently announced std::set<uint256> m_tx_announced; - //! Store transactions which were requested by us - std::set<uint256> m_tx_in_flight; + //! Store transactions which were requested by us, with timestamp + std::map<uint256, int64_t> m_tx_in_flight; + + //! Periodically check for stuck getdata requests + int64_t m_check_expiry_timer{0}; }; TxDownloadState m_tx_download; @@ -704,30 +707,40 @@ void UpdateTxRequestTime(const uint256& txid, int64_t request_time) EXCLUSIVE_LO } } - -void RequestTx(CNodeState* state, const uint256& txid, int64_t nNow) EXCLUSIVE_LOCKS_REQUIRED(cs_main) +int64_t CalculateTxGetDataTime(const uint256& txid, int64_t current_time, bool use_inbound_delay) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { - CNodeState::TxDownloadState& peer_download_state = state->m_tx_download; - if (peer_download_state.m_tx_announced.size() >= MAX_PEER_TX_ANNOUNCEMENTS || peer_download_state.m_tx_announced.count(txid)) { - // Too many queued announcements from this peer, or we already have - // this announcement - return; - } - peer_download_state.m_tx_announced.insert(txid); - int64_t process_time; int64_t last_request_time = GetTxRequestTime(txid); // First time requesting this tx if (last_request_time == 0) { - process_time = nNow; + process_time = current_time; } else { // Randomize the delay to avoid biasing some peers over others (such as due to // fixed ordering of peer processing in ThreadMessageHandler) process_time = last_request_time + GETDATA_TX_INTERVAL + GetRand(MAX_GETDATA_RANDOM_DELAY); } - // We delay processing announcements from non-preferred (eg inbound) peers - if (!state->fPreferredDownload) process_time += INBOUND_PEER_TX_DELAY; + // We delay processing announcements from inbound peers + if (use_inbound_delay) process_time += INBOUND_PEER_TX_DELAY; + + return process_time; +} + +void RequestTx(CNodeState* state, const uint256& txid, int64_t nNow) EXCLUSIVE_LOCKS_REQUIRED(cs_main) +{ + CNodeState::TxDownloadState& peer_download_state = state->m_tx_download; + if (peer_download_state.m_tx_announced.size() >= MAX_PEER_TX_ANNOUNCEMENTS || + peer_download_state.m_tx_process_time.size() >= MAX_PEER_TX_ANNOUNCEMENTS || + peer_download_state.m_tx_announced.count(txid)) { + // Too many queued announcements from this peer, or we already have + // this announcement + return; + } + peer_download_state.m_tx_announced.insert(txid); + + // Calculate the time to try requesting this transaction. Use + // fPreferredDownload as a proxy for outbound peers. + int64_t process_time = CalculateTxGetDataTime(txid, nNow, !state->fPreferredDownload); peer_download_state.m_tx_process_time.emplace(process_time, txid); } @@ -1542,16 +1555,28 @@ void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnm } } + // Unknown types in the GetData stay in vRecvGetData and block any future + // message from this peer, see vRecvGetData check in ProcessMessages(). + // Depending on future p2p changes, we might either drop unknown getdata on + // the floor or disconnect the peer. + pfrom->vRecvGetData.erase(pfrom->vRecvGetData.begin(), it); if (!vNotFound.empty()) { // Let the peer know that we didn't find what it asked for, so it doesn't - // have to wait around forever. Currently only SPV clients actually care - // about this message: it's needed when they are recursively walking the - // dependencies of relevant unconfirmed transactions. SPV clients want to - // do that because they want to know about (and store and rebroadcast and - // risk analyze) the dependencies of transactions relevant to them, without - // having to download the entire memory pool. + // have to wait around forever. + // SPV clients care about this message: it's needed when they are + // recursively walking the dependencies of relevant unconfirmed + // transactions. SPV clients want to do that because they want to know + // about (and store and rebroadcast and risk analyze) the dependencies + // of transactions relevant to them, without having to download the + // entire memory pool. + // Also, other nodes can use these messages to automatically request a + // transaction from some other peer that annnounced it, and stop + // waiting for us to respond. + // In normal operation, we often send NOTFOUND messages for parents of + // transactions that we relay; if a peer is missing a parent, they may + // assume we have them and request the parents from us. connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::NOTFOUND, vNotFound)); } } @@ -3148,8 +3173,27 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr } if (strCommand == NetMsgType::NOTFOUND) { - // We do not care about the NOTFOUND message, but logging an Unknown Command - // message would be undesirable as we transmit it ourselves. + // Remove the NOTFOUND transactions from the peer + LOCK(cs_main); + CNodeState *state = State(pfrom->GetId()); + std::vector<CInv> vInv; + vRecv >> vInv; + if (vInv.size() <= MAX_PEER_TX_IN_FLIGHT + MAX_BLOCKS_IN_TRANSIT_PER_PEER) { + for (CInv &inv : vInv) { + if (inv.type == MSG_TX || inv.type == MSG_WITNESS_TX) { + // If we receive a NOTFOUND message for a txid we requested, erase + // it from our data structures for this peer. + auto in_flight_it = state->m_tx_download.m_tx_in_flight.find(inv.hash); + if (in_flight_it == state->m_tx_download.m_tx_in_flight.end()) { + // Skip any further work if this is a spurious NOTFOUND + // message. + continue; + } + state->m_tx_download.m_tx_in_flight.erase(in_flight_it); + state->m_tx_download.m_tx_announced.erase(inv.hash); + } + } + } return true; } @@ -3221,6 +3265,7 @@ bool PeerLogicValidation::ProcessMessages(CNode* pfrom, std::atomic<bool>& inter return false; // this maintains the order of responses + // and prevents vRecvGetData to grow unbounded if (!pfrom->vRecvGetData.empty()) return true; if (!pfrom->orphan_work_set.empty()) return true; @@ -3947,9 +3992,33 @@ bool PeerLogicValidation::SendMessages(CNode* pto) // // Message: getdata (non-blocks) // + + // For robustness, expire old requests after a long timeout, so that + // we can resume downloading transactions from a peer even if they + // were unresponsive in the past. + // Eventually we should consider disconnecting peers, but this is + // conservative. + if (state.m_tx_download.m_check_expiry_timer <= nNow) { + for (auto it=state.m_tx_download.m_tx_in_flight.begin(); it != state.m_tx_download.m_tx_in_flight.end();) { + if (it->second <= nNow - TX_EXPIRY_INTERVAL) { + LogPrint(BCLog::NET, "timeout of inflight tx %s from peer=%d\n", it->first.ToString(), pto->GetId()); + state.m_tx_download.m_tx_announced.erase(it->first); + state.m_tx_download.m_tx_in_flight.erase(it++); + } else { + ++it; + } + } + // On average, we do this check every TX_EXPIRY_INTERVAL. Randomize + // so that we're not doing this for all peers at the same time. + state.m_tx_download.m_check_expiry_timer = nNow + TX_EXPIRY_INTERVAL/2 + GetRand(TX_EXPIRY_INTERVAL); + } + auto& tx_process_time = state.m_tx_download.m_tx_process_time; while (!tx_process_time.empty() && tx_process_time.begin()->first <= nNow && state.m_tx_download.m_tx_in_flight.size() < MAX_PEER_TX_IN_FLIGHT) { - const uint256& txid = tx_process_time.begin()->second; + const uint256 txid = tx_process_time.begin()->second; + // Erase this entry from tx_process_time (it may be added back for + // processing at a later time, see below) + tx_process_time.erase(tx_process_time.begin()); CInv inv(MSG_TX | GetFetchFlags(pto), txid); if (!AlreadyHave(inv)) { // If this transaction was last requested more than 1 minute ago, @@ -3963,20 +4032,20 @@ bool PeerLogicValidation::SendMessages(CNode* pto) vGetData.clear(); } UpdateTxRequestTime(inv.hash, nNow); - state.m_tx_download.m_tx_in_flight.insert(inv.hash); + state.m_tx_download.m_tx_in_flight.emplace(inv.hash, nNow); } else { // This transaction is in flight from someone else; queue // up processing to happen after the download times out // (with a slight delay for inbound peers, to prefer // requests to outbound peers). - RequestTx(&state, txid, nNow); + int64_t next_process_time = CalculateTxGetDataTime(txid, nNow, !state.fPreferredDownload); + tx_process_time.emplace(next_process_time, txid); } } else { // We have already seen this transaction, no need to download. state.m_tx_download.m_tx_announced.erase(inv.hash); state.m_tx_download.m_tx_in_flight.erase(inv.hash); } - tx_process_time.erase(tx_process_time.begin()); } @@ -4023,4 +4092,5 @@ public: mapOrphanTransactions.clear(); mapOrphanTransactionsByPrev.clear(); } -} instance_of_cnetprocessingcleanup; +}; +static CNetProcessingCleanup instance_of_cnetprocessingcleanup; diff --git a/src/netaddress.cpp b/src/netaddress.cpp index 6ee2d8a4b3..4fbfa2b5c8 100644 --- a/src/netaddress.cpp +++ b/src/netaddress.cpp @@ -204,6 +204,11 @@ bool CNetAddr::IsRFC4843() const return (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x00 && (GetByte(12) & 0xF0) == 0x10); } +bool CNetAddr::IsRFC7343() const +{ + return (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x00 && (GetByte(12) & 0xF0) == 0x20); +} + /** * @returns Whether or not this is a dummy address that maps an onion address * into IPv6. @@ -234,7 +239,7 @@ bool CNetAddr::IsLocal() const * be used to refer to an actual host. * * @note A valid address may or may not be publicly routable on the global - * internet. As in, the set of valid addreses is a superset of the set of + * internet. As in, the set of valid addresses is a superset of the set of * publicly routable addresses. * * @see CNetAddr::IsRoutable() @@ -282,14 +287,14 @@ bool CNetAddr::IsValid() const * @returns Whether or not this network address is publicly routable on the * global internet. * - * @note A routable address is always valid. As in, the set of routable addreses + * @note A routable address is always valid. As in, the set of routable addresses * is a subset of the set of valid addresses. * * @see CNetAddr::IsValid() */ bool CNetAddr::IsRoutable() const { - return IsValid() && !(IsRFC1918() || IsRFC2544() || IsRFC3927() || IsRFC4862() || IsRFC6598() || IsRFC5737() || (IsRFC4193() && !IsTor()) || IsRFC4843() || IsLocal() || IsInternal()); + return IsValid() && !(IsRFC1918() || IsRFC2544() || IsRFC3927() || IsRFC4862() || IsRFC6598() || IsRFC5737() || (IsRFC4193() && !IsTor()) || IsRFC4843() || IsRFC7343() || IsLocal() || IsInternal()); } /** diff --git a/src/netaddress.h b/src/netaddress.h index 8230e40606..673eaf8d7b 100644 --- a/src/netaddress.h +++ b/src/netaddress.h @@ -63,7 +63,8 @@ class CNetAddr bool IsRFC3964() const; // IPv6 6to4 tunnelling (2002::/16) bool IsRFC4193() const; // IPv6 unique local (FC00::/7) bool IsRFC4380() const; // IPv6 Teredo tunnelling (2001::/32) - bool IsRFC4843() const; // IPv6 ORCHID (2001:10::/28) + bool IsRFC4843() const; // IPv6 ORCHID (deprecated) (2001:10::/28) + bool IsRFC7343() const; // IPv6 ORCHIDv2 (2001:20::/28) bool IsRFC4862() const; // IPv6 autoconfig (FE80::/64) bool IsRFC6052() const; // IPv6 well-known prefix for IPv4-embedded address (64:FF9B::/96) bool IsRFC6145() const; // IPv6 IPv4-translated address (::FFFF:0:0:0/96) (actually defined in RFC2765) diff --git a/src/netbase.cpp b/src/netbase.cpp index 6c386a9ade..78b3b6ae3a 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -5,10 +5,7 @@ #include <netbase.h> -#include <hash.h> #include <sync.h> -#include <uint256.h> -#include <random.h> #include <tinyformat.h> #include <util/system.h> #include <util/strencodings.h> diff --git a/src/noui.cpp b/src/noui.cpp index c7d8fee0ba..caab9f326e 100644 --- a/src/noui.cpp +++ b/src/noui.cpp @@ -18,26 +18,30 @@ bool noui_ThreadSafeMessageBox(const std::string& message, const std::string& ca { bool fSecure = style & CClientUIInterface::SECURE; style &= ~CClientUIInterface::SECURE; + bool prefix = !(style & CClientUIInterface::MSG_NOPREFIX); + style &= ~CClientUIInterface::MSG_NOPREFIX; std::string strCaption; - // Check for usage of predefined caption - switch (style) { - case CClientUIInterface::MSG_ERROR: - strCaption += _("Error"); - break; - case CClientUIInterface::MSG_WARNING: - strCaption += _("Warning"); - break; - case CClientUIInterface::MSG_INFORMATION: - strCaption += _("Information"); - break; - default: - strCaption += caption; // Use supplied caption (can be empty) + if (prefix) { + switch (style) { + case CClientUIInterface::MSG_ERROR: + strCaption = "Error: "; + break; + case CClientUIInterface::MSG_WARNING: + strCaption = "Warning: "; + break; + case CClientUIInterface::MSG_INFORMATION: + strCaption = "Information: "; + break; + default: + strCaption = caption + ": "; // Use supplied caption (can be empty) + } } - if (!fSecure) - LogPrintf("%s: %s\n", strCaption, message); - fprintf(stderr, "%s: %s\n", strCaption.c_str(), message.c_str()); + if (!fSecure) { + LogPrintf("%s%s\n", strCaption, message); + } + tfm::format(std::cerr, "%s%s\n", strCaption.c_str(), message.c_str()); return false; } diff --git a/src/policy/fees.cpp b/src/policy/fees.cpp index 6456eec016..5d538606c2 100644 --- a/src/policy/fees.cpp +++ b/src/policy/fees.cpp @@ -4,7 +4,6 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <policy/fees.h> -#include <policy/policy.h> #include <clientversion.h> #include <primitives/transaction.h> @@ -48,7 +47,7 @@ private: std::vector<double> txCtAvg; // Count the total # of txs confirmed within Y blocks in each bucket - // Track the historical moving average of theses totals over blocks + // Track the historical moving average of these totals over blocks std::vector<std::vector<double>> confAvg; // confAvg[Y][X] // Track moving avg of txs which have been evicted from the mempool diff --git a/src/policy/fees.h b/src/policy/fees.h index 6e61f76178..16683bf5ad 100644 --- a/src/policy/fees.h +++ b/src/policy/fees.h @@ -43,7 +43,6 @@ enum class FeeReason { PAYTXFEE, FALLBACK, REQUIRED, - MAXTXFEE, }; /* Used to determine type of fee estimation requested */ diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 63a3d06267..51de5841ec 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -9,10 +9,6 @@ #include <consensus/validation.h> #include <coins.h> -#include <policy/settings.h> -#include <tinyformat.h> -#include <util/system.h> -#include <util/strencodings.h> CAmount GetDustThreshold(const CTxOut& txout, const CFeeRate& dustRelayFeeIn) diff --git a/src/prevector.h b/src/prevector.h index ea8707389a..9d576321b6 100644 --- a/src/prevector.h +++ b/src/prevector.h @@ -378,6 +378,21 @@ public: fill(ptr, first, last); } + inline void resize_uninitialized(size_type new_size) { + // resize_uninitialized changes the size of the prevector but does not initialize it. + // If size < new_size, the added elements must be initialized explicitly. + if (capacity() < new_size) { + change_capacity(new_size); + _size += new_size - size(); + return; + } + if (new_size < size()) { + erase(item_ptr(new_size), end()); + } else { + _size += new_size - size(); + } + } + iterator erase(iterator pos) { return erase(pos, pos + 1); } diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp index a0c2e3f125..60c7c2d160 100644 --- a/src/primitives/block.cpp +++ b/src/primitives/block.cpp @@ -7,7 +7,6 @@ #include <hash.h> #include <tinyformat.h> -#include <util/strencodings.h> #include <crypto/common.h> uint256 CBlockHeader::GetHash() const diff --git a/src/psbt.cpp b/src/psbt.cpp index 97bda51a63..fe74002e82 100644 --- a/src/psbt.cpp +++ b/src/psbt.cpp @@ -2,9 +2,6 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include <coins.h> -#include <consensus/tx_verify.h> -#include <policy/policy.h> #include <psbt.h> #include <util/strencodings.h> @@ -215,6 +212,25 @@ bool PSBTInputSigned(const PSBTInput& input) return !input.final_script_sig.empty() || !input.final_script_witness.IsNull(); } +void UpdatePSBTOutput(const SigningProvider& provider, PartiallySignedTransaction& psbt, int index) +{ + const CTxOut& out = psbt.tx->vout.at(index); + PSBTOutput& psbt_out = psbt.outputs.at(index); + + // Fill a SignatureData with output info + SignatureData sigdata; + psbt_out.FillSignatureData(sigdata); + + // Construct a would-be spend of this output, to update sigdata with. + // Note that ProduceSignature is used to fill in metadata (not actual signatures), + // so provider does not need to provide any private keys (it can be a HidingSigningProvider). + MutableTransactionSignatureCreator creator(psbt.tx.get_ptr(), /* index */ 0, out.nValue, SIGHASH_ALL); + ProduceSignature(provider, creator, out.scriptPubKey, sigdata); + + // Put redeem_script, witness_script, key paths, into PSBTOutput. + psbt_out.FromSignatureData(sigdata); +} + bool SignPSBTInput(const SigningProvider& provider, PartiallySignedTransaction& psbt, int index, int sighash, SignatureData* out_sigdata, bool use_dummy) { PSBTInput& input = psbt.inputs.at(index); diff --git a/src/psbt.h b/src/psbt.h index 1bc1e91a84..f3840b9ed3 100644 --- a/src/psbt.h +++ b/src/psbt.h @@ -565,6 +565,12 @@ bool PSBTInputSigned(const PSBTInput& input); /** Signs a PSBTInput, verifying that all provided data matches what is being signed. */ bool SignPSBTInput(const SigningProvider& provider, PartiallySignedTransaction& psbt, int index, int sighash = SIGHASH_ALL, SignatureData* out_sigdata = nullptr, bool use_dummy = false); +/** Updates a PSBTOutput with information from provider. + * + * This fills in the redeem_script, witness_script, and hd_keypaths where possible. + */ +void UpdatePSBTOutput(const SigningProvider& provider, PartiallySignedTransaction& psbt, int index); + /** * Finalizes a PSBT if possible, combining partial signatures. * diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index 50d6afabcd..d8c39e8862 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -10,7 +10,6 @@ #include <qt/forms/ui_addressbookpage.h> #include <qt/addresstablemodel.h> -#include <qt/bitcoingui.h> #include <qt/csvmodelwriter.h> #include <qt/editaddressdialog.h> #include <qt/guiutil.h> diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index c3143e948a..fa6c9c9f7a 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -7,7 +7,6 @@ #include <qt/guiutil.h> #include <qt/walletmodel.h> -#include <interfaces/node.h> #include <key_io.h> #include <wallet/wallet.h> diff --git a/src/qt/bantablemodel.cpp b/src/qt/bantablemodel.cpp index 00c446cc63..8a6b205cd8 100644 --- a/src/qt/bantablemodel.cpp +++ b/src/qt/bantablemodel.cpp @@ -5,8 +5,6 @@ #include <qt/bantablemodel.h> #include <qt/clientmodel.h> -#include <qt/guiconstants.h> -#include <qt/guiutil.h> #include <interfaces/node.h> #include <sync.h> diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 81255aaae9..2fdbcca043 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -31,13 +31,9 @@ #include <interfaces/node.h> #include <noui.h> #include <util/threadnames.h> -#include <rpc/server.h> #include <ui_interface.h> #include <uint256.h> #include <util/system.h> -#include <warnings.h> - -#include <walletinitinterface.h> #include <memory> #include <stdint.h> @@ -334,7 +330,7 @@ void BitcoinApplication::initializeResult(bool success) if(success) { // Log this only after AppInitMain finishes, as then logging setup is guaranteed complete - qWarning() << "Platform customization:" << platformStyle->getName(); + qInfo() << "Platform customization:" << platformStyle->getName(); #ifdef ENABLE_WALLET m_wallet_controller = new WalletController(m_node, platformStyle, optionsModel, this); #ifdef ENABLE_BIP70 @@ -440,16 +436,17 @@ int GuiMain(int argc, char* argv[]) Q_INIT_RESOURCE(bitcoin); Q_INIT_RESOURCE(bitcoin_locale); - BitcoinApplication app(*node, argc, argv); // Generate high-dpi pixmaps QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); #if QT_VERSION >= 0x050600 - QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); #endif #ifdef Q_OS_MAC QApplication::setAttribute(Qt::AA_DontShowIconsInMenus); #endif + BitcoinApplication app(*node, argc, argv); + // Register meta types used for QMetaObject::invokeMethod qRegisterMetaType< bool* >(); // Need to pass name here as CAmount is a typedef (see http://qt-project.org/doc/qt-5/qmetatype.html#qRegisterMetaType) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index b5c92e10a2..babb2ce518 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -335,8 +335,9 @@ void BitcoinGUI::createActions() openAction->setStatusTip(tr("Open a bitcoin: URI or payment request")); m_open_wallet_action = new QAction(tr("Open Wallet"), this); - m_open_wallet_action->setMenu(new QMenu(this)); + m_open_wallet_action->setEnabled(false); m_open_wallet_action->setStatusTip(tr("Open a wallet")); + m_open_wallet_menu = new QMenu(this); m_close_wallet_action = new QAction(tr("Close Wallet..."), this); m_close_wallet_action->setStatusTip(tr("Close wallet")); @@ -368,13 +369,13 @@ void BitcoinGUI::createActions() connect(usedSendingAddressesAction, &QAction::triggered, walletFrame, &WalletFrame::usedSendingAddresses); connect(usedReceivingAddressesAction, &QAction::triggered, walletFrame, &WalletFrame::usedReceivingAddresses); connect(openAction, &QAction::triggered, this, &BitcoinGUI::openClicked); - connect(m_open_wallet_action->menu(), &QMenu::aboutToShow, [this] { - m_open_wallet_action->menu()->clear(); + connect(m_open_wallet_menu, &QMenu::aboutToShow, [this] { + m_open_wallet_menu->clear(); std::vector<std::string> available_wallets = m_wallet_controller->getWalletsAvailableToOpen(); std::vector<std::string> wallets = m_node.listWalletDir(); for (const auto& path : wallets) { QString name = path.empty() ? QString("["+tr("default wallet")+"]") : QString::fromStdString(path); - QAction* action = m_open_wallet_action->menu()->addAction(name); + QAction* action = m_open_wallet_menu->addAction(name); if (std::find(available_wallets.begin(), available_wallets.end(), path) == available_wallets.end()) { // This wallet is already loaded @@ -410,7 +411,7 @@ void BitcoinGUI::createActions() }); } if (wallets.empty()) { - QAction* action = m_open_wallet_action->menu()->addAction(tr("No wallets available")); + QAction* action = m_open_wallet_menu->addAction(tr("No wallets available")); action->setEnabled(false); } }); @@ -633,6 +634,9 @@ void BitcoinGUI::setWalletController(WalletController* wallet_controller) m_wallet_controller = wallet_controller; + m_open_wallet_action->setEnabled(true); + m_open_wallet_action->setMenu(m_open_wallet_menu); + connect(wallet_controller, &WalletController::walletAdded, this, &BitcoinGUI::addWallet); connect(wallet_controller, &WalletController::walletRemoved, this, &BitcoinGUI::removeWallet); @@ -1035,49 +1039,51 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVer progressBar->setToolTip(tooltip); } -void BitcoinGUI::message(const QString &title, const QString &message, unsigned int style, bool *ret) +void BitcoinGUI::message(const QString& title, QString message, unsigned int style, bool* ret) { - QString strTitle = tr("Bitcoin"); // default title + // Default title. On macOS, the window title is ignored (as required by the macOS Guidelines). + QString strTitle{PACKAGE_NAME}; // Default to information icon int nMBoxIcon = QMessageBox::Information; int nNotifyIcon = Notificator::Information; - QString msgType; + bool prefix = !(style & CClientUIInterface::MSG_NOPREFIX); + style &= ~CClientUIInterface::MSG_NOPREFIX; - // Prefer supplied title over style based title + QString msgType; if (!title.isEmpty()) { msgType = title; - } - else { + } else { switch (style) { case CClientUIInterface::MSG_ERROR: msgType = tr("Error"); + if (prefix) message = tr("Error: %1").arg(message); break; case CClientUIInterface::MSG_WARNING: msgType = tr("Warning"); + if (prefix) message = tr("Warning: %1").arg(message); break; case CClientUIInterface::MSG_INFORMATION: msgType = tr("Information"); + // No need to prepend the prefix here. break; default: break; } } - // Append title to "Bitcoin - " - if (!msgType.isEmpty()) + + if (!msgType.isEmpty()) { strTitle += " - " + msgType; + } - // Check for error/warning icon if (style & CClientUIInterface::ICON_ERROR) { nMBoxIcon = QMessageBox::Critical; nNotifyIcon = Notificator::Critical; - } - else if (style & CClientUIInterface::ICON_WARNING) { + } else if (style & CClientUIInterface::ICON_WARNING) { nMBoxIcon = QMessageBox::Warning; nNotifyIcon = Notificator::Warning; } - // Display message if (style & CClientUIInterface::MODAL) { // Check for buttons, use OK as default, if none was supplied QMessageBox::StandardButton buttons; @@ -1090,9 +1096,9 @@ void BitcoinGUI::message(const QString &title, const QString &message, unsigned int r = mBox.exec(); if (ret != nullptr) *ret = r == QMessageBox::Ok; - } - else + } else { notificator->notify(static_cast<Notificator::Class>(nNotifyIcon), strTitle, message); + } } void BitcoinGUI::changeEvent(QEvent *e) diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index b58ccbb455..46ced79007 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -148,6 +148,7 @@ private: QAction* openAction = nullptr; QAction* showHelpMessageAction = nullptr; QAction* m_open_wallet_action{nullptr}; + QMenu* m_open_wallet_menu{nullptr}; QAction* m_close_wallet_action{nullptr}; QAction* m_wallet_selector_label_action = nullptr; QAction* m_wallet_selector_action = nullptr; @@ -219,7 +220,7 @@ public Q_SLOTS: @see CClientUIInterface::MessageBoxFlags @param[in] ret pointer to a bool that will be modified to whether Ok was clicked (modal only) */ - void message(const QString &title, const QString &message, unsigned int style, bool *ret = nullptr); + void message(const QString& title, QString message, unsigned int style, bool* ret = nullptr); #ifdef ENABLE_WALLET void setCurrentWallet(WalletModel* wallet_model); diff --git a/src/qt/bitcoinunits.cpp b/src/qt/bitcoinunits.cpp index 8aa1fdba4d..b27f8a744f 100644 --- a/src/qt/bitcoinunits.cpp +++ b/src/qt/bitcoinunits.cpp @@ -4,8 +4,6 @@ #include <qt/bitcoinunits.h> -#include <primitives/transaction.h> - #include <QStringList> BitcoinUnits::BitcoinUnits(QObject *parent): diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 88a35534c2..ce950150df 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -9,18 +9,12 @@ #include <qt/guiutil.h> #include <qt/peertablemodel.h> -#include <chain.h> -#include <chainparams.h> #include <clientversion.h> #include <interfaces/handler.h> #include <interfaces/node.h> -#include <validation.h> #include <net.h> #include <netbase.h> -#include <txmempool.h> -#include <ui_interface.h> #include <util/system.h> -#include <warnings.h> #include <stdint.h> diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 6c9bae7673..6b9f79aaf8 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -10,12 +10,10 @@ #include <qt/forms/ui_coincontroldialog.h> #include <qt/addresstablemodel.h> -#include <base58.h> #include <qt/bitcoinunits.h> #include <qt/guiutil.h> #include <qt/optionsmodel.h> #include <qt/platformstyle.h> -#include <txmempool.h> #include <qt/walletmodel.h> #include <wallet/coincontrol.h> @@ -23,8 +21,6 @@ #include <key_io.h> #include <policy/fees.h> #include <policy/policy.h> -#include <validation.h> // For mempool -#include <wallet/fees.h> #include <wallet/wallet.h> #include <QApplication> diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index 5b4fb4cc18..f3974b1c85 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -172,7 +172,7 @@ static void CopySettings(QSettings& dst, const QSettings& src) /** Back up a QSettings to an ini-formatted file. */ static void BackupSettings(const fs::path& filename, const QSettings& src) { - qWarning() << "Backing up GUI settings to" << GUIUtil::boostPathToQString(filename); + qInfo() << "Backing up GUI settings to" << GUIUtil::boostPathToQString(filename); QSettings dst(GUIUtil::boostPathToQString(filename), QSettings::IniFormat); dst.clear(); CopySettings(dst, src); diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 43dccec4ea..c99515fe1c 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -488,7 +488,7 @@ void PaymentServer::LoadRootCAs(X509_STORE* _store) continue; } } - qWarning() << "PaymentServer::LoadRootCAs: Loaded " << nRootCerts << " root certificates"; + qInfo() << "PaymentServer::LoadRootCAs: Loaded " << nRootCerts << " root certificates"; // Project for another day: // Fetch certificate revocation lists, and add them to certStore. diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp index 496aeebf7d..85b691c470 100644 --- a/src/qt/peertablemodel.cpp +++ b/src/qt/peertablemodel.cpp @@ -9,7 +9,6 @@ #include <qt/guiutil.h> #include <interfaces/node.h> -#include <validation.h> // for cs_main #include <sync.h> #include <QDebug> diff --git a/src/qt/platformstyle.cpp b/src/qt/platformstyle.cpp index d537d759de..fca2a4e8c5 100644 --- a/src/qt/platformstyle.cpp +++ b/src/qt/platformstyle.cpp @@ -4,8 +4,6 @@ #include <qt/platformstyle.h> -#include <qt/guiconstants.h> - #include <QApplication> #include <QColor> #include <QImage> diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index fc58090dcd..c58717e21e 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -7,9 +7,7 @@ #include <qt/receivecoinsdialog.h> #include <qt/forms/ui_receivecoinsdialog.h> -#include <qt/addressbookpage.h> #include <qt/addresstablemodel.h> -#include <qt/bitcoinunits.h> #include <qt/optionsmodel.h> #include <qt/platformstyle.h> #include <qt/receiverequestdialog.h> diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp index 20b29145a0..e492502002 100644 --- a/src/qt/receiverequestdialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -8,7 +8,6 @@ #include <qt/bitcoinunits.h> #include <qt/guiutil.h> #include <qt/optionsmodel.h> -#include <qt/qrimagewidget.h> #include <QClipboard> #include <QPixmap> diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 8a0b265834..cb9efe9319 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -279,18 +279,16 @@ void SendCoinsDialog::on_sendButton_clicked() QStringList formatted; for (const SendCoinsRecipient &rcp : currentTransaction.getRecipients()) { - // generate bold amount string with wallet name in case of multiwallet - QString amount = "<b>" + BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), rcp.amount); + // generate amount string with wallet name in case of multiwallet + QString amount = BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), rcp.amount); if (model->isMultiwallet()) { - amount.append(" <u>"+tr("from wallet %1").arg(GUIUtil::HtmlEscape(model->getWalletName()))+"</u> "); + amount.append(tr(" from wallet '%1'").arg(model->getWalletName())); } - amount.append("</b>"); - // generate monospace address string - QString address = "<span style='font-family: monospace;'>" + rcp.address; - address.append("</span>"); + + // generate address string + QString address = rcp.address; QString recipientElement; - recipientElement = "<br />"; #ifdef ENABLE_BIP70 if (!rcp.paymentRequest.IsInitialized()) // normal payment @@ -298,7 +296,7 @@ void SendCoinsDialog::on_sendButton_clicked() { if(rcp.label.length() > 0) // label with address { - recipientElement.append(tr("%1 to %2").arg(amount, GUIUtil::HtmlEscape(rcp.label))); + recipientElement.append(tr("%1 to '%2'").arg(amount, rcp.label)); recipientElement.append(QString(" (%1)").arg(address)); } else // just address @@ -309,7 +307,7 @@ void SendCoinsDialog::on_sendButton_clicked() #ifdef ENABLE_BIP70 else if(!rcp.authenticatedMerchant.isEmpty()) // authenticated payment request { - recipientElement.append(tr("%1 to %2").arg(amount, GUIUtil::HtmlEscape(rcp.authenticatedMerchant))); + recipientElement.append(tr("%1 to '%2'").arg(amount, rcp.authenticatedMerchant)); } else // unauthenticated payment request { @@ -323,7 +321,7 @@ void SendCoinsDialog::on_sendButton_clicked() QString questionString = tr("Are you sure you want to send?"); questionString.append("<br /><span style='font-size:10pt;'>"); questionString.append(tr("Please, review your transaction.")); - questionString.append("</span><br />%1"); + questionString.append("</span>%1"); if(txFee > 0) { @@ -364,8 +362,17 @@ void SendCoinsDialog::on_sendButton_clicked() questionString.append(QString("<br /><span style='font-size:10pt; font-weight:normal;'>(=%1)</span>") .arg(alternativeUnits.join(" " + tr("or") + " "))); - SendConfirmationDialog confirmationDialog(tr("Confirm send coins"), - questionString.arg(formatted.join("<br />")), SEND_CONFIRM_DELAY, this); + QString informative_text; + QString detailed_text; + if (formatted.size() > 1) { + questionString = questionString.arg(""); + informative_text = tr("To review recipient list click \"Show Details...\""); + detailed_text = formatted.join("\n\n"); + } else { + questionString = questionString.arg("<br /><br />" + formatted.at(0)); + } + + SendConfirmationDialog confirmationDialog(tr("Confirm send coins"), questionString, informative_text, detailed_text, SEND_CONFIRM_DELAY, this); confirmationDialog.exec(); QMessageBox::StandardButton retval = static_cast<QMessageBox::StandardButton>(confirmationDialog.result()); @@ -881,10 +888,15 @@ void SendCoinsDialog::coinControlUpdateLabels() } } -SendConfirmationDialog::SendConfirmationDialog(const QString &title, const QString &text, int _secDelay, - QWidget *parent) : - QMessageBox(QMessageBox::Question, title, text, QMessageBox::Yes | QMessageBox::Cancel, parent), secDelay(_secDelay) +SendConfirmationDialog::SendConfirmationDialog(const QString& title, const QString& text, const QString& informative_text, const QString& detailed_text, int _secDelay, QWidget* parent) + : QMessageBox(parent), secDelay(_secDelay) { + setIcon(QMessageBox::Question); + setWindowTitle(title); // On macOS, the window title is ignored (as required by the macOS Guidelines). + setText(text); + setInformativeText(informative_text); + setDetailedText(detailed_text); + setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel); setDefaultButton(QMessageBox::Cancel); yesButton = button(QMessageBox::Yes); updateYesButton(); diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h index 337a72b878..c6c1816877 100644 --- a/src/qt/sendcoinsdialog.h +++ b/src/qt/sendcoinsdialog.h @@ -108,7 +108,7 @@ class SendConfirmationDialog : public QMessageBox Q_OBJECT public: - SendConfirmationDialog(const QString &title, const QString &text, int secDelay = SEND_CONFIRM_DELAY, QWidget *parent = nullptr); + SendConfirmationDialog(const QString& title, const QString& text, const QString& informative_text = "", const QString& detailed_text = "", int secDelay = SEND_CONFIRM_DELAY, QWidget* parent = nullptr); int exec(); private Q_SLOTS: diff --git a/src/qt/test/addressbooktests.cpp b/src/qt/test/addressbooktests.cpp index 2ba1c2604c..11a518ebd2 100644 --- a/src/qt/test/addressbooktests.cpp +++ b/src/qt/test/addressbooktests.cpp @@ -4,8 +4,6 @@ #include <interfaces/chain.h> #include <interfaces/node.h> -#include <qt/addressbookpage.h> -#include <qt/addresstablemodel.h> #include <qt/editaddressdialog.h> #include <qt/optionsmodel.h> #include <qt/platformstyle.h> @@ -14,7 +12,6 @@ #include <key.h> #include <key_io.h> -#include <pubkey.h> #include <wallet/wallet.h> #include <QApplication> diff --git a/src/qt/test/apptests.cpp b/src/qt/test/apptests.cpp index da25d83175..a900ec0198 100644 --- a/src/qt/test/apptests.cpp +++ b/src/qt/test/apptests.cpp @@ -5,7 +5,7 @@ #include <qt/test/apptests.h> #include <chainparams.h> -#include <init.h> +#include <key.h> #include <qt/bitcoin.h> #include <qt/bitcoingui.h> #include <qt/networkstyle.h> @@ -16,9 +16,6 @@ #if defined(HAVE_CONFIG_H) #include <config/bitcoin-config.h> #endif -#ifdef ENABLE_WALLET -#include <wallet/db.h> -#endif #include <QAction> #include <QEventLoop> @@ -29,7 +26,6 @@ #include <QtGlobal> #include <QtTest/QtTestWidgets> #include <QtTest/QtTestGui> -#include <new> #include <string> #include <univalue.h> @@ -66,6 +62,9 @@ void AppTests::appTests() } #endif + ECC_Stop(); // Already started by the common test setup, so stop it to avoid interference + LogInstance().DisconnectTestLogger(); + m_app.parameterSetup(); m_app.createOptionsModel(true /* reset settings */); QScopedPointer<const NetworkStyle> style( diff --git a/src/qt/test/rpcnestedtests.cpp b/src/qt/test/rpcnestedtests.cpp index b0bd89b290..3735f41f9d 100644 --- a/src/qt/test/rpcnestedtests.cpp +++ b/src/qt/test/rpcnestedtests.cpp @@ -4,12 +4,7 @@ #include <qt/test/rpcnestedtests.h> -#include <chainparams.h> -#include <consensus/validation.h> -#include <fs.h> #include <interfaces/node.h> -#include <validation.h> -#include <rpc/register.h> #include <rpc/server.h> #include <qt/rpcconsole.h> #include <test/setup_common.h> @@ -39,6 +34,9 @@ void RPCNestedTests::rpcNestedTests() tableRPC.appendCommand("rpcNestedTest", &vRPCCommands[0]); //mempool.setSanityCheck(1.0); + ECC_Stop(); // Already started by the common test setup, so stop it to avoid interference + LogInstance().DisconnectTestLogger(); + TestingSetup test; if (RPCIsInWarmup(nullptr)) SetRPCWarmupFinished(); diff --git a/src/qt/test/rpcnestedtests.h b/src/qt/test/rpcnestedtests.h index e33f4e3da1..97143ff78a 100644 --- a/src/qt/test/rpcnestedtests.h +++ b/src/qt/test/rpcnestedtests.h @@ -8,9 +8,6 @@ #include <QObject> #include <QTest> -#include <txdb.h> -#include <txmempool.h> - class RPCNestedTests : public QObject { Q_OBJECT diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp index a2bf53973b..79d88ab742 100644 --- a/src/qt/test/test_main.cpp +++ b/src/qt/test/test_main.cpp @@ -6,14 +6,13 @@ #include <config/bitcoin-config.h> #endif -#include <chainparams.h> #include <interfaces/node.h> #include <qt/bitcoin.h> #include <qt/test/apptests.h> #include <qt/test/rpcnestedtests.h> -#include <util/system.h> #include <qt/test/uritests.h> #include <qt/test/compattests.h> +#include <test/setup_common.h> #ifdef ENABLE_WALLET #include <qt/test/addressbooktests.h> @@ -48,14 +47,8 @@ extern void noui_connect(); // This is all you need to run all the tests int main(int argc, char *argv[]) { - SetupEnvironment(); - SetupNetworking(); - SelectParams(CBaseChainParams::REGTEST); - noui_connect(); - ClearDatadirCache(); - fs::path pathTemp = fs::temp_directory_path() / strprintf("test_bitcoin-qt_%lu_%i", (unsigned long)GetTime(), (int)GetRand(100000)); - fs::create_directories(pathTemp); - gArgs.ForceSetArg("-datadir", pathTemp.string()); + BasicTestingSetup test{CBaseChainParams::REGTEST}; + auto node = interfaces::MakeNode(); bool fInvalid = false; @@ -109,7 +102,5 @@ int main(int argc, char *argv[]) } #endif - fs::remove_all(pathTemp); - return fInvalid; } diff --git a/src/qt/test/wallettests.cpp b/src/qt/test/wallettests.cpp index ab40e9962b..e54915ec75 100644 --- a/src/qt/test/wallettests.cpp +++ b/src/qt/test/wallettests.cpp @@ -1,10 +1,8 @@ #include <qt/test/wallettests.h> #include <qt/test/util.h> -#include <init.h> #include <interfaces/chain.h> #include <interfaces/node.h> -#include <base58.h> #include <qt/bitcoinamountfield.h> #include <qt/optionsmodel.h> #include <qt/platformstyle.h> diff --git a/src/qt/trafficgraphwidget.cpp b/src/qt/trafficgraphwidget.cpp index 1588be8da3..006007be63 100644 --- a/src/qt/trafficgraphwidget.cpp +++ b/src/qt/trafficgraphwidget.cpp @@ -104,6 +104,7 @@ void TrafficGraphWidget::paintEvent(QPaintEvent *) } } + painter.setRenderHint(QPainter::Antialiasing); if(!vSamplesIn.empty()) { QPainterPath p; paintPath(p, vSamplesIn); diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 0d070d9e87..ebe7925368 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -20,9 +20,8 @@ #include <script/script.h> #include <timedata.h> #include <util/system.h> -#include <wallet/db.h> -#include <wallet/wallet.h> #include <policy/policy.h> +#include <wallet/ismine.h> #include <stdint.h> #include <string> diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index aa785553c8..9de90759fa 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -5,11 +5,9 @@ #include <qt/transactionrecord.h> #include <chain.h> -#include <consensus/consensus.h> #include <interfaces/wallet.h> #include <key_io.h> -#include <timedata.h> -#include <validation.h> +#include <wallet/ismine.h> #include <stdint.h> diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 631a9b891d..6fe35b13cf 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -15,11 +15,7 @@ #include <core_io.h> #include <interfaces/handler.h> -#include <interfaces/node.h> -#include <sync.h> #include <uint256.h> -#include <util/system.h> -#include <validation.h> #include <QColor> #include <QDateTime> diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index 762ec434a1..17e174e57a 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -10,7 +10,6 @@ #include <qt/editaddressdialog.h> #include <qt/optionsmodel.h> #include <qt/platformstyle.h> -#include <qt/sendcoinsdialog.h> #include <qt/transactiondescdialog.h> #include <qt/transactionfilterproxy.h> #include <qt/transactionrecord.h> diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index b051dd159b..aa810690c9 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -11,17 +11,12 @@ #include <qt/forms/ui_helpmessagedialog.h> #include <qt/bitcoingui.h> -#include <qt/clientmodel.h> -#include <qt/guiconstants.h> -#include <qt/intro.h> #ifdef ENABLE_BIP70 #include <qt/paymentrequestplus.h> #endif -#include <qt/guiutil.h> #include <clientversion.h> #include <init.h> -#include <interfaces/node.h> #include <util/system.h> #include <util/strencodings.h> @@ -129,7 +124,7 @@ HelpMessageDialog::~HelpMessageDialog() void HelpMessageDialog::printToConsole() { // On other operating systems, the expected action is to print the message to the console. - fprintf(stdout, "%s\n", qPrintable(text)); + tfm::format(std::cout, "%s\n", qPrintable(text)); } void HelpMessageDialog::showOrPrint() diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index a2b295df21..c1eba61749 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -221,9 +221,7 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact return TransactionCreationFailed; } - // reject absurdly high fee. (This can never happen because the - // wallet caps the fee at m_default_max_tx_fee. This merely serves as a - // belt-and-suspenders check) + // Reject absurdly high fee if (nFeeRequired > m_wallet->getDefaultMaxTxFee()) return AbsurdFee; } diff --git a/src/qt/walletmodeltransaction.cpp b/src/qt/walletmodeltransaction.cpp index 2694d67800..8c0dc276b0 100644 --- a/src/qt/walletmodeltransaction.cpp +++ b/src/qt/walletmodeltransaction.cpp @@ -8,7 +8,6 @@ #include <qt/walletmodeltransaction.h> -#include <interfaces/node.h> #include <policy/policy.h> WalletModelTransaction::WalletModelTransaction(const QList<SendCoinsRecipient> &_recipients) : diff --git a/src/qt/winshutdownmonitor.cpp b/src/qt/winshutdownmonitor.cpp index 08cae76add..b177b22b3f 100644 --- a/src/qt/winshutdownmonitor.cpp +++ b/src/qt/winshutdownmonitor.cpp @@ -63,7 +63,7 @@ void WinShutdownMonitor::registerShutdownBlockReason(const QString& strReason, c } if (shutdownBRCreate(mainWinId, strReason.toStdWString().c_str())) - qWarning() << "registerShutdownBlockReason: Successfully registered: " + strReason; + qInfo() << "registerShutdownBlockReason: Successfully registered: " + strReason; else qWarning() << "registerShutdownBlockReason: Failed to register: " + strReason; } diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index d2d157e785..9f3748cb65 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -6,7 +6,6 @@ #include <rpc/blockchain.h> #include <amount.h> -#include <base58.h> #include <blockfilter.h> #include <chain.h> #include <chainparams.h> @@ -15,7 +14,6 @@ #include <core_io.h> #include <hash.h> #include <index/blockfilterindex.h> -#include <index/txindex.h> #include <key_io.h> #include <policy/feerate.h> #include <policy/policy.h> @@ -1063,7 +1061,12 @@ static UniValue pruneblockchain(const JSONRPCRequest& request) } PruneBlockFilesManual(height); - return uint64_t(height); + const CBlockIndex* block = ::ChainActive().Tip(); + assert(block); + while (block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA)) { + block = block->pprev; + } + return uint64_t(block->nHeight); } static UniValue gettxoutsetinfo(const JSONRPCRequest& request) @@ -2244,41 +2247,12 @@ UniValue scantxoutset(const JSONRPCRequest& request) // loop through the scan objects for (const UniValue& scanobject : request.params[1].get_array().getValues()) { - std::string desc_str; - std::pair<int64_t, int64_t> range = {0, 1000}; - if (scanobject.isStr()) { - desc_str = scanobject.get_str(); - } else if (scanobject.isObject()) { - UniValue desc_uni = find_value(scanobject, "desc"); - if (desc_uni.isNull()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Descriptor needs to be provided in scan object"); - desc_str = desc_uni.get_str(); - UniValue range_uni = find_value(scanobject, "range"); - if (!range_uni.isNull()) { - range = ParseDescriptorRange(range_uni); - } - } else { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Scan object needs to be either a string or an object"); - } - FlatSigningProvider provider; - auto desc = Parse(desc_str, provider); - if (!desc) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Invalid descriptor '%s'", desc_str)); - } - if (!desc->IsRange()) { - range.first = 0; - range.second = 0; - } - for (int i = range.first; i <= range.second; ++i) { - std::vector<CScript> scripts; - if (!desc->Expand(i, provider, scripts, provider)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Cannot derive script without private keys: '%s'", desc_str)); - } - for (const auto& script : scripts) { - std::string inferred = InferDescriptor(script, provider)->ToString(); - needles.emplace(script); - descriptors.emplace(std::move(script), std::move(inferred)); - } + auto scripts = EvalDescriptorStringOrObject(scanobject, provider); + for (const auto& script : scripts) { + std::string inferred = InferDescriptor(script, provider)->ToString(); + needles.emplace(script); + descriptors.emplace(std::move(script), std::move(inferred)); } } diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 4144a17bc3..8f6bdc21aa 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -36,6 +36,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "sendtoaddress", 4, "subtractfeefromamount" }, { "sendtoaddress", 5 , "replaceable" }, { "sendtoaddress", 6 , "conf_target" }, + { "sendtoaddress", 8, "avoid_reuse" }, { "settxfee", 0, "amount" }, { "sethdseed", 0, "newkeypool" }, { "getreceivedbyaddress", 1, "minconf" }, @@ -48,6 +49,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "listreceivedbylabel", 2, "include_watchonly" }, { "getbalance", 1, "minconf" }, { "getbalance", 2, "include_watchonly" }, + { "getbalance", 3, "avoid_reuse" }, { "getblockhash", 0, "height" }, { "waitforblockheight", 0, "height" }, { "waitforblockheight", 1, "timeout" }, @@ -141,6 +143,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "setban", 2, "bantime" }, { "setban", 3, "absolute" }, { "setnetworkactive", 0, "state" }, + { "setwalletflag", 1, "value" }, { "getmempoolancestors", 1, "verbose" }, { "getmempooldescendants", 1, "verbose" }, { "bumpfee", 1, "options" }, @@ -162,6 +165,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "rescanblockchain", 1, "stop_height"}, { "createwallet", 1, "disable_private_keys"}, { "createwallet", 2, "blank"}, + { "createwallet", 4, "avoid_reuse"}, { "getnodeaddresses", 0, "count"}, { "stop", 0, "wait" }, }; diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 477f05f46c..6636a8a29a 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -103,7 +103,6 @@ static UniValue getnetworkhashps(const JSONRPCRequest& request) static UniValue generateBlocks(const CScript& coinbase_script, int nGenerate, uint64_t nMaxTries) { - static const int nInnerLoopCount = 0x10000; int nHeightEnd = 0; int nHeight = 0; @@ -124,14 +123,14 @@ static UniValue generateBlocks(const CScript& coinbase_script, int nGenerate, ui LOCK(cs_main); IncrementExtraNonce(pblock, ::ChainActive().Tip(), nExtraNonce); } - while (nMaxTries > 0 && pblock->nNonce < nInnerLoopCount && !CheckProofOfWork(pblock->GetHash(), pblock->nBits, Params().GetConsensus())) { + while (nMaxTries > 0 && pblock->nNonce < std::numeric_limits<uint32_t>::max() && !CheckProofOfWork(pblock->GetHash(), pblock->nBits, Params().GetConsensus()) && !ShutdownRequested()) { ++pblock->nNonce; --nMaxTries; } - if (nMaxTries == 0) { + if (nMaxTries == 0 || ShutdownRequested()) { break; } - if (pblock->nNonce == nInnerLoopCount) { + if (pblock->nNonce == std::numeric_limits<uint32_t>::max()) { continue; } std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(*pblock); @@ -469,7 +468,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request) nTransactionsUpdatedLastLP = nTransactionsUpdatedLast; } - // Release the wallet and main lock while waiting + // Release lock while waiting LEAVE_CRITICAL_SECTION(cs_main); { checktxtime = std::chrono::steady_clock::now() + std::chrono::minutes(1); @@ -480,6 +479,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request) if (g_best_block_cv.wait_until(lock, checktxtime) == std::cv_status::timeout) { // Timeout: Check transactions for update + // without holding ::mempool.cs to avoid deadlocks if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLastLP) break; checktxtime += std::chrono::seconds(10); diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 72a2919712..7a1bdec7b9 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -3,25 +3,17 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include <chain.h> -#include <clientversion.h> -#include <core_io.h> #include <crypto/ripemd160.h> #include <key_io.h> -#include <validation.h> #include <httpserver.h> -#include <net.h> -#include <netbase.h> #include <outputtype.h> #include <rpc/blockchain.h> #include <rpc/server.h> #include <rpc/util.h> #include <script/descriptor.h> -#include <timedata.h> #include <util/system.h> #include <util/strencodings.h> #include <util/validation.h> -#include <warnings.h> #include <stdint.h> #include <tuple> @@ -130,9 +122,9 @@ static UniValue createmultisig(const JSONRPCRequest& request) } // Construct using pay-to-script-hash: - const CScript inner = CreateMultisigRedeemscript(required, pubkeys); CBasicKeyStore keystore; - const CTxDestination dest = AddAndGetDestinationForScript(keystore, inner, output_type); + CScript inner; + const CTxDestination dest = AddAndGetMultisigDestination(required, pubkeys, output_type, keystore, inner); UniValue result(UniValue::VOBJ); result.pushKV("address", EncodeDestination(dest)); diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index e49c3e031f..d993a88458 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -5,7 +5,6 @@ #include <rpc/server.h> #include <banman.h> -#include <chainparams.h> #include <clientversion.h> #include <core_io.h> #include <net.h> @@ -17,7 +16,6 @@ #include <rpc/util.h> #include <sync.h> #include <timedata.h> -#include <ui_interface.h> #include <util/strencodings.h> #include <util/system.h> #include <validation.h> diff --git a/src/rpc/protocol.cpp b/src/rpc/protocol.cpp index 23999b305a..33b0130a94 100644 --- a/src/rpc/protocol.cpp +++ b/src/rpc/protocol.cpp @@ -10,7 +10,6 @@ #include <util/system.h> #include <util/strencodings.h> #include <util/time.h> -#include <version.h> /** * JSON-RPC protocol. Bitcoin speaks version 1.0 for maximum compatibility, diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index b3926786db..966ff3fedc 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -6,21 +6,16 @@ #include <chain.h> #include <coins.h> #include <compat/byteswap.h> -#include <consensus/tx_verify.h> #include <consensus/validation.h> #include <core_io.h> #include <index/txindex.h> -#include <init.h> -#include <interfaces/chain.h> #include <key_io.h> #include <keystore.h> #include <merkleblock.h> #include <node/coin.h> #include <node/psbt.h> #include <node/transaction.h> -#include <policy/policy.h> #include <policy/rbf.h> -#include <policy/settings.h> #include <primitives/transaction.h> #include <psbt.h> #include <rpc/rawtransaction_util.h> @@ -31,7 +26,6 @@ #include <script/sign.h> #include <script/standard.h> #include <uint256.h> -#include <util/bip32.h> #include <util/moneystr.h> #include <util/strencodings.h> #include <validation.h> @@ -45,7 +39,7 @@ /** High fee for sendrawtransaction and testmempoolaccept. * By default, transaction with a fee higher than this will be rejected by the - * RPCs. This can be overriden with the maxfeerate argument. + * RPCs. This can be overridden with the maxfeerate argument. */ constexpr static CAmount DEFAULT_MAX_RAW_TX_FEE{COIN / 10}; @@ -202,7 +196,7 @@ static UniValue getrawtransaction(const JSONRPCRequest& request) } errmsg = "No such transaction found in the provided block"; } else if (!g_txindex) { - errmsg = "No such mempool transaction. Use -txindex to enable blockchain transaction queries"; + errmsg = "No such mempool transaction. Use -txindex or provide a block hash to enable blockchain transaction queries"; } else if (!f_txindex_ready) { errmsg = "No such mempool transaction. Blockchain transactions are still in the process of being indexed"; } else { @@ -432,14 +426,17 @@ static UniValue createrawtransaction(const JSONRPCRequest& request) static UniValue decoderawtransaction(const JSONRPCRequest& request) { - if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) - throw std::runtime_error( - RPCHelpMan{"decoderawtransaction", + const RPCHelpMan help{"decoderawtransaction", "\nReturn a JSON object representing the serialized, hex-encoded transaction.\n", { {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction hex string"}, - {"iswitness", RPCArg::Type::BOOL, /* default */ "depends on heuristic tests", "Whether the transaction hex is a serialized witness transaction\n" - " If iswitness is not present, heuristic tests will be used in decoding"}, + {"iswitness", RPCArg::Type::BOOL, /* default */ "depends on heuristic tests", "Whether the transaction hex is a serialized witness transaction.\n" + "If iswitness is not present, heuristic tests will be used in decoding.\n" + "If true, only witness deserialization will be tried.\n" + "If false, only non-witness deserialization will be tried.\n" + "This boolean should reflect whether the transaction has inputs\n" + "(e.g. fully valid, or on-chain transactions), if known by the caller." + }, }, RPCResult{ "{\n" @@ -486,7 +483,11 @@ static UniValue decoderawtransaction(const JSONRPCRequest& request) HelpExampleCli("decoderawtransaction", "\"hexstring\"") + HelpExampleRpc("decoderawtransaction", "\"hexstring\"") }, - }.ToString()); + }; + + if (request.fHelp || !help.IsValidNumArgs(request.params.size())) { + throw std::runtime_error(help.ToString()); + } RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL}); @@ -748,8 +749,8 @@ static UniValue signrawtransactionwithkey(const JSONRPCRequest& request) "}\n" }, RPCExamples{ - HelpExampleCli("signrawtransactionwithkey", "\"myhex\"") - + HelpExampleRpc("signrawtransactionwithkey", "\"myhex\"") + HelpExampleCli("signrawtransactionwithkey", "\"myhex\" \"[\\\"key1\\\",\\\"key2\\\"]\"") + + HelpExampleRpc("signrawtransactionwithkey", "\"myhex\", \"[\\\"key1\\\",\\\"key2\\\"]\"") }, }.ToString()); @@ -1423,19 +1424,20 @@ UniValue createpsbt(const JSONRPCRequest& request) UniValue converttopsbt(const JSONRPCRequest& request) { - if (request.fHelp || request.params.size() < 1 || request.params.size() > 3) - throw std::runtime_error( - RPCHelpMan{"converttopsbt", + const RPCHelpMan help{"converttopsbt", "\nConverts a network serialized transaction to a PSBT. This should be used only with createrawtransaction and fundrawtransaction\n" "createpsbt and walletcreatefundedpsbt should be used for new applications.\n", { {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex string of a raw transaction"}, - {"permitsigdata", RPCArg::Type::BOOL, /* default */ "false", "If true, any signatures in the input will be discarded and conversion.\n" + {"permitsigdata", RPCArg::Type::BOOL, /* default */ "false", "If true, any signatures in the input will be discarded and conversion\n" " will continue. If false, RPC will fail if any signatures are present."}, {"iswitness", RPCArg::Type::BOOL, /* default */ "depends on heuristic tests", "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 will be tried. Only has an effect if\n" - " permitsigdata is true."}, + "If iswitness is not present, heuristic tests will be used in decoding.\n" + "If true, only witness deserialization will be tried.\n" + "If false, only non-witness deserialization will be tried.\n" + "This boolean should reflect whether the transaction has inputs\n" + "(e.g. fully valid, or on-chain transactions), if known by the caller." + }, }, RPCResult{ " \"psbt\" (string) The resulting raw transaction (base64-encoded string)\n" @@ -1446,8 +1448,11 @@ UniValue converttopsbt(const JSONRPCRequest& request) "\nConvert the transaction to a PSBT\n" + HelpExampleCli("converttopsbt", "\"rawtransaction\"") }, - }.ToString()); + }; + if (request.fHelp || !help.IsValidNumArgs(request.params.size())) { + throw std::runtime_error(help.ToString()); + } RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL, UniValue::VBOOL}, true); @@ -1456,8 +1461,8 @@ UniValue converttopsbt(const JSONRPCRequest& request) bool permitsigdata = request.params[1].isNull() ? false : request.params[1].get_bool(); bool witness_specified = !request.params[2].isNull(); bool iswitness = witness_specified ? request.params[2].get_bool() : false; - bool try_witness = permitsigdata ? (witness_specified ? iswitness : true) : false; - bool try_no_witness = permitsigdata ? (witness_specified ? !iswitness : true) : true; + const bool try_witness = witness_specified ? iswitness : true; + const bool try_no_witness = witness_specified ? !iswitness : true; if (!DecodeHexTx(tx, request.params[0].get_str(), try_no_witness, try_witness)) { throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); } @@ -1490,12 +1495,19 @@ UniValue converttopsbt(const JSONRPCRequest& request) UniValue utxoupdatepsbt(const JSONRPCRequest& request) { - if (request.fHelp || request.params.size() != 1) { + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) { throw std::runtime_error( RPCHelpMan{"utxoupdatepsbt", - "\nUpdates a PSBT with witness UTXOs retrieved from the UTXO set or the mempool.\n", + "\nUpdates all segwit inputs and outputs in a PSBT with data from output descriptors, the UTXO set or the mempool.\n", { - {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "A base64 string of a PSBT"} + {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "A base64 string of a PSBT"}, + {"descriptors", RPCArg::Type::ARR, RPCArg::Optional::OMITTED_NAMED_ARG, "An array of either strings or objects", { + {"", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "An output descriptor"}, + {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "An object with an output descriptor and extra information", { + {"desc", RPCArg::Type::STR, RPCArg::Optional::NO, "An output descriptor"}, + {"range", RPCArg::Type::RANGE, "1000", "Up to what index HD chains should be explored (either end or [begin,end])"}, + }}, + }}, }, RPCResult { " \"psbt\" (string) The base64-encoded partially signed transaction with inputs updated\n" @@ -1505,7 +1517,7 @@ UniValue utxoupdatepsbt(const JSONRPCRequest& request) }}.ToString()); } - RPCTypeCheck(request.params, {UniValue::VSTR}, true); + RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR}, true); // Unserialize the transactions PartiallySignedTransaction psbtx; @@ -1514,6 +1526,17 @@ UniValue utxoupdatepsbt(const JSONRPCRequest& request) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error)); } + // Parse descriptors, if any. + FlatSigningProvider provider; + if (!request.params[1].isNull()) { + auto descs = request.params[1].get_array(); + for (size_t i = 0; i < descs.size(); ++i) { + EvalDescriptorStringOrObject(descs[i], provider); + } + } + // We don't actually need private keys further on; hide them as a precaution. + HidingSigningProvider public_provider(&provider, /* nosign */ true, /* nobip32derivs */ false); + // Fetch previous transactions (inputs): CCoinsView viewDummy; CCoinsViewCache view(&viewDummy); @@ -1540,11 +1563,19 @@ UniValue utxoupdatepsbt(const JSONRPCRequest& request) const Coin& coin = view.AccessCoin(psbtx.tx->vin[i].prevout); - std::vector<std::vector<unsigned char>> solutions_data; - txnouttype which_type = Solver(coin.out.scriptPubKey, solutions_data); - if (which_type == TX_WITNESS_V0_SCRIPTHASH || which_type == TX_WITNESS_V0_KEYHASH || which_type == TX_WITNESS_UNKNOWN) { + if (IsSegWitOutput(provider, coin.out.scriptPubKey)) { input.witness_utxo = coin.out; } + + // Update script/keypath information using descriptor data. + // Note that SignPSBTInput does a lot more than just constructing ECDSA signatures + // we don't actually care about those here, in fact. + SignPSBTInput(public_provider, psbtx, i, /* sighash_type */ 1); + } + + // Update script/keypath information using descriptor data. + for (unsigned int i = 0; i < psbtx.tx->vout.size(); ++i) { + UpdatePSBTOutput(public_provider, psbtx, i); } CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); diff --git a/src/rpc/rawtransaction_util.cpp b/src/rpc/rawtransaction_util.cpp index 8af491977c..14fcb628eb 100644 --- a/src/rpc/rawtransaction_util.cpp +++ b/src/rpc/rawtransaction_util.cpp @@ -7,7 +7,6 @@ #include <coins.h> #include <core_io.h> -#include <interfaces/chain.h> #include <key_io.h> #include <keystore.h> #include <policy/policy.h> @@ -222,6 +221,9 @@ UniValue SignTransaction(CMutableTransaction& mtx, const UniValue& prevTxsUnival // Automatically also add the P2WSH wrapped version of the script (to deal with P2SH-P2WSH). keystore->AddCScript(GetScriptForWitness(witnessScript)); } + if (rs.isNull() && ws.isNull()) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Missing redeemScript/witnessScript"); + } } } } diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 9df4070cbb..ca17d379bc 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -7,11 +7,9 @@ #include <fs.h> #include <key_io.h> -#include <random.h> #include <rpc/util.h> #include <shutdown.h> #include <sync.h> -#include <ui_interface.h> #include <util/strencodings.h> #include <util/system.h> diff --git a/src/rpc/util.cpp b/src/rpc/util.cpp index 9cdb22001f..67ccb225b5 100644 --- a/src/rpc/util.cpp +++ b/src/rpc/util.cpp @@ -4,7 +4,9 @@ #include <key_io.h> #include <keystore.h> +#include <outputtype.h> #include <rpc/util.h> +#include <script/descriptor.h> #include <tinyformat.h> #include <util/strencodings.h> @@ -150,8 +152,8 @@ CPubKey AddrToPubKey(CKeyStore* const keystore, const std::string& addr_in) return vchPubKey; } -// Creates a multisig redeemscript from a given list of public keys and number required. -CScript CreateMultisigRedeemscript(const int required, const std::vector<CPubKey>& pubkeys) +// Creates a multisig address from a given list of public keys, number of signatures required, and the address type +CTxDestination AddAndGetMultisigDestination(const int required, const std::vector<CPubKey>& pubkeys, OutputType type, CKeyStore& keystore, CScript& script_out) { // Gather public keys if (required < 1) { @@ -164,13 +166,24 @@ CScript CreateMultisigRedeemscript(const int required, const std::vector<CPubKey throw JSONRPCError(RPC_INVALID_PARAMETER, "Number of keys involved in the multisignature address creation > 16\nReduce the number"); } - CScript result = GetScriptForMultisig(required, pubkeys); + script_out = GetScriptForMultisig(required, pubkeys); - if (result.size() > MAX_SCRIPT_ELEMENT_SIZE) { - throw JSONRPCError(RPC_INVALID_PARAMETER, (strprintf("redeemScript exceeds size limit: %d > %d", result.size(), MAX_SCRIPT_ELEMENT_SIZE))); + if (script_out.size() > MAX_SCRIPT_ELEMENT_SIZE) { + throw JSONRPCError(RPC_INVALID_PARAMETER, (strprintf("redeemScript exceeds size limit: %d > %d", script_out.size(), MAX_SCRIPT_ELEMENT_SIZE))); } - return result; + // Check if any keys are uncompressed. If so, the type is legacy + for (const CPubKey& pk : pubkeys) { + if (!pk.IsCompressed()) { + type = OutputType::LEGACY; + break; + } + } + + // Make the address + CTxDestination dest = AddAndGetDestinationForScript(keystore, script_out, type); + + return dest; } class DescribeAddressVisitor : public boost::static_visitor<UniValue> @@ -685,3 +698,40 @@ std::pair<int64_t, int64_t> ParseDescriptorRange(const UniValue& value) } return {low, high}; } + +std::vector<CScript> EvalDescriptorStringOrObject(const UniValue& scanobject, FlatSigningProvider& provider) +{ + std::string desc_str; + std::pair<int64_t, int64_t> range = {0, 1000}; + if (scanobject.isStr()) { + desc_str = scanobject.get_str(); + } else if (scanobject.isObject()) { + UniValue desc_uni = find_value(scanobject, "desc"); + if (desc_uni.isNull()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Descriptor needs to be provided in scan object"); + desc_str = desc_uni.get_str(); + UniValue range_uni = find_value(scanobject, "range"); + if (!range_uni.isNull()) { + range = ParseDescriptorRange(range_uni); + } + } else { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Scan object needs to be either a string or an object"); + } + + auto desc = Parse(desc_str, provider); + if (!desc) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Invalid descriptor '%s'", desc_str)); + } + if (!desc->IsRange()) { + range.first = 0; + range.second = 0; + } + std::vector<CScript> ret; + for (int i = range.first; i <= range.second; ++i) { + std::vector<CScript> scripts; + if (!desc->Expand(i, provider, scripts, provider)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Cannot derive script without private keys: '%s'", desc_str)); + } + std::move(scripts.begin(), scripts.end(), std::back_inserter(ret)); + } + return ret; +} diff --git a/src/rpc/util.h b/src/rpc/util.h index e4fa8fc3d7..8762281d73 100644 --- a/src/rpc/util.h +++ b/src/rpc/util.h @@ -6,8 +6,11 @@ #define BITCOIN_RPC_UTIL_H #include <node/transaction.h> +#include <outputtype.h> #include <pubkey.h> #include <rpc/protocol.h> +#include <script/script.h> +#include <script/sign.h> #include <script/standard.h> #include <univalue.h> @@ -70,7 +73,7 @@ extern std::string HelpExampleRpc(const std::string& methodname, const std::stri CPubKey HexToPubKey(const std::string& hex_in); CPubKey AddrToPubKey(CKeyStore* const keystore, const std::string& addr_in); -CScript CreateMultisigRedeemscript(const int required, const std::vector<CPubKey>& pubkeys); +CTxDestination AddAndGetMultisigDestination(const int required, const std::vector<CPubKey>& pubkeys, OutputType type, CKeyStore& keystore, CScript& script_out); UniValue DescribeAddress(const CTxDestination& dest); @@ -83,6 +86,9 @@ UniValue JSONRPCTransactionError(TransactionError terr, const std::string& err_s //! Parse a JSON range specified as int64, or [int64, int64] std::pair<int64_t, int64_t> ParseDescriptorRange(const UniValue& value); +/** Evaluate a descriptor given as a string, or as a {"desc":...,"range":...} object, with default range of 1000. */ +std::vector<CScript> EvalDescriptorStringOrObject(const UniValue& scanobject, FlatSigningProvider& provider); + struct RPCArg { enum class Type { OBJ, diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp index 9be87fabb0..50119ba184 100644 --- a/src/script/descriptor.cpp +++ b/src/script/descriptor.cpp @@ -164,6 +164,9 @@ struct PubkeyProvider /** Get the descriptor string form including private data (if available in arg). */ virtual bool ToPrivateString(const SigningProvider& arg, std::string& out) const = 0; + + /** Derive a private key, if private data is available in arg. */ + virtual bool GetPrivKey(int pos, const SigningProvider& arg, CKey& key) const = 0; }; class OriginPubkeyProvider final : public PubkeyProvider @@ -195,6 +198,10 @@ public: ret = "[" + OriginString() + "]" + std::move(sub); return true; } + bool GetPrivKey(int pos, const SigningProvider& arg, CKey& key) const override + { + return m_provider->GetPrivKey(pos, arg, key); + } }; /** An object representing a parsed constant public key in a descriptor. */ @@ -222,6 +229,10 @@ public: ret = EncodeSecret(key); return true; } + bool GetPrivKey(int pos, const SigningProvider& arg, CKey& key) const override + { + return arg.GetKey(m_pubkey.GetID(), key); + } }; enum class DeriveType { @@ -266,14 +277,9 @@ public: { if (key) { if (IsHardened()) { - CExtKey extkey; - if (!GetExtKey(arg, extkey)) return false; - for (auto entry : m_path) { - extkey.Derive(extkey, entry); - } - if (m_derive == DeriveType::UNHARDENED) extkey.Derive(extkey, pos); - if (m_derive == DeriveType::HARDENED) extkey.Derive(extkey, pos | 0x80000000UL); - *key = extkey.Neuter().pubkey; + CKey priv_key; + if (!GetPrivKey(pos, arg, priv_key)) return false; + *key = priv_key.GetPubKey(); } else { // TODO: optimize by caching CExtPubKey extkey = m_extkey; @@ -312,6 +318,18 @@ public: } return true; } + bool GetPrivKey(int pos, const SigningProvider& arg, CKey& key) const override + { + CExtKey extkey; + if (!GetExtKey(arg, extkey)) return false; + for (auto entry : m_path) { + extkey.Derive(extkey, entry); + } + if (m_derive == DeriveType::UNHARDENED) extkey.Derive(extkey, pos); + if (m_derive == DeriveType::HARDENED) extkey.Derive(extkey, pos | 0x80000000UL); + key = extkey.key; + return true; + } }; /** Base class for all Descriptor implementations. */ @@ -462,6 +480,20 @@ public: Span<const unsigned char> span = MakeSpan(cache); return ExpandHelper(pos, DUMMY_SIGNING_PROVIDER, &span, output_scripts, out, nullptr) && span.size() == 0; } + + void ExpandPrivate(int pos, const SigningProvider& provider, FlatSigningProvider& out) const final + { + for (const auto& p : m_pubkey_args) { + CKey key; + if (!p->GetPrivKey(pos, provider, key)) continue; + out.keys.emplace(key.GetPubKey().GetID(), key); + } + if (m_script_arg) { + FlatSigningProvider subprovider; + m_script_arg->ExpandPrivate(pos, provider, subprovider); + out = Merge(out, subprovider); + } + } }; /** Construct a vector with one element, which is moved into it. */ diff --git a/src/script/descriptor.h b/src/script/descriptor.h index 907a102284..af7ae229ca 100644 --- a/src/script/descriptor.h +++ b/src/script/descriptor.h @@ -60,6 +60,14 @@ struct Descriptor { * out: scripts and public keys necessary for solving the expanded scriptPubKeys will be put here (may be equal to provider). */ virtual bool ExpandFromCache(int pos, const std::vector<unsigned char>& cache, std::vector<CScript>& output_scripts, FlatSigningProvider& out) const = 0; + + /** Expand the private key for a descriptor at a specified position, if possible. + * + * pos: the position at which to expand the descriptor. If IsRange() is false, this is ignored. + * provider: the provider to query for the private keys. + * out: any private keys available for the specified pos will be placed here. + */ + virtual void ExpandPrivate(int pos, const SigningProvider& provider, FlatSigningProvider& out) const = 0; }; /** Parse a descriptor string. Included private keys are put in out. diff --git a/src/script/script.cpp b/src/script/script.cpp index 982aa241e7..0666a385d1 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -5,7 +5,6 @@ #include <script/script.h> -#include <tinyformat.h> #include <util/strencodings.h> const char* GetOpName(opcodetype opcode) diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp index 94005cf6f3..eaf5363bd7 100644 --- a/src/script/sigcache.cpp +++ b/src/script/sigcache.cpp @@ -5,7 +5,6 @@ #include <script/sigcache.h> -#include <memusage.h> #include <pubkey.h> #include <random.h> #include <uint256.h> diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 36dd68a3d8..5320dc0876 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -505,3 +505,19 @@ FlatSigningProvider Merge(const FlatSigningProvider& a, const FlatSigningProvide ret.origins.insert(b.origins.begin(), b.origins.end()); return ret; } + +bool IsSegWitOutput(const SigningProvider& provider, const CScript& script) +{ + std::vector<valtype> solutions; + auto whichtype = Solver(script, solutions); + if (whichtype == TX_WITNESS_V0_SCRIPTHASH || whichtype == TX_WITNESS_V0_KEYHASH || whichtype == TX_WITNESS_UNKNOWN) return true; + if (whichtype == TX_SCRIPTHASH) { + auto h160 = uint160(solutions[0]); + CScript subscript; + if (provider.GetCScript(h160, subscript)) { + whichtype = Solver(subscript, solutions); + if (whichtype == TX_WITNESS_V0_SCRIPTHASH || whichtype == TX_WITNESS_V0_KEYHASH || whichtype == TX_WITNESS_UNKNOWN) return true; + } + } + return false; +} diff --git a/src/script/sign.h b/src/script/sign.h index f746325b90..e5c0329a61 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -232,4 +232,7 @@ void UpdateInput(CTxIn& input, const SignatureData& data); * Solvability is unrelated to whether we consider this output to be ours. */ bool IsSolvable(const SigningProvider& provider, const CScript& script); +/** Check whether a scriptPubKey is known to be segwit. */ +bool IsSegWitOutput(const SigningProvider& provider, const CScript& script); + #endif // BITCOIN_SCRIPT_SIGN_H diff --git a/src/script/standard.cpp b/src/script/standard.cpp index 91a301bcdf..b7d6cd925c 100644 --- a/src/script/standard.cpp +++ b/src/script/standard.cpp @@ -8,8 +8,6 @@ #include <crypto/sha256.h> #include <pubkey.h> #include <script/script.h> -#include <util/system.h> -#include <util/strencodings.h> typedef std::vector<unsigned char> valtype; diff --git a/src/serialize.h b/src/serialize.h index b001ee1324..1dc27d84eb 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -670,7 +670,7 @@ void Unserialize_impl(Stream& is, prevector<N, T>& v, const unsigned char&) while (i < nSize) { unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T))); - v.resize(i + blk); + v.resize_uninitialized(i + blk); is.read((char*)&v[i], blk * sizeof(T)); i += blk; } @@ -688,8 +688,8 @@ void Unserialize_impl(Stream& is, prevector<N, T>& v, const V&) nMid += 5000000 / sizeof(T); if (nMid > nSize) nMid = nSize; - v.resize(nMid); - for (; i < nMid; i++) + v.resize_uninitialized(nMid); + for (; i < nMid; ++i) Unserialize(is, v[i]); } } diff --git a/src/sync.cpp b/src/sync.cpp index c2767b200a..20258d8e9a 100644 --- a/src/sync.cpp +++ b/src/sync.cpp @@ -57,7 +57,7 @@ struct CLockLocation { std::string ToString() const { - return tfm::format( + return strprintf( "%s %s:%s%s (in thread %s)", mutexName, sourceFile, itostr(sourceLine), (fTry ? " (TRY)" : ""), m_thread_name); } @@ -118,7 +118,7 @@ static void potential_deadlock_detected(const std::pair<void*, void*>& mismatch, LogPrintf(" %s\n", i.second.ToString()); } if (g_debug_lockorder_abort) { - fprintf(stderr, "Assertion failed: detected inconsistent lock order at %s:%i, details in debug log.\n", __FILE__, __LINE__); + tfm::format(std::cerr, "Assertion failed: detected inconsistent lock order at %s:%i, details in debug log.\n", __FILE__, __LINE__); abort(); } throw std::logic_error("potential deadlock detected"); @@ -175,7 +175,7 @@ void AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, for (const std::pair<void*, CLockLocation>& i : g_lockstack) if (i.first == cs) return; - fprintf(stderr, "Assertion failed: lock %s not held in %s:%i; locks held:\n%s", pszName, pszFile, nLine, LocksHeld().c_str()); + tfm::format(std::cerr, "Assertion failed: lock %s not held in %s:%i; locks held:\n%s", pszName, pszFile, nLine, LocksHeld().c_str()); abort(); } @@ -183,7 +183,7 @@ void AssertLockNotHeldInternal(const char* pszName, const char* pszFile, int nLi { for (const std::pair<void*, CLockLocation>& i : g_lockstack) { if (i.first == cs) { - fprintf(stderr, "Assertion failed: lock %s held in %s:%i; locks held:\n%s", pszName, pszFile, nLine, LocksHeld().c_str()); + tfm::format(std::cerr, "Assertion failed: lock %s held in %s:%i; locks held:\n%s", pszName, pszFile, nLine, LocksHeld().c_str()); abort(); } } diff --git a/src/test/allocator_tests.cpp b/src/test/allocator_tests.cpp index f255691704..e333763f27 100644 --- a/src/test/allocator_tests.cpp +++ b/src/test/allocator_tests.cpp @@ -2,9 +2,9 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <util/memory.h> #include <util/system.h> -#include <support/allocators/secure.h> #include <test/setup_common.h> #include <memory> diff --git a/src/test/arith_uint256_tests.cpp b/src/test/arith_uint256_tests.cpp index 809c627d27..9ac87261b6 100644 --- a/src/test/arith_uint256_tests.cpp +++ b/src/test/arith_uint256_tests.cpp @@ -11,7 +11,6 @@ #include <uint256.h> #include <arith_uint256.h> #include <string> -#include <version.h> #include <test/setup_common.h> BOOST_FIXTURE_TEST_SUITE(arith_uint256_tests, BasicTestingSetup) diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp index 0c0423c0db..662878750e 100644 --- a/src/test/bip32_tests.cpp +++ b/src/test/bip32_tests.cpp @@ -4,9 +4,10 @@ #include <boost/test/unit_test.hpp> +#include <clientversion.h> #include <key.h> #include <key_io.h> -#include <uint256.h> +#include <streams.h> #include <util/system.h> #include <util/strencodings.h> #include <test/setup_common.h> diff --git a/src/test/blockchain_tests.cpp b/src/test/blockchain_tests.cpp index 13afcca375..ca75563ef0 100644 --- a/src/test/blockchain_tests.cpp +++ b/src/test/blockchain_tests.cpp @@ -2,6 +2,7 @@ #include <stdlib.h> +#include <chain.h> #include <rpc/blockchain.h> #include <test/setup_common.h> diff --git a/src/test/blockencodings_tests.cpp b/src/test/blockencodings_tests.cpp index f57e1a0ebd..dac201a35f 100644 --- a/src/test/blockencodings_tests.cpp +++ b/src/test/blockencodings_tests.cpp @@ -6,7 +6,7 @@ #include <consensus/merkle.h> #include <chainparams.h> #include <pow.h> -#include <random.h> +#include <streams.h> #include <test/setup_common.h> diff --git a/src/test/blockfilter_index_tests.cpp b/src/test/blockfilter_index_tests.cpp index 7ba483173c..cf87aa9303 100644 --- a/src/test/blockfilter_index_tests.cpp +++ b/src/test/blockfilter_index_tests.cpp @@ -10,6 +10,7 @@ #include <pow.h> #include <test/setup_common.h> #include <script/standard.h> +#include <util/time.h> #include <validation.h> #include <boost/test/unit_test.hpp> @@ -267,8 +268,6 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, TestChain100Setup) BOOST_FIXTURE_TEST_CASE(blockfilter_index_init_destroy, BasicTestingSetup) { - SetDataDir("tempdir"); - BlockFilterIndex* filter_index; filter_index = GetBlockFilterIndex(BlockFilterType::BASIC); diff --git a/src/test/checkqueue_tests.cpp b/src/test/checkqueue_tests.cpp index 408a7fbda4..d796444419 100644 --- a/src/test/checkqueue_tests.cpp +++ b/src/test/checkqueue_tests.cpp @@ -2,6 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <util/memory.h> #include <util/system.h> #include <util/time.h> #include <validation.h> @@ -17,8 +18,6 @@ #include <condition_variable> #include <unordered_set> -#include <memory> -#include <random.h> // BasicTestingSetup not sufficient because nScriptCheckThreads is not set // otherwise. diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index 665975ca67..948591196c 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -3,14 +3,14 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <attributes.h> +#include <clientversion.h> #include <coins.h> -#include <consensus/validation.h> #include <script/standard.h> +#include <streams.h> #include <test/setup_common.h> #include <uint256.h> #include <undo.h> #include <util/strencodings.h> -#include <validation.h> #include <map> #include <vector> @@ -280,6 +280,7 @@ UtxoData::iterator FindRandomFrom(const std::set<COutPoint> &utxoSet) { BOOST_AUTO_TEST_CASE(updatecoins_simulation_test) { SeedInsecureRand(/* deterministic */ true); + g_mock_deterministic_tests = true; bool spent_a_duplicate_coinbase = false; // A simple map to track what we expect the cache stack to represent. @@ -474,6 +475,8 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test) // Verify coverage. BOOST_CHECK(spent_a_duplicate_coinbase); + + g_mock_deterministic_tests = false; } BOOST_AUTO_TEST_CASE(ccoins_serialization) diff --git a/src/test/compilerbug_tests.cpp b/src/test/compilerbug_tests.cpp new file mode 100644 index 0000000000..74e1eac3ea --- /dev/null +++ b/src/test/compilerbug_tests.cpp @@ -0,0 +1,43 @@ +// Copyright (c) 2019 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 <test/setup_common.h> +#include <boost/test/unit_test.hpp> + +BOOST_FIXTURE_TEST_SUITE(compilerbug_tests, BasicTestingSetup) + +#if defined(__GNUC__) +// This block will also be built under clang, which is fine (as it supports noinline) +void __attribute__ ((noinline)) set_one(unsigned char* ptr) +{ + *ptr = 1; +} + +int __attribute__ ((noinline)) check_zero(unsigned char const* in, unsigned int len) +{ + for (unsigned int i = 0; i < len; ++i) { + if (in[i] != 0) return 0; + } + return 1; +} + +void set_one_on_stack() { + unsigned char buf[1]; + set_one(buf); +} + +BOOST_AUTO_TEST_CASE(gccbug_90348) { + // Test for GCC bug 90348. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90348 + for (int i = 0; i <= 4; ++i) { + unsigned char in[4]; + for (int j = 0; j < i; ++j) { + in[j] = 0; + set_one_on_stack(); // Apparently modifies in[0] + } + BOOST_CHECK(check_zero(in, i)); + } +} +#endif + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/crypto_tests.cpp b/src/test/crypto_tests.cpp index 35911e507f..4e2acca4c3 100644 --- a/src/test/crypto_tests.cpp +++ b/src/test/crypto_tests.cpp @@ -567,7 +567,7 @@ BOOST_AUTO_TEST_CASE(poly1305_testvector) BOOST_AUTO_TEST_CASE(hkdf_hmac_sha256_l32_tests) { - // Use rfc5869 test vectors but trucated to 32 bytes (our implementation only support length 32) + // Use rfc5869 test vectors but truncated to 32 bytes (our implementation only support length 32) TestHKDF_SHA256_32( /* IKM */ "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", /* salt */ "000102030405060708090a0b0c", diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp index 0bde92c18d..efcadd51fc 100644 --- a/src/test/dbwrapper_tests.cpp +++ b/src/test/dbwrapper_tests.cpp @@ -4,8 +4,8 @@ #include <dbwrapper.h> #include <uint256.h> -#include <random.h> #include <test/setup_common.h> +#include <util/memory.h> #include <memory> @@ -27,7 +27,7 @@ BOOST_AUTO_TEST_CASE(dbwrapper) { // Perform tests both obfuscated and non-obfuscated. for (const bool obfuscate : {false, true}) { - fs::path ph = SetDataDir(std::string("dbwrapper").append(obfuscate ? "_true" : "_false")); + fs::path ph = GetDataDir() / (obfuscate ? "dbwrapper_obfuscate_true" : "dbwrapper_obfuscate_false"); CDBWrapper dbw(ph, (1 << 20), true, false, obfuscate); char key = 'k'; uint256 in = InsecureRand256(); @@ -47,7 +47,7 @@ BOOST_AUTO_TEST_CASE(dbwrapper_batch) { // Perform tests both obfuscated and non-obfuscated. for (const bool obfuscate : {false, true}) { - fs::path ph = SetDataDir(std::string("dbwrapper_batch").append(obfuscate ? "_true" : "_false")); + fs::path ph = GetDataDir() / (obfuscate ? "dbwrapper_batch_obfuscate_true" : "dbwrapper_batch_obfuscate_false"); CDBWrapper dbw(ph, (1 << 20), true, false, obfuscate); char key = 'i'; @@ -83,7 +83,7 @@ BOOST_AUTO_TEST_CASE(dbwrapper_iterator) { // Perform tests both obfuscated and non-obfuscated. for (const bool obfuscate : {false, true}) { - fs::path ph = SetDataDir(std::string("dbwrapper_iterator").append(obfuscate ? "_true" : "_false")); + fs::path ph = GetDataDir() / (obfuscate ? "dbwrapper_iterator_obfuscate_true" : "dbwrapper_iterator_obfuscate_false"); CDBWrapper dbw(ph, (1 << 20), true, false, obfuscate); // The two keys are intentionally chosen for ordering @@ -123,7 +123,7 @@ BOOST_AUTO_TEST_CASE(dbwrapper_iterator) BOOST_AUTO_TEST_CASE(existing_data_no_obfuscate) { // We're going to share this fs::path between two wrappers - fs::path ph = SetDataDir("existing_data_no_obfuscate"); + fs::path ph = GetDataDir() / "existing_data_no_obfuscate"; create_directories(ph); // Set up a non-obfuscated wrapper to write some initial data. @@ -164,7 +164,7 @@ BOOST_AUTO_TEST_CASE(existing_data_no_obfuscate) BOOST_AUTO_TEST_CASE(existing_data_reindex) { // We're going to share this fs::path between two wrappers - fs::path ph = SetDataDir("existing_data_reindex"); + fs::path ph = GetDataDir() / "existing_data_reindex"; create_directories(ph); // Set up a non-obfuscated wrapper to write some initial data. @@ -199,7 +199,7 @@ BOOST_AUTO_TEST_CASE(existing_data_reindex) BOOST_AUTO_TEST_CASE(iterator_ordering) { - fs::path ph = SetDataDir("iterator_ordering"); + fs::path ph = GetDataDir() / "iterator_ordering"; CDBWrapper dbw(ph, (1 << 20), true, false, false); for (int x=0x00; x<256; ++x) { uint8_t key = x; @@ -277,7 +277,7 @@ BOOST_AUTO_TEST_CASE(iterator_string_ordering) { char buf[10]; - fs::path ph = SetDataDir("iterator_string_ordering"); + fs::path ph = GetDataDir() / "iterator_string_ordering"; CDBWrapper dbw(ph, (1 << 20), true, false, false); for (int x=0x00; x<10; ++x) { for (int y = 0; y < 10; y++) { diff --git a/src/test/denialofservice_tests.cpp b/src/test/denialofservice_tests.cpp index d47f395c15..93883d1d98 100644 --- a/src/test/denialofservice_tests.cpp +++ b/src/test/denialofservice_tests.cpp @@ -9,10 +9,11 @@ #include <keystore.h> #include <net.h> #include <net_processing.h> -#include <pow.h> #include <script/sign.h> #include <serialize.h> +#include <util/memory.h> #include <util/system.h> +#include <util/time.h> #include <validation.h> #include <test/setup_common.h> diff --git a/src/test/flatfile_tests.cpp b/src/test/flatfile_tests.cpp index 1db2f8054c..740d805cce 100644 --- a/src/test/flatfile_tests.cpp +++ b/src/test/flatfile_tests.cpp @@ -2,8 +2,11 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <clientversion.h> #include <flatfile.h> +#include <streams.h> #include <test/setup_common.h> +#include <util/system.h> #include <boost/test/unit_test.hpp> @@ -11,7 +14,7 @@ BOOST_FIXTURE_TEST_SUITE(flatfile_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(flatfile_filename) { - auto data_dir = SetDataDir("flatfile_test"); + const auto data_dir = GetDataDir(); FlatFilePos pos(456, 789); @@ -24,7 +27,7 @@ BOOST_AUTO_TEST_CASE(flatfile_filename) BOOST_AUTO_TEST_CASE(flatfile_open) { - auto data_dir = SetDataDir("flatfile_test"); + const auto data_dir = GetDataDir(); FlatFileSeq seq(data_dir, "a", 16 * 1024); std::string line1("A purely peer-to-peer version of electronic cash would allow online " @@ -85,7 +88,7 @@ BOOST_AUTO_TEST_CASE(flatfile_open) BOOST_AUTO_TEST_CASE(flatfile_allocate) { - auto data_dir = SetDataDir("flatfile_test"); + const auto data_dir = GetDataDir(); FlatFileSeq seq(data_dir, "a", 100); bool out_of_space; @@ -105,7 +108,7 @@ BOOST_AUTO_TEST_CASE(flatfile_allocate) BOOST_AUTO_TEST_CASE(flatfile_flush) { - auto data_dir = SetDataDir("flatfile_test"); + const auto data_dir = GetDataDir(); FlatFileSeq seq(data_dir, "a", 100); bool out_of_space; diff --git a/src/test/fs_tests.cpp b/src/test/fs_tests.cpp index 6bd6bb1be3..6d5a6641f0 100644 --- a/src/test/fs_tests.cpp +++ b/src/test/fs_tests.cpp @@ -4,6 +4,7 @@ // #include <fs.h> #include <test/setup_common.h> +#include <util/system.h> #include <boost/test/unit_test.hpp> @@ -11,7 +12,7 @@ BOOST_FIXTURE_TEST_SUITE(fs_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(fsbridge_fstream) { - fs::path tmpfolder = SetDataDir("fsbridge_fstream"); + fs::path tmpfolder = GetDataDir(); // tmpfile1 should be the same as tmpfile2 fs::path tmpfile1 = tmpfolder / "fs_tests_₿_🏃"; fs::path tmpfile2 = tmpfolder / L"fs_tests_₿_🏃"; diff --git a/src/test/fuzz/deserialize.cpp b/src/test/fuzz/deserialize.cpp index 97d7633715..9364ac4a32 100644 --- a/src/test/fuzz/deserialize.cpp +++ b/src/test/fuzz/deserialize.cpp @@ -2,6 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <addrdb.h> #include <addrman.h> #include <blockencodings.h> #include <chain.h> @@ -11,8 +12,6 @@ #include <net.h> #include <primitives/block.h> #include <protocol.h> -#include <pubkey.h> -#include <script/script.h> #include <streams.h> #include <undo.h> #include <version.h> @@ -20,8 +19,6 @@ #include <stdint.h> #include <unistd.h> -#include <algorithm> -#include <memory> #include <vector> #include <test/fuzz/fuzz.h> diff --git a/src/test/fuzz/fuzz.h b/src/test/fuzz/fuzz.h index 8b03a7e46e..4e009d9b54 100644 --- a/src/test/fuzz/fuzz.h +++ b/src/test/fuzz/fuzz.h @@ -5,7 +5,6 @@ #ifndef BITCOIN_TEST_FUZZ_FUZZ_H #define BITCOIN_TEST_FUZZ_FUZZ_H -#include <functional> #include <stdint.h> #include <vector> diff --git a/src/test/fuzz/script_flags.cpp b/src/test/fuzz/script_flags.cpp index 2c0bfa360c..9b90d66755 100644 --- a/src/test/fuzz/script_flags.cpp +++ b/src/test/fuzz/script_flags.cpp @@ -3,7 +3,6 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <script/interpreter.h> -#include <script/script.h> #include <streams.h> #include <version.h> diff --git a/src/test/hash_tests.cpp b/src/test/hash_tests.cpp index 325b7002f2..d91fcb0034 100644 --- a/src/test/hash_tests.cpp +++ b/src/test/hash_tests.cpp @@ -2,13 +2,12 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <clientversion.h> #include <crypto/siphash.h> #include <hash.h> #include <util/strencodings.h> #include <test/setup_common.h> -#include <vector> - #include <boost/test/unit_test.hpp> BOOST_FIXTURE_TEST_SUITE(hash_tests, BasicTestingSetup) diff --git a/src/test/key_properties.cpp b/src/test/key_properties.cpp index 8b508ed7f7..abcfc4547b 100644 --- a/src/test/key_properties.cpp +++ b/src/test/key_properties.cpp @@ -3,13 +3,9 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <key.h> -#include <base58.h> -#include <script/script.h> #include <uint256.h> #include <util/system.h> -#include <util/strencodings.h> #include <test/setup_common.h> -#include <string> #include <vector> #include <boost/test/unit_test.hpp> diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp index 1b95105eab..3e99dcaa40 100644 --- a/src/test/key_tests.cpp +++ b/src/test/key_tests.cpp @@ -5,7 +5,6 @@ #include <key.h> #include <key_io.h> -#include <script/script.h> #include <uint256.h> #include <util/system.h> #include <util/strencodings.h> diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp index 0f74b379c0..c6a3de2285 100644 --- a/src/test/mempool_tests.cpp +++ b/src/test/mempool_tests.cpp @@ -5,11 +5,11 @@ #include <policy/policy.h> #include <txmempool.h> #include <util/system.h> +#include <util/time.h> #include <test/setup_common.h> #include <boost/test/unit_test.hpp> -#include <list> #include <vector> BOOST_FIXTURE_TEST_SUITE(mempool_tests, TestingSetup) diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 4321d7d16e..4bd40687a6 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -7,15 +7,14 @@ #include <consensus/consensus.h> #include <consensus/merkle.h> #include <consensus/tx_verify.h> -#include <consensus/validation.h> #include <miner.h> #include <policy/policy.h> -#include <pubkey.h> #include <script/standard.h> #include <txmempool.h> #include <uint256.h> #include <util/strencodings.h> #include <util/system.h> +#include <util/time.h> #include <validation.h> #include <test/setup_common.h> diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp index 682f1bee26..11e79937be 100644 --- a/src/test/multisig_tests.cpp +++ b/src/test/multisig_tests.cpp @@ -9,7 +9,7 @@ #include <script/script_error.h> #include <script/interpreter.h> #include <script/sign.h> -#include <script/ismine.h> +#include <tinyformat.h> #include <uint256.h> #include <test/setup_common.h> diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp index 54d18c0a1c..fed65afdbf 100644 --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -1,16 +1,19 @@ // Copyright (c) 2012-2019 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 <addrdb.h> #include <addrman.h> +#include <clientversion.h> #include <test/setup_common.h> #include <string> #include <boost/test/unit_test.hpp> -#include <hash.h> #include <serialize.h> #include <streams.h> #include <net.h> #include <netbase.h> #include <chainparams.h> +#include <util/memory.h> #include <util/system.h> #include <memory> @@ -89,7 +92,6 @@ BOOST_AUTO_TEST_CASE(cnode_listen_port) BOOST_AUTO_TEST_CASE(caddrdb_read) { - SetDataDir("caddrdb_read"); CAddrManUncorrupted addrmanUncorrupted; addrmanUncorrupted.MakeDeterministic(); @@ -135,7 +137,6 @@ BOOST_AUTO_TEST_CASE(caddrdb_read) BOOST_AUTO_TEST_CASE(caddrdb_read_corrupted) { - SetDataDir("caddrdb_read_corrupted"); CAddrManCorrupted addrmanCorrupted; addrmanCorrupted.MakeDeterministic(); diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp index dd5e3eb6d5..86c0cecbf1 100644 --- a/src/test/netbase_tests.cpp +++ b/src/test/netbase_tests.cpp @@ -59,6 +59,7 @@ BOOST_AUTO_TEST_CASE(netbase_properties) BOOST_CHECK(ResolveIP("FC00::").IsRFC4193()); BOOST_CHECK(ResolveIP("2001::2").IsRFC4380()); BOOST_CHECK(ResolveIP("2001:10::").IsRFC4843()); + BOOST_CHECK(ResolveIP("2001:20::").IsRFC7343()); BOOST_CHECK(ResolveIP("FE80::").IsRFC4862()); BOOST_CHECK(ResolveIP("64:FF9B::").IsRFC6052()); BOOST_CHECK(ResolveIP("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").IsTor()); diff --git a/src/test/policyestimator_tests.cpp b/src/test/policyestimator_tests.cpp index 149094fc00..016a4f471b 100644 --- a/src/test/policyestimator_tests.cpp +++ b/src/test/policyestimator_tests.cpp @@ -7,6 +7,7 @@ #include <txmempool.h> #include <uint256.h> #include <util/system.h> +#include <util/time.h> #include <test/setup_common.h> diff --git a/src/test/pow_tests.cpp b/src/test/pow_tests.cpp index 653433bfce..1123d4202c 100644 --- a/src/test/pow_tests.cpp +++ b/src/test/pow_tests.cpp @@ -5,7 +5,6 @@ #include <chain.h> #include <chainparams.h> #include <pow.h> -#include <random.h> #include <util/system.h> #include <test/setup_common.h> diff --git a/src/test/prevector_tests.cpp b/src/test/prevector_tests.cpp index 141be50f50..fc1f946bba 100644 --- a/src/test/prevector_tests.cpp +++ b/src/test/prevector_tests.cpp @@ -183,6 +183,26 @@ public: pre_vector = pre_vector_alt; } + void resize_uninitialized(realtype values) { + size_t r = values.size(); + size_t s = real_vector.size() / 2; + if (real_vector.capacity() < s + r) { + real_vector.reserve(s + r); + } + real_vector.resize(s); + pre_vector.resize_uninitialized(s); + for (auto v : values) { + real_vector.push_back(v); + } + auto p = pre_vector.size(); + pre_vector.resize_uninitialized(p + r); + for (auto v : values) { + pre_vector[p] = v; + ++p; + } + test(); + } + ~prevector_tester() { BOOST_CHECK_MESSAGE(passed, "insecure_rand: " + rand_seed.ToString()); } @@ -260,6 +280,14 @@ BOOST_AUTO_TEST_CASE(PrevectorTestInt) if (InsecureRandBits(5) == 18) { test.move(); } + if (InsecureRandBits(5) == 19) { + unsigned int num = 1 + (InsecureRandBits(4)); + std::vector<int> values(num); + for (auto &v : values) { + v = InsecureRand32(); + } + test.resize_uninitialized(values); + } } } } diff --git a/src/test/raii_event_tests.cpp b/src/test/raii_event_tests.cpp index 2b01acf7fa..41ca8029e5 100644 --- a/src/test/raii_event_tests.cpp +++ b/src/test/raii_event_tests.cpp @@ -14,8 +14,6 @@ #include <test/setup_common.h> -#include <vector> - #include <boost/test/unit_test.hpp> static std::map<void*, short> tags; diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index 07d1326bcb..5ae0812243 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -9,10 +9,8 @@ #include <core_io.h> #include <init.h> #include <interfaces/chain.h> -#include <key_io.h> -#include <netbase.h> - #include <test/setup_common.h> +#include <util/time.h> #include <boost/algorithm/string.hpp> #include <boost/test/unit_test.hpp> diff --git a/src/test/script_p2sh_tests.cpp b/src/test/script_p2sh_tests.cpp index 9c4606f1b3..735b67c06e 100644 --- a/src/test/script_p2sh_tests.cpp +++ b/src/test/script_p2sh_tests.cpp @@ -3,7 +3,6 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <consensus/tx_verify.h> -#include <core_io.h> #include <key.h> #include <keystore.h> #include <validation.h> @@ -12,7 +11,6 @@ #include <script/script_error.h> #include <policy/settings.h> #include <script/sign.h> -#include <script/ismine.h> #include <test/setup_common.h> #include <vector> @@ -99,7 +97,6 @@ BOOST_AUTO_TEST_CASE(sign) txTo[i].vin[0].prevout.n = i; txTo[i].vin[0].prevout.hash = txFrom.GetHash(); txTo[i].vout[0].nValue = 1; - BOOST_CHECK_MESSAGE(IsMine(keystore, txFrom.vout[i].scriptPubKey), strprintf("IsMine %d", i)); } for (int i = 0; i < 8; i++) { @@ -196,7 +193,6 @@ BOOST_AUTO_TEST_CASE(set) txTo[i].vin[0].prevout.hash = txFrom.GetHash(); txTo[i].vout[0].nValue = 1*CENT; txTo[i].vout[0].scriptPubKey = inner[i]; - BOOST_CHECK_MESSAGE(IsMine(keystore, txFrom.vout[i].scriptPubKey), strprintf("IsMine %d", i)); } for (int i = 0; i < 4; i++) { diff --git a/src/test/script_standard_tests.cpp b/src/test/script_standard_tests.cpp index 9f50083335..046b220e3f 100644 --- a/src/test/script_standard_tests.cpp +++ b/src/test/script_standard_tests.cpp @@ -4,9 +4,7 @@ #include <key.h> #include <keystore.h> -#include <script/ismine.h> #include <script/script.h> -#include <script/script_error.h> #include <script/standard.h> #include <test/setup_common.h> @@ -372,364 +370,4 @@ BOOST_AUTO_TEST_CASE(script_standard_GetScriptFor_) BOOST_CHECK(result == expected); } -BOOST_AUTO_TEST_CASE(script_standard_IsMine) -{ - CKey keys[2]; - CPubKey pubkeys[2]; - for (int i = 0; i < 2; i++) { - keys[i].MakeNewKey(true); - pubkeys[i] = keys[i].GetPubKey(); - } - - CKey uncompressedKey; - uncompressedKey.MakeNewKey(false); - CPubKey uncompressedPubkey = uncompressedKey.GetPubKey(); - - CScript scriptPubKey; - isminetype result; - - // P2PK compressed - { - CBasicKeyStore keystore; - scriptPubKey = GetScriptForRawPubKey(pubkeys[0]); - - // Keystore does not have key - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_NO); - - // Keystore has key - BOOST_CHECK(keystore.AddKey(keys[0])); - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); - } - - // P2PK uncompressed - { - CBasicKeyStore keystore; - scriptPubKey = GetScriptForRawPubKey(uncompressedPubkey); - - // Keystore does not have key - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_NO); - - // Keystore has key - BOOST_CHECK(keystore.AddKey(uncompressedKey)); - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); - } - - // P2PKH compressed - { - CBasicKeyStore keystore; - scriptPubKey = GetScriptForDestination(PKHash(pubkeys[0])); - - // Keystore does not have key - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_NO); - - // Keystore has key - BOOST_CHECK(keystore.AddKey(keys[0])); - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); - } - - // P2PKH uncompressed - { - CBasicKeyStore keystore; - scriptPubKey = GetScriptForDestination(PKHash(uncompressedPubkey)); - - // Keystore does not have key - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_NO); - - // Keystore has key - BOOST_CHECK(keystore.AddKey(uncompressedKey)); - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); - } - - // P2SH - { - CBasicKeyStore keystore; - - CScript redeemScript = GetScriptForDestination(PKHash(pubkeys[0])); - scriptPubKey = GetScriptForDestination(ScriptHash(redeemScript)); - - // Keystore does not have redeemScript or key - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_NO); - - // Keystore has redeemScript but no key - BOOST_CHECK(keystore.AddCScript(redeemScript)); - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_NO); - - // Keystore has redeemScript and key - BOOST_CHECK(keystore.AddKey(keys[0])); - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); - } - - // (P2PKH inside) P2SH inside P2SH (invalid) - { - CBasicKeyStore keystore; - - CScript redeemscript_inner = GetScriptForDestination(PKHash(pubkeys[0])); - CScript redeemscript = GetScriptForDestination(ScriptHash(redeemscript_inner)); - scriptPubKey = GetScriptForDestination(ScriptHash(redeemscript)); - - BOOST_CHECK(keystore.AddCScript(redeemscript)); - BOOST_CHECK(keystore.AddCScript(redeemscript_inner)); - BOOST_CHECK(keystore.AddCScript(scriptPubKey)); - BOOST_CHECK(keystore.AddKey(keys[0])); - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_NO); - } - - // (P2PKH inside) P2SH inside P2WSH (invalid) - { - CBasicKeyStore keystore; - - CScript redeemscript = GetScriptForDestination(PKHash(pubkeys[0])); - CScript witnessscript = GetScriptForDestination(ScriptHash(redeemscript)); - scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash(witnessscript)); - - BOOST_CHECK(keystore.AddCScript(witnessscript)); - BOOST_CHECK(keystore.AddCScript(redeemscript)); - BOOST_CHECK(keystore.AddCScript(scriptPubKey)); - BOOST_CHECK(keystore.AddKey(keys[0])); - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_NO); - } - - // P2WPKH inside P2WSH (invalid) - { - CBasicKeyStore keystore; - - CScript witnessscript = GetScriptForDestination(WitnessV0KeyHash(PKHash(pubkeys[0]))); - scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash(witnessscript)); - - BOOST_CHECK(keystore.AddCScript(witnessscript)); - BOOST_CHECK(keystore.AddCScript(scriptPubKey)); - BOOST_CHECK(keystore.AddKey(keys[0])); - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_NO); - } - - // (P2PKH inside) P2WSH inside P2WSH (invalid) - { - CBasicKeyStore keystore; - - CScript witnessscript_inner = GetScriptForDestination(PKHash(pubkeys[0])); - CScript witnessscript = GetScriptForDestination(WitnessV0ScriptHash(witnessscript_inner)); - scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash(witnessscript)); - - BOOST_CHECK(keystore.AddCScript(witnessscript_inner)); - BOOST_CHECK(keystore.AddCScript(witnessscript)); - BOOST_CHECK(keystore.AddCScript(scriptPubKey)); - BOOST_CHECK(keystore.AddKey(keys[0])); - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_NO); - } - - // P2WPKH compressed - { - CBasicKeyStore keystore; - BOOST_CHECK(keystore.AddKey(keys[0])); - - scriptPubKey = GetScriptForDestination(WitnessV0KeyHash(PKHash(pubkeys[0]))); - - // Keystore implicitly has key and P2SH redeemScript - BOOST_CHECK(keystore.AddCScript(scriptPubKey)); - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); - } - - // P2WPKH uncompressed - { - CBasicKeyStore keystore; - BOOST_CHECK(keystore.AddKey(uncompressedKey)); - - scriptPubKey = GetScriptForDestination(WitnessV0KeyHash(PKHash(uncompressedPubkey))); - - // Keystore has key, but no P2SH redeemScript - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_NO); - - // Keystore has key and P2SH redeemScript - BOOST_CHECK(keystore.AddCScript(scriptPubKey)); - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_NO); - } - - // scriptPubKey multisig - { - CBasicKeyStore keystore; - - scriptPubKey = GetScriptForMultisig(2, {uncompressedPubkey, pubkeys[1]}); - - // Keystore does not have any keys - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_NO); - - // Keystore has 1/2 keys - BOOST_CHECK(keystore.AddKey(uncompressedKey)); - - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_NO); - - // Keystore has 2/2 keys - BOOST_CHECK(keystore.AddKey(keys[1])); - - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_NO); - - // Keystore has 2/2 keys and the script - BOOST_CHECK(keystore.AddCScript(scriptPubKey)); - - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_NO); - } - - // P2SH multisig - { - CBasicKeyStore keystore; - BOOST_CHECK(keystore.AddKey(uncompressedKey)); - BOOST_CHECK(keystore.AddKey(keys[1])); - - CScript redeemScript = GetScriptForMultisig(2, {uncompressedPubkey, pubkeys[1]}); - scriptPubKey = GetScriptForDestination(ScriptHash(redeemScript)); - - // Keystore has no redeemScript - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_NO); - - // Keystore has redeemScript - BOOST_CHECK(keystore.AddCScript(redeemScript)); - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); - } - - // P2WSH multisig with compressed keys - { - CBasicKeyStore keystore; - BOOST_CHECK(keystore.AddKey(keys[0])); - BOOST_CHECK(keystore.AddKey(keys[1])); - - CScript witnessScript = GetScriptForMultisig(2, {pubkeys[0], pubkeys[1]}); - scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash(witnessScript)); - - // Keystore has keys, but no witnessScript or P2SH redeemScript - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_NO); - - // Keystore has keys and witnessScript, but no P2SH redeemScript - BOOST_CHECK(keystore.AddCScript(witnessScript)); - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_NO); - - // Keystore has keys, witnessScript, P2SH redeemScript - BOOST_CHECK(keystore.AddCScript(scriptPubKey)); - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); - } - - // P2WSH multisig with uncompressed key - { - CBasicKeyStore keystore; - BOOST_CHECK(keystore.AddKey(uncompressedKey)); - BOOST_CHECK(keystore.AddKey(keys[1])); - - CScript witnessScript = GetScriptForMultisig(2, {uncompressedPubkey, pubkeys[1]}); - scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash(witnessScript)); - - // Keystore has keys, but no witnessScript or P2SH redeemScript - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_NO); - - // Keystore has keys and witnessScript, but no P2SH redeemScript - BOOST_CHECK(keystore.AddCScript(witnessScript)); - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_NO); - - // Keystore has keys, witnessScript, P2SH redeemScript - BOOST_CHECK(keystore.AddCScript(scriptPubKey)); - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_NO); - } - - // P2WSH multisig wrapped in P2SH - { - CBasicKeyStore keystore; - - CScript witnessScript = GetScriptForMultisig(2, {pubkeys[0], pubkeys[1]}); - CScript redeemScript = GetScriptForDestination(WitnessV0ScriptHash(witnessScript)); - scriptPubKey = GetScriptForDestination(ScriptHash(redeemScript)); - - // Keystore has no witnessScript, P2SH redeemScript, or keys - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_NO); - - // Keystore has witnessScript and P2SH redeemScript, but no keys - BOOST_CHECK(keystore.AddCScript(redeemScript)); - BOOST_CHECK(keystore.AddCScript(witnessScript)); - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_NO); - - // Keystore has keys, witnessScript, P2SH redeemScript - BOOST_CHECK(keystore.AddKey(keys[0])); - BOOST_CHECK(keystore.AddKey(keys[1])); - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); - } - - // OP_RETURN - { - CBasicKeyStore keystore; - BOOST_CHECK(keystore.AddKey(keys[0])); - - scriptPubKey.clear(); - scriptPubKey << OP_RETURN << ToByteVector(pubkeys[0]); - - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_NO); - } - - // witness unspendable - { - CBasicKeyStore keystore; - BOOST_CHECK(keystore.AddKey(keys[0])); - - scriptPubKey.clear(); - scriptPubKey << OP_0 << ToByteVector(ParseHex("aabb")); - - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_NO); - } - - // witness unknown - { - CBasicKeyStore keystore; - BOOST_CHECK(keystore.AddKey(keys[0])); - - scriptPubKey.clear(); - scriptPubKey << OP_16 << ToByteVector(ParseHex("aabb")); - - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_NO); - } - - // Nonstandard - { - CBasicKeyStore keystore; - BOOST_CHECK(keystore.AddKey(keys[0])); - - scriptPubKey.clear(); - scriptPubKey << OP_9 << OP_ADD << OP_11 << OP_EQUAL; - - result = IsMine(keystore, scriptPubKey); - BOOST_CHECK_EQUAL(result, ISMINE_NO); - } -} - BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 4798909e2f..ae903df0ad 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -14,12 +14,12 @@ #include <util/strencodings.h> #include <test/setup_common.h> #include <rpc/util.h> +#include <streams.h> #if defined(HAVE_CONSENSUS_LIB) #include <script/bitcoinconsensus.h> #endif -#include <fstream> #include <stdint.h> #include <string> #include <vector> diff --git a/src/test/scriptnum10.h b/src/test/scriptnum10.h index e763b64275..2c89a18331 100644 --- a/src/test/scriptnum10.h +++ b/src/test/scriptnum10.h @@ -6,7 +6,6 @@ #ifndef BITCOIN_TEST_SCRIPTNUM10_H #define BITCOIN_TEST_SCRIPTNUM10_H -#include <algorithm> #include <limits> #include <stdexcept> #include <stdint.h> diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp index 2fab309aa4..8a8620938e 100644 --- a/src/test/serialize_tests.cpp +++ b/src/test/serialize_tests.cpp @@ -6,6 +6,7 @@ #include <streams.h> #include <hash.h> #include <test/setup_common.h> +#include <util/strencodings.h> #include <stdint.h> diff --git a/src/test/setup_common.cpp b/src/test/setup_common.cpp index 5b454da52b..e3ba9cddb0 100644 --- a/src/test/setup_common.cpp +++ b/src/test/setup_common.cpp @@ -10,17 +10,22 @@ #include <consensus/params.h> #include <consensus/validation.h> #include <crypto/sha256.h> +#include <init.h> #include <miner.h> -#include <net_processing.h> +#include <net.h> #include <noui.h> #include <pow.h> #include <rpc/register.h> #include <rpc/server.h> #include <script/sigcache.h> #include <streams.h> -#include <ui_interface.h> +#include <txdb.h> +#include <util/memory.h> +#include <util/strencodings.h> +#include <util/time.h> #include <util/validation.h> #include <validation.h> +#include <validationinterface.h> const std::function<std::string(const char*)> G_TRANSLATION_FUN = nullptr; @@ -35,6 +40,13 @@ std::ostream& operator<<(std::ostream& os, const uint256& num) BasicTestingSetup::BasicTestingSetup(const std::string& chainName) : m_path_root(fs::temp_directory_path() / "test_common_" PACKAGE_NAME / strprintf("%lu_%i", (unsigned long)GetTime(), (int)(InsecureRandRange(1 << 30)))) { + fs::create_directories(m_path_root); + gArgs.ForceSetArg("-datadir", m_path_root.string()); + ClearDatadirCache(); + SelectParams(chainName); + gArgs.ForceSetArg("-printtoconsole", "0"); + InitLogging(); + LogInstance().StartLogging(); SHA256AutoDetect(); ECC_Start(); SetupEnvironment(); @@ -42,7 +54,6 @@ BasicTestingSetup::BasicTestingSetup(const std::string& chainName) InitSignatureCache(); InitScriptExecutionCache(); fCheckBlockIndex = true; - SelectParams(chainName); static bool noui_connected = false; if (!noui_connected) { noui_connect(); @@ -52,27 +63,18 @@ BasicTestingSetup::BasicTestingSetup(const std::string& chainName) BasicTestingSetup::~BasicTestingSetup() { + LogInstance().DisconnectTestLogger(); fs::remove_all(m_path_root); ECC_Stop(); } -fs::path BasicTestingSetup::SetDataDir(const std::string& name) -{ - fs::path ret = m_path_root / name; - fs::create_directories(ret); - gArgs.ForceSetArg("-datadir", ret.string()); - return ret; -} - TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(chainName) { - SetDataDir("tempdir"); const CChainParams& chainparams = Params(); // Ideally we'd move all the RPC tests to the functional testing framework // instead of unit tests, but for now we need these here. RegisterAllCoreRPCCommands(tableRPC); - ClearDatadirCache(); // We have to run a scheduler thread to prevent ActivateBestChain // from blocking due to queue overrun. diff --git a/src/test/setup_common.h b/src/test/setup_common.h index 893eca216d..6c9494898c 100644 --- a/src/test/setup_common.h +++ b/src/test/setup_common.h @@ -11,10 +11,8 @@ #include <pubkey.h> #include <random.h> #include <scheduler.h> -#include <txdb.h> #include <txmempool.h> -#include <memory> #include <type_traits> #include <boost/thread.hpp> @@ -54,22 +52,19 @@ static inline bool InsecureRandBool() { return g_insecure_rand_ctx.randbool(); } static constexpr CAmount CENT{1000000}; /** Basic testing setup. - * This just configures logging and chain parameters. + * This just configures logging, data dir and chain parameters. */ struct BasicTestingSetup { ECCVerifyHandle globalVerifyHandle; explicit BasicTestingSetup(const std::string& chainName = CBaseChainParams::MAIN); ~BasicTestingSetup(); - - fs::path SetDataDir(const std::string& name); - private: const fs::path m_path_root; }; /** Testing setup that configures a complete environment. - * Included are data directory, coins database, script check threads setup. + * Included are coins database, script check threads setup. */ struct TestingSetup : public BasicTestingSetup { boost::thread_group threadGroup; diff --git a/src/test/sigopcount_tests.cpp b/src/test/sigopcount_tests.cpp index 5c12ec13d2..a32f2cda92 100644 --- a/src/test/sigopcount_tests.cpp +++ b/src/test/sigopcount_tests.cpp @@ -2,8 +2,8 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <consensus/consensus.h> #include <consensus/tx_verify.h> -#include <consensus/validation.h> #include <pubkey.h> #include <key.h> #include <script/script.h> diff --git a/src/test/streams_tests.cpp b/src/test/streams_tests.cpp index 4e37199c63..b812cef801 100644 --- a/src/test/streams_tests.cpp +++ b/src/test/streams_tests.cpp @@ -3,7 +3,6 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <streams.h> -#include <support/allocators/zeroafterfree.h> #include <test/setup_common.h> #include <boost/test/unit_test.hpp> diff --git a/src/test/torcontrol_tests.cpp b/src/test/torcontrol_tests.cpp index 6d8459f5b1..d846062d9b 100644 --- a/src/test/torcontrol_tests.cpp +++ b/src/test/torcontrol_tests.cpp @@ -3,7 +3,6 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. // #include <test/setup_common.h> -#include <torcontrol.h> #include <boost/test/unit_test.hpp> diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index f5ff18c055..f77b77a972 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -20,6 +20,7 @@ #include <script/sign.h> #include <script/script_error.h> #include <script/standard.h> +#include <streams.h> #include <util/strencodings.h> #include <map> diff --git a/src/test/txindex_tests.cpp b/src/test/txindex_tests.cpp index 19561d4f67..d794d09d30 100644 --- a/src/test/txindex_tests.cpp +++ b/src/test/txindex_tests.cpp @@ -8,7 +8,6 @@ #include <test/setup_common.h> #include <util/system.h> #include <util/time.h> -#include <validation.h> #include <boost/test/unit_test.hpp> diff --git a/src/test/txvalidation_tests.cpp b/src/test/txvalidation_tests.cpp index 26ae7be202..2356e0ccdc 100644 --- a/src/test/txvalidation_tests.cpp +++ b/src/test/txvalidation_tests.cpp @@ -3,8 +3,6 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <validation.h> -#include <txmempool.h> -#include <amount.h> #include <consensus/validation.h> #include <primitives/transaction.h> #include <script/script.h> diff --git a/src/test/txvalidationcache_tests.cpp b/src/test/txvalidationcache_tests.cpp index fe30d5f3a7..45c97fa2aa 100644 --- a/src/test/txvalidationcache_tests.cpp +++ b/src/test/txvalidationcache_tests.cpp @@ -5,17 +5,11 @@ #include <consensus/validation.h> #include <key.h> #include <validation.h> -#include <miner.h> -#include <pubkey.h> #include <txmempool.h> -#include <random.h> #include <script/standard.h> #include <script/sign.h> #include <test/setup_common.h> -#include <util/time.h> -#include <core_io.h> #include <keystore.h> -#include <policy/policy.h> #include <boost/test/unit_test.hpp> diff --git a/src/test/uint256_tests.cpp b/src/test/uint256_tests.cpp index c1749fb856..33a118c2bb 100644 --- a/src/test/uint256_tests.cpp +++ b/src/test/uint256_tests.cpp @@ -1,19 +1,17 @@ // Copyright (c) 2011-2019 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 <arith_uint256.h> +#include <streams.h> #include <uint256.h> #include <version.h> #include <test/setup_common.h> #include <boost/test/unit_test.hpp> -#include <stdint.h> #include <sstream> #include <iomanip> -#include <limits> -#include <cmath> #include <string> -#include <stdio.h> BOOST_FIXTURE_TEST_SUITE(uint256_tests, BasicTestingSetup) diff --git a/src/test/util.cpp b/src/test/util.cpp index 64ecc6623a..a2ea648324 100644 --- a/src/test/util.cpp +++ b/src/test/util.cpp @@ -6,22 +6,17 @@ #include <chainparams.h> #include <consensus/merkle.h> -#include <consensus/validation.h> #include <key_io.h> #include <miner.h> #include <outputtype.h> #include <pow.h> -#include <scheduler.h> #include <script/standard.h> -#include <txdb.h> #include <validation.h> #include <validationinterface.h> #ifdef ENABLE_WALLET #include <wallet/wallet.h> #endif -#include <boost/thread.hpp> - const std::string ADDRESS_BCRT1_UNSPENDABLE = "bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3xueyj"; #ifdef ENABLE_WALLET diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 8fee66d6c3..9960573b33 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -5,14 +5,15 @@ #include <util/system.h> #include <clientversion.h> -#include <primitives/transaction.h> #include <sync.h> #include <test/util.h> #include <util/strencodings.h> #include <util/moneystr.h> +#include <util/time.h> #include <test/setup_common.h> #include <stdint.h> +#include <thread> #include <vector> #ifndef WIN32 #include <signal.h> @@ -1398,7 +1399,7 @@ static void TestOtherProcess(fs::path dirname, std::string lockname, int fd) BOOST_AUTO_TEST_CASE(test_LockDirectory) { - fs::path dirname = SetDataDir("test_LockDirectory") / fs::unique_path(); + fs::path dirname = GetDataDir() / "lock_dir"; const std::string lockname = ".lock"; #ifndef WIN32 // Revert SIGCHLD to default, otherwise boost.test will catch and fail on @@ -1487,7 +1488,7 @@ BOOST_AUTO_TEST_CASE(test_LockDirectory) BOOST_AUTO_TEST_CASE(test_DirIsWritable) { // Should be able to write to the data dir. - fs::path tmpdirname = SetDataDir("test_DirIsWritable"); + fs::path tmpdirname = GetDataDir(); BOOST_CHECK_EQUAL(DirIsWritable(tmpdirname), true); // Should not be able to write to a non-existent dir. diff --git a/src/test/validation_block_tests.cpp b/src/test/validation_block_tests.cpp index 5dee034b20..b3368d44b6 100644 --- a/src/test/validation_block_tests.cpp +++ b/src/test/validation_block_tests.cpp @@ -10,14 +10,20 @@ #include <miner.h> #include <pow.h> #include <random.h> +#include <script/standard.h> #include <test/setup_common.h> +#include <util/time.h> #include <validation.h> #include <validationinterface.h> +#include <thread> + struct RegtestingSetup : public TestingSetup { RegtestingSetup() : TestingSetup(CBaseChainParams::REGTEST) {} }; +static const std::vector<unsigned char> V_OP_TRUE{OP_TRUE}; + BOOST_FIXTURE_TEST_SUITE(validation_block_tests, RegtestingSetup) struct TestSubscriber : public CValidationInterface { @@ -59,8 +65,21 @@ std::shared_ptr<CBlock> Block(const uint256& prev_hash) pblock->hashPrevBlock = prev_hash; pblock->nTime = ++time; + pubKey.clear(); + { + WitnessV0ScriptHash witness_program; + CSHA256().Write(&V_OP_TRUE[0], V_OP_TRUE.size()).Finalize(witness_program.begin()); + pubKey << OP_0 << ToByteVector(witness_program); + } + + // Make the coinbase transaction with two outputs: + // One zero-value one that has a unique pubkey to make sure that blocks at the same height can have a different hash + // Another one that has the coinbase reward in a P2WSH with OP_TRUE as witness program to make it easy to spend CMutableTransaction txCoinbase(*pblock->vtx[0]); - txCoinbase.vout.resize(1); + txCoinbase.vout.resize(2); + txCoinbase.vout[1].scriptPubKey = pubKey; + txCoinbase.vout[1].nValue = txCoinbase.vout[0].nValue; + txCoinbase.vout[0].nValue = 0; txCoinbase.vin[0].scriptWitness.SetNull(); pblock->vtx[0] = MakeTransactionRef(std::move(txCoinbase)); @@ -69,6 +88,9 @@ std::shared_ptr<CBlock> Block(const uint256& prev_hash) std::shared_ptr<CBlock> FinalizeBlock(std::shared_ptr<CBlock> pblock) { + LOCK(cs_main); // For LookupBlockIndex + GenerateCoinbaseCommitment(*pblock, LookupBlockIndex(pblock->hashPrevBlock), Params().GetConsensus()); + pblock->hashMerkleRoot = BlockMerkleRoot(*pblock); while (!CheckProofOfWork(pblock->GetHash(), pblock->nBits, Params().GetConsensus())) { @@ -79,13 +101,13 @@ std::shared_ptr<CBlock> FinalizeBlock(std::shared_ptr<CBlock> pblock) } // construct a valid block -const std::shared_ptr<const CBlock> GoodBlock(const uint256& prev_hash) +std::shared_ptr<const CBlock> GoodBlock(const uint256& prev_hash) { return FinalizeBlock(Block(prev_hash)); } // construct an invalid block (but with a valid header) -const std::shared_ptr<const CBlock> BadBlock(const uint256& prev_hash) +std::shared_ptr<const CBlock> BadBlock(const uint256& prev_hash) { auto pblock = Block(prev_hash); @@ -185,4 +207,131 @@ BOOST_AUTO_TEST_CASE(processnewblock_signals_ordering) BOOST_CHECK_EQUAL(sub.m_expected_tip, ::ChainActive().Tip()->GetBlockHash()); } +/** + * Test that mempool updates happen atomically with reorgs. + * + * This prevents RPC clients, among others, from retrieving immediately-out-of-date mempool data + * during large reorgs. + * + * The test verifies this by creating a chain of `num_txs` blocks, matures their coinbases, and then + * submits txns spending from their coinbase to the mempool. A fork chain is then processed, + * invalidating the txns and evicting them from the mempool. + * + * We verify that the mempool updates atomically by polling it continuously + * from another thread during the reorg and checking that its size only changes + * once. The size changing exactly once indicates that the polling thread's + * view of the mempool is either consistent with the chain state before reorg, + * or consistent with the chain state after the reorg, and not just consistent + * with some intermediate state during the reorg. + */ +BOOST_AUTO_TEST_CASE(mempool_locks_reorg) +{ + bool ignored; + auto ProcessBlock = [&ignored](std::shared_ptr<const CBlock> block) -> bool { + return ProcessNewBlock(Params(), block, /* fForceProcessing */ true, /* fNewBlock */ &ignored); + }; + + // Process all mined blocks + BOOST_REQUIRE(ProcessBlock(std::make_shared<CBlock>(Params().GenesisBlock()))); + auto last_mined = GoodBlock(Params().GenesisBlock().GetHash()); + BOOST_REQUIRE(ProcessBlock(last_mined)); + + // Run the test multiple times + for (int test_runs = 3; test_runs > 0; --test_runs) { + BOOST_CHECK_EQUAL(last_mined->GetHash(), ::ChainActive().Tip()->GetBlockHash()); + + // Later on split from here + const uint256 split_hash{last_mined->hashPrevBlock}; + + // Create a bunch of transactions to spend the miner rewards of the + // most recent blocks + std::vector<CTransactionRef> txs; + for (int num_txs = 22; num_txs > 0; --num_txs) { + CMutableTransaction mtx; + mtx.vin.push_back(CTxIn{COutPoint{last_mined->vtx[0]->GetHash(), 1}, CScript{}}); + mtx.vin[0].scriptWitness.stack.push_back(V_OP_TRUE); + mtx.vout.push_back(last_mined->vtx[0]->vout[1]); + mtx.vout[0].nValue -= 1000; + txs.push_back(MakeTransactionRef(mtx)); + + last_mined = GoodBlock(last_mined->GetHash()); + BOOST_REQUIRE(ProcessBlock(last_mined)); + } + + // Mature the inputs of the txs + for (int j = COINBASE_MATURITY; j > 0; --j) { + last_mined = GoodBlock(last_mined->GetHash()); + BOOST_REQUIRE(ProcessBlock(last_mined)); + } + + // Mine a reorg (and hold it back) before adding the txs to the mempool + const uint256 tip_init{last_mined->GetHash()}; + + std::vector<std::shared_ptr<const CBlock>> reorg; + last_mined = GoodBlock(split_hash); + reorg.push_back(last_mined); + for (size_t j = COINBASE_MATURITY + txs.size() + 1; j > 0; --j) { + last_mined = GoodBlock(last_mined->GetHash()); + reorg.push_back(last_mined); + } + + // Add the txs to the tx pool + { + LOCK(cs_main); + CValidationState state; + std::list<CTransactionRef> plTxnReplaced; + for (const auto& tx : txs) { + BOOST_REQUIRE(AcceptToMemoryPool( + ::mempool, + state, + tx, + /* pfMissingInputs */ &ignored, + &plTxnReplaced, + /* bypass_limits */ false, + /* nAbsurdFee */ 0)); + } + } + + // Check that all txs are in the pool + { + LOCK(::mempool.cs); + BOOST_CHECK_EQUAL(::mempool.mapTx.size(), txs.size()); + } + + // Run a thread that simulates an RPC caller that is polling while + // validation is doing a reorg + std::thread rpc_thread{[&]() { + // This thread is checking that the mempool either contains all of + // the transactions invalidated by the reorg, or none of them, and + // not some intermediate amount. + while (true) { + LOCK(::mempool.cs); + if (::mempool.mapTx.size() == 0) { + // We are done with the reorg + break; + } + // Internally, we might be in the middle of the reorg, but + // externally the reorg to the most-proof-of-work chain should + // be atomic. So the caller assumes that the returned mempool + // is consistent. That is, it has all txs that were there + // before the reorg. + assert(::mempool.mapTx.size() == txs.size()); + continue; + } + LOCK(cs_main); + // We are done with the reorg, so the tip must have changed + assert(tip_init != ::ChainActive().Tip()->GetBlockHash()); + }}; + + // Submit the reorg in this thread to invalidate and remove the txs from the tx pool + for (const auto& b : reorg) { + ProcessBlock(b); + } + // Check that the reorg was eventually successful + BOOST_CHECK_EQUAL(last_mined->GetHash(), ::ChainActive().Tip()->GetBlockHash()); + + // We can join the other thread, which returns when the reorg was successful + rpc_thread.join(); + } +} BOOST_AUTO_TEST_SUITE_END() diff --git a/src/timedata.cpp b/src/timedata.cpp index 9c022c9ad1..b43639d729 100644 --- a/src/timedata.cpp +++ b/src/timedata.cpp @@ -12,7 +12,6 @@ #include <sync.h> #include <ui_interface.h> #include <util/system.h> -#include <util/strencodings.h> #include <warnings.h> diff --git a/src/tinyformat.h b/src/tinyformat.h index 14b7cd3026..182f518a0b 100644 --- a/src/tinyformat.h +++ b/src/tinyformat.h @@ -1063,6 +1063,7 @@ std::string format(const std::string &fmt, const Args&... args) } // namespace tinyformat +/** Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for details) */ #define strprintf tfm::format #endif // TINYFORMAT_H_INCLUDED diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 550e23b222..a1c730ba08 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -3,6 +3,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <chainparams.h> #include <torcontrol.h> #include <util/strencodings.h> #include <netbase.h> @@ -412,7 +413,7 @@ public: TorController(struct event_base* base, const std::string& target); ~TorController(); - /** Get name fo file to store private key in */ + /** Get name of file to store private key in */ fs::path GetPrivateKeyFile(); /** Reconnect, after getting disconnected */ @@ -500,7 +501,7 @@ void TorController::add_onion_cb(TorControlConnection& _conn, const TorControlRe } return; } - service = LookupNumeric(std::string(service_id+".onion").c_str(), GetListenPort()); + service = LookupNumeric(std::string(service_id+".onion").c_str(), Params().GetDefaultPort()); LogPrintf("tor: Got service ID %s, advertising service %s\n", service_id, service.ToString()); if (WriteBinaryFile(GetPrivateKeyFile(), private_key)) { LogPrint(BCLog::TOR, "tor: Cached service private key to %s\n", GetPrivateKeyFile().string()); @@ -534,9 +535,8 @@ void TorController::auth_cb(TorControlConnection& _conn, const TorControlReply& if (private_key.empty()) // No private key, generate one private_key = "NEW:RSA1024"; // Explicitly request RSA1024 - see issue #9214 // Request hidden service, redirect port. - // Note that the 'virtual' port doesn't have to be the same as our internal port, but this is just a convenient - // choice. TODO; refactor the shutdown sequence some day. - _conn.Command(strprintf("ADD_ONION %s Port=%i,127.0.0.1:%i", private_key, GetListenPort(), GetListenPort()), + // Note that the 'virtual' port is always the default port to avoid decloaking nodes using other ports. + _conn.Command(strprintf("ADD_ONION %s Port=%i,127.0.0.1:%i", private_key, Params().GetDefaultPort(), GetListenPort()), std::bind(&TorController::add_onion_cb, this, std::placeholders::_1, std::placeholders::_2)); } else { LogPrintf("tor: Authentication failed\n"); diff --git a/src/txdb.cpp b/src/txdb.cpp index 494b87ad48..73fe2a8ee4 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -5,8 +5,6 @@ #include <txdb.h> -#include <chainparams.h> -#include <hash.h> #include <random.h> #include <pow.h> #include <shutdown.h> diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 80dbd9c19d..9257cff718 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -13,8 +13,6 @@ #include <policy/fees.h> #include <policy/settings.h> #include <reverse_iterator.h> -#include <streams.h> -#include <timedata.h> #include <util/system.h> #include <util/moneystr.h> #include <util/time.h> @@ -106,7 +104,7 @@ void CTxMemPool::UpdateForDescendants(txiter updateIt, cacheMap &cachedDescendan // for each such descendant, also update the ancestor state to include the parent. void CTxMemPool::UpdateTransactionsFromBlock(const std::vector<uint256> &vHashesToUpdate) { - LOCK(cs); + AssertLockHeld(cs); // For each entry in vHashesToUpdate, store the set of in-mempool, but not // in-vHashesToUpdate transactions, so that we don't have to recalculate // descendants when we come across a previously seen entry. @@ -324,8 +322,8 @@ void CTxMemPoolEntry::UpdateAncestorState(int64_t modifySize, CAmount modifyFee, assert(int(nSigOpCostWithAncestors) >= 0); } -CTxMemPool::CTxMemPool(CBlockPolicyEstimator* estimator) : - nTransactionsUpdated(0), minerPolicyEstimator(estimator) +CTxMemPool::CTxMemPool(CBlockPolicyEstimator* estimator) + : nTransactionsUpdated(0), minerPolicyEstimator(estimator) { _clear(); //lock free clear @@ -343,13 +341,11 @@ bool CTxMemPool::isSpent(const COutPoint& outpoint) const unsigned int CTxMemPool::GetTransactionsUpdated() const { - LOCK(cs); return nTransactionsUpdated; } void CTxMemPool::AddTransactionsUpdated(unsigned int n) { - LOCK(cs); nTransactionsUpdated += n; } @@ -461,8 +457,7 @@ void CTxMemPool::CalculateDescendants(txiter entryit, setEntries& setDescendants void CTxMemPool::removeRecursive(const CTransaction &origTx, MemPoolRemovalReason reason) { // Remove transaction from memory pool - { - LOCK(cs); + AssertLockHeld(cs); setEntries txToRemove; txiter origit = mapTx.find(origTx.GetHash()); if (origit != mapTx.end()) { @@ -487,13 +482,12 @@ void CTxMemPool::removeRecursive(const CTransaction &origTx, MemPoolRemovalReaso } RemoveStaged(setAllRemoves, false, reason); - } } void CTxMemPool::removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags) { // Remove transactions spending a coinbase which are now immature and no-longer-final transactions - LOCK(cs); + AssertLockHeld(cs); setEntries txToRemove; for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { const CTransaction& tx = it->GetTx(); @@ -549,7 +543,7 @@ void CTxMemPool::removeConflicts(const CTransaction &tx) */ void CTxMemPool::removeForBlock(const std::vector<CTransactionRef>& vtx, unsigned int nBlockHeight) { - LOCK(cs); + AssertLockHeld(cs); std::vector<const CTxMemPoolEntry*> entries; for (const auto& tx : vtx) { @@ -924,7 +918,7 @@ void CTxMemPool::RemoveStaged(setEntries &stage, bool updateDescendants, MemPool } int CTxMemPool::Expire(int64_t time) { - LOCK(cs); + AssertLockHeld(cs); indexed_transaction_set::index<entry_time>::type::iterator it = mapTx.get<entry_time>().begin(); setEntries toremove; while (it != mapTx.get<entry_time>().end() && it->GetTime() < time) { @@ -1017,7 +1011,7 @@ void CTxMemPool::trackPackageRemoved(const CFeeRate& rate) { } void CTxMemPool::TrimToSize(size_t sizelimit, std::vector<COutPoint>* pvNoSpendsRemaining) { - LOCK(cs); + AssertLockHeld(cs); unsigned nTxnRemoved = 0; CFeeRate maxFeeRateRemoved(0); diff --git a/src/txmempool.h b/src/txmempool.h index ce0b762336..565dd61f0f 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -6,12 +6,13 @@ #ifndef BITCOIN_TXMEMPOOL_H #define BITCOIN_TXMEMPOOL_H +#include <atomic> +#include <map> #include <memory> #include <set> -#include <map> -#include <vector> -#include <utility> #include <string> +#include <utility> +#include <vector> #include <amount.h> #include <coins.h> @@ -443,7 +444,7 @@ class CTxMemPool { private: uint32_t nCheckFrequency GUARDED_BY(cs); //!< Value n means that n times in 2^32 we check. - unsigned int nTransactionsUpdated; //!< Used by getblocktemplate to trigger CreateNewBlock() invocation + std::atomic<unsigned int> nTransactionsUpdated; //!< Used by getblocktemplate to trigger CreateNewBlock() invocation CBlockPolicyEstimator* minerPolicyEstimator; uint64_t totalTxSize; //!< sum of all mempool tx's virtual sizes. Differs from serialized tx size since witness data is discounted. Defined in BIP 141. @@ -513,21 +514,12 @@ public: * `mempool.cs` whenever adding transactions to the mempool and whenever * changing the chain tip. It's necessary to keep both mutexes locked until * the mempool is consistent with the new chain tip and fully populated. - * - * @par Consistency bug - * - * The second guarantee above is not currently enforced, but - * https://github.com/bitcoin/bitcoin/pull/14193 will fix it. No known code - * in bitcoin currently depends on second guarantee, but it is important to - * fix for third party code that needs be able to frequently poll the - * mempool without locking `cs_main` and without encountering missing - * transactions during reorgs. */ mutable RecursiveMutex cs; indexed_transaction_set mapTx GUARDED_BY(cs); using txiter = indexed_transaction_set::nth_index<0>::type::const_iterator; - std::vector<std::pair<uint256, txiter> > vTxHashes; //!< All tx witness hashes/entries in mapTx, in random order + std::vector<std::pair<uint256, txiter>> vTxHashes GUARDED_BY(cs); //!< All tx witness hashes/entries in mapTx, in random order struct CompareIteratorByHash { bool operator()(const txiter &a, const txiter &b) const { @@ -582,10 +574,10 @@ public: void addUnchecked(const CTxMemPoolEntry& entry, bool validFeeEstimate = true) EXCLUSIVE_LOCKS_REQUIRED(cs, cs_main); void addUnchecked(const CTxMemPoolEntry& entry, setEntries& setAncestors, bool validFeeEstimate = true) EXCLUSIVE_LOCKS_REQUIRED(cs, cs_main); - void removeRecursive(const CTransaction &tx, MemPoolRemovalReason reason = MemPoolRemovalReason::UNKNOWN); - void removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags) EXCLUSIVE_LOCKS_REQUIRED(cs_main); - void removeConflicts(const CTransaction &tx) EXCLUSIVE_LOCKS_REQUIRED(cs); - void removeForBlock(const std::vector<CTransactionRef>& vtx, unsigned int nBlockHeight); + void removeRecursive(const CTransaction& tx, MemPoolRemovalReason reason = MemPoolRemovalReason::UNKNOWN) EXCLUSIVE_LOCKS_REQUIRED(cs); + void removeForReorg(const CCoinsViewCache* pcoins, unsigned int nMemPoolHeight, int flags) EXCLUSIVE_LOCKS_REQUIRED(cs, cs_main); + void removeConflicts(const CTransaction& tx) EXCLUSIVE_LOCKS_REQUIRED(cs); + void removeForBlock(const std::vector<CTransactionRef>& vtx, unsigned int nBlockHeight) EXCLUSIVE_LOCKS_REQUIRED(cs); void clear(); void _clear() EXCLUSIVE_LOCKS_REQUIRED(cs); //lock free @@ -598,7 +590,7 @@ public: * Check that none of this transactions inputs are in the mempool, and thus * the tx is not dependent on other mempool transactions to be included in a block. */ - bool HasNoInputsOf(const CTransaction& tx) const; + bool HasNoInputsOf(const CTransaction& tx) const EXCLUSIVE_LOCKS_REQUIRED(cs); /** Affect CreateNewBlock prioritisation of transactions */ void PrioritiseTransaction(const uint256& hash, const CAmount& nFeeDelta); @@ -632,7 +624,7 @@ public: * for). Note: vHashesToUpdate should be the set of transactions from the * disconnected block that have been accepted back into the mempool. */ - void UpdateTransactionsFromBlock(const std::vector<uint256>& vHashesToUpdate) EXCLUSIVE_LOCKS_REQUIRED(cs_main); + void UpdateTransactionsFromBlock(const std::vector<uint256>& vHashesToUpdate) EXCLUSIVE_LOCKS_REQUIRED(cs, cs_main); /** Try to calculate all in-mempool ancestors of entry. * (these are all calculated including the tx itself) @@ -663,10 +655,10 @@ public: * pvNoSpendsRemaining, if set, will be populated with the list of outpoints * which are not in mempool which no longer have any spends in this mempool. */ - void TrimToSize(size_t sizelimit, std::vector<COutPoint>* pvNoSpendsRemaining=nullptr); + void TrimToSize(size_t sizelimit, std::vector<COutPoint>* pvNoSpendsRemaining = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs); /** Expire all transaction (and their dependencies) in the mempool older than time. Return the number of removed transactions. */ - int Expire(int64_t time); + int Expire(int64_t time) EXCLUSIVE_LOCKS_REQUIRED(cs); /** * Calculate the ancestor and descendant count for the given transaction. diff --git a/src/ui_interface.cpp b/src/ui_interface.cpp index 31a95486d7..d310637145 100644 --- a/src/ui_interface.cpp +++ b/src/ui_interface.cpp @@ -3,7 +3,6 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <ui_interface.h> -#include <util/system.h> #include <boost/signals2/last_value.hpp> #include <boost/signals2/signal.hpp> @@ -22,7 +21,8 @@ struct UISignals { boost::signals2::signal<CClientUIInterface::NotifyBlockTipSig> NotifyBlockTip; boost::signals2::signal<CClientUIInterface::NotifyHeaderTipSig> NotifyHeaderTip; boost::signals2::signal<CClientUIInterface::BannedListChangedSig> BannedListChanged; -} g_ui_signals; +}; +static UISignals g_ui_signals; #define ADD_SIGNALS_IMPL_WRAPPER(signal_name) \ boost::signals2::connection CClientUIInterface::signal_name##_connect(std::function<signal_name##Sig> fn) \ diff --git a/src/ui_interface.h b/src/ui_interface.h index d408f6f889..5e0380dc45 100644 --- a/src/ui_interface.h +++ b/src/ui_interface.h @@ -69,6 +69,9 @@ public: /** Force blocking, modal message box dialog (not just OS notification) */ MODAL = 0x10000000U, + /** Do not prepend error/warning prefix */ + MSG_NOPREFIX = 0x20000000U, + /** Do not print contents of message to debug log */ SECURE = 0x40000000U, diff --git a/src/util/error.cpp b/src/util/error.cpp index 68ffd8b046..9331a92ad7 100644 --- a/src/util/error.cpp +++ b/src/util/error.cpp @@ -27,6 +27,8 @@ std::string TransactionErrorString(const TransactionError err) return "PSBTs not compatible (different transactions)"; case TransactionError::SIGHASH_MISMATCH: return "Specified sighash value does not match existing value"; + case TransactionError::MAX_FEE_EXCEEDED: + return "Fee exceeds maximum configured by -maxtxfee"; // no default case, so the compiler can warn about missing cases } assert(false); diff --git a/src/util/error.h b/src/util/error.h index d93309551b..0fd474b962 100644 --- a/src/util/error.h +++ b/src/util/error.h @@ -27,6 +27,7 @@ enum class TransactionError { INVALID_PSBT, PSBT_MISMATCH, SIGHASH_MISMATCH, + MAX_FEE_EXCEEDED, }; std::string TransactionErrorString(const TransactionError error); diff --git a/src/util/fees.cpp b/src/util/fees.cpp index 5fdaa1284c..cf16d5e44f 100644 --- a/src/util/fees.cpp +++ b/src/util/fees.cpp @@ -18,7 +18,6 @@ std::string StringForFeeReason(FeeReason reason) { {FeeReason::PAYTXFEE, "PayTxFee set"}, {FeeReason::FALLBACK, "Fallback fee"}, {FeeReason::REQUIRED, "Minimum Required Fee"}, - {FeeReason::MAXTXFEE, "MaxTxFee limit"} }; auto reason_string = fee_reason_strings.find(reason); diff --git a/src/util/system.cpp b/src/util/system.cpp index 6925bda4ef..87ff6e62ba 100644 --- a/src/util/system.cpp +++ b/src/util/system.cpp @@ -1,13 +1,11 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2018 The Bitcoin Core developers +// Copyright (c) 2009-2019 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 <util/system.h> #include <chainparamsbase.h> -#include <random.h> -#include <serialize.h> #include <util/strencodings.h> #include <stdarg.h> @@ -675,7 +673,7 @@ void PrintExceptionContinue(const std::exception* pex, const char* pszThread) { std::string message = FormatException(pex, pszThread); LogPrintf("\n\n************************\n%s\n", message); - fprintf(stderr, "\n\n************************\n%s\n", message.c_str()); + tfm::format(std::cerr, "\n\n************************\n%s\n", message.c_str()); } fs::path GetDefaultDataDir() @@ -707,19 +705,16 @@ fs::path GetDefaultDataDir() static fs::path g_blocks_path_cache_net_specific; static fs::path pathCached; static fs::path pathCachedNetSpecific; -static CCriticalSection csPathCached; +static RecursiveMutex csPathCached; const fs::path &GetBlocksDir() { - LOCK(csPathCached); - fs::path &path = g_blocks_path_cache_net_specific; - // This can be called during exceptions by LogPrintf(), so we cache the - // value so we don't have to do memory allocations after that. - if (!path.empty()) - return path; + // Cache the path to avoid calling fs::create_directories on every call of + // this function + if (!path.empty()) return path; if (gArgs.IsArgSet("-blocksdir")) { path = fs::system_complete(gArgs.GetArg("-blocksdir", "")); @@ -739,15 +734,12 @@ const fs::path &GetBlocksDir() const fs::path &GetDataDir(bool fNetSpecific) { - LOCK(csPathCached); - fs::path &path = fNetSpecific ? pathCachedNetSpecific : pathCached; - // This can be called during exceptions by LogPrintf(), so we cache the - // value so we don't have to do memory allocations after that. - if (!path.empty()) - return path; + // Cache the path to avoid calling fs::create_directories on every call of + // this function + if (!path.empty()) return path; if (gArgs.IsArgSet("-datadir")) { path = fs::system_complete(gArgs.GetArg("-datadir", "")); @@ -935,7 +927,7 @@ bool ArgsManager::ReadConfigFiles(std::string& error, bool ignore_invalid_keys) } } for (const std::string& to_include : includeconf) { - fprintf(stderr, "warning: -includeconf cannot be used from included files; ignoring -includeconf=%s\n", to_include.c_str()); + tfm::format(std::cerr, "warning: -includeconf cannot be used from included files; ignoring -includeconf=%s\n", to_include.c_str()); } } } diff --git a/src/util/system.h b/src/util/system.h index 1a83cb67b1..15d7b1b402 100644 --- a/src/util/system.h +++ b/src/util/system.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2018 The Bitcoin Core developers +// Copyright (c) 2009-2019 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -20,18 +20,16 @@ #include <fs.h> #include <logging.h> #include <sync.h> -#include <util/threadnames.h> #include <tinyformat.h> #include <util/memory.h> +#include <util/threadnames.h> #include <util/time.h> -#include <atomic> #include <exception> #include <map> #include <set> #include <stdint.h> #include <string> -#include <unordered_set> #include <utility> #include <vector> @@ -85,6 +83,7 @@ fs::path GetDefaultDataDir(); // The blocks directory is always net specific. const fs::path &GetBlocksDir(); const fs::path &GetDataDir(bool fNetSpecific = true); +/** Tests only */ void ClearDatadirCache(); fs::path GetConfigFile(const std::string& confPath); #ifdef WIN32 diff --git a/src/validation.cpp b/src/validation.cpp index 6fd7964647..c6995ed24b 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -20,7 +20,6 @@ #include <index/txindex.h> #include <policy/fees.h> #include <policy/policy.h> -#include <policy/rbf.h> #include <policy/settings.h> #include <pow.h> #include <primitives/block.h> @@ -78,7 +77,7 @@ bool CBlockIndexWorkComparator::operator()(const CBlockIndex *pa, const CBlockIn return false; } -CChainState g_chainstate; +static CChainState g_chainstate; CChainState& ChainstateActive() { return g_chainstate; } @@ -112,7 +111,6 @@ bool fCheckpointsEnabled = DEFAULT_CHECKPOINTS_ENABLED; size_t nCoinCacheUsage = 5000 * 300; uint64_t nPruneTarget = 0; int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE; -bool fEnableReplacement = DEFAULT_ENABLE_REPLACEMENT; uint256 hashAssumeValid; arith_uint256 nMinimumChainWork; @@ -306,7 +304,8 @@ bool CheckSequenceLocks(const CTxMemPool& pool, const CTransaction& tx, int flag // Returns the script flags which should be checked for a given block static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const Consensus::Params& chainparams); -static void LimitMempoolSize(CTxMemPool& pool, size_t limit, unsigned long age) { +static void LimitMempoolSize(CTxMemPool& pool, size_t limit, unsigned long age) EXCLUSIVE_LOCKS_REQUIRED(pool.cs) +{ int expired = pool.Expire(GetTime() - age); if (expired != 0) { LogPrint(BCLog::MEMPOOL, "Expired %i transactions from the memory pool\n", expired); @@ -343,7 +342,7 @@ static bool IsCurrentForFeeEstimation() EXCLUSIVE_LOCKS_REQUIRED(cs_main) * and instead just erase from the mempool as needed. */ -static void UpdateMempoolForReorg(DisconnectedBlockTransactions &disconnectpool, bool fAddToMempool) EXCLUSIVE_LOCKS_REQUIRED(cs_main) +static void UpdateMempoolForReorg(DisconnectedBlockTransactions& disconnectpool, bool fAddToMempool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, ::mempool.cs) { AssertLockHeld(cs_main); std::vector<uint256> vHashUpdate; @@ -487,15 +486,12 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool // unconfirmed ancestors anyway; doing otherwise is hopelessly // insecure. bool fReplacementOptOut = true; - if (fEnableReplacement) + for (const CTxIn &_txin : ptxConflicting->vin) { - for (const CTxIn &_txin : ptxConflicting->vin) + if (_txin.nSequence <= MAX_BIP125_RBF_SEQUENCE) { - if (_txin.nSequence <= MAX_BIP125_RBF_SEQUENCE) - { - fReplacementOptOut = false; - break; - } + fReplacementOptOut = false; + break; } } if (fReplacementOptOut) { @@ -1049,7 +1045,7 @@ bool CChainState::IsInitialBlockDownload() const return false; } -CBlockIndex *pindexBestForkTip = nullptr, *pindexBestForkBase = nullptr; +static CBlockIndex *pindexBestForkTip = nullptr, *pindexBestForkBase = nullptr; static void AlertNotify(const std::string& strMessage) { @@ -1379,20 +1375,22 @@ bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex* pindex) } /** Abort with a message */ -static bool AbortNode(const std::string& strMessage, const std::string& userMessage="") +static bool AbortNode(const std::string& strMessage, const std::string& userMessage = "", unsigned int prefix = 0) { SetMiscWarning(strMessage); LogPrintf("*** %s\n", strMessage); - uiInterface.ThreadSafeMessageBox( - userMessage.empty() ? _("Error: A fatal internal error occurred, see debug.log for details") : userMessage, - "", CClientUIInterface::MSG_ERROR); + if (!userMessage.empty()) { + uiInterface.ThreadSafeMessageBox(userMessage, "", CClientUIInterface::MSG_ERROR | prefix); + } else { + uiInterface.ThreadSafeMessageBox(_("Error: A fatal internal error occurred, see debug.log for details"), "", CClientUIInterface::MSG_ERROR | CClientUIInterface::MSG_NOPREFIX); + } StartShutdown(); return false; } -static bool AbortNode(CValidationState& state, const std::string& strMessage, const std::string& userMessage="") +static bool AbortNode(CValidationState& state, const std::string& strMessage, const std::string& userMessage = "", unsigned int prefix = 0) { - AbortNode(strMessage, userMessage); + AbortNode(strMessage, userMessage, prefix); return state.Error(strMessage); } @@ -2003,7 +2001,7 @@ bool CChainState::FlushStateToDisk( if (fDoFullFlush || fPeriodicWrite) { // Depend on nMinDiskSpace to ensure we can write block index if (!CheckDiskSpace(GetBlocksDir())) { - return AbortNode(state, "Disk space is low!", _("Error: Disk space is low!")); + return AbortNode(state, "Disk space is too low!", _("Error: Disk space is too low!"), CClientUIInterface::MSG_NOPREFIX); } // First make sure all block and undo data is flushed to disk. FlushBlockFile(); @@ -2038,7 +2036,7 @@ bool CChainState::FlushStateToDisk( // an overestimation, as most will delete an existing entry or // overwrite one. Still, use a conservative safety factor of 2. if (!CheckDiskSpace(GetDataDir(), 48 * 2 * 2 * pcoinsTip->GetCacheSize())) { - return AbortNode(state, "Disk space is low!", _("Error: Disk space is low!")); + return AbortNode(state, "Disk space is too low!", _("Error: Disk space is too low!"), CClientUIInterface::MSG_NOPREFIX); } // Flush the chainstate (which may refer to block index entries). if (!pcoinsTip->Flush()) @@ -2550,7 +2548,7 @@ bool CChainState::ActivateBestChain(CValidationState &state, const CChainParams& LimitValidationInterfaceQueue(); { - LOCK(cs_main); + LOCK2(cs_main, ::mempool.cs); // Lock transaction pool for at least as long as it takes for connectTrace to be consumed CBlockIndex* starting_tip = m_chain.Tip(); bool blocks_connected = false; do { @@ -2670,6 +2668,7 @@ bool CChainState::InvalidateBlock(CValidationState& state, const CChainParams& c LimitValidationInterfaceQueue(); LOCK(cs_main); + LOCK(::mempool.cs); // Lock for as long as disconnectpool is in scope to make sure UpdateMempoolForReorg is called after DisconnectTip without unlocking in between if (!m_chain.Contains(pindex)) break; pindex_was_in_chain = true; CBlockIndex *invalid_walk_tip = m_chain.Tip(); @@ -2904,7 +2903,7 @@ static bool FindBlockPos(FlatFilePos &pos, unsigned int nAddSize, unsigned int n bool out_of_space; size_t bytes_allocated = BlockFileSeq().Allocate(pos, nAddSize, out_of_space); if (out_of_space) { - return AbortNode("Disk space is low!", _("Error: Disk space is low!")); + return AbortNode("Disk space is too low!", _("Error: Disk space is too low!"), CClientUIInterface::MSG_NOPREFIX); } if (bytes_allocated != 0 && fPruneMode) { fCheckForPruning = true; @@ -2928,7 +2927,7 @@ static bool FindUndoPos(CValidationState &state, int nFile, FlatFilePos &pos, un bool out_of_space; size_t bytes_allocated = UndoFileSeq().Allocate(pos, nAddSize, out_of_space); if (out_of_space) { - return AbortNode(state, "Disk space is low!", _("Error: Disk space is low!")); + return AbortNode(state, "Disk space is too low!", _("Error: Disk space is too low!"), CClientUIInterface::MSG_NOPREFIX); } if (bytes_allocated != 0 && fPruneMode) { fCheckForPruning = true; @@ -4103,7 +4102,7 @@ bool CChainState::RewindBlockIndex(const CChainParams& params) // Loop until the tip is below nHeight, or we reach a pruned block. while (!ShutdownRequested()) { { - LOCK(cs_main); + LOCK2(cs_main, ::mempool.cs); // Make sure nothing changed from under us (this won't happen because RewindBlockIndex runs before importing/network are active) assert(tip == m_chain.Tip()); if (tip == nullptr || tip->nHeight < nHeight) break; @@ -4762,4 +4761,5 @@ public: delete (*it1).second; mapBlockIndex.clear(); } -} instance_of_cmaincleanup; +}; +static CMainCleanup instance_of_cmaincleanup; diff --git a/src/validation.h b/src/validation.h index 963439d35b..9573d62048 100644 --- a/src/validation.h +++ b/src/validation.h @@ -18,6 +18,7 @@ #include <protocol.h> // For CMessageHeader::MessageStartChars #include <script/script_error.h> #include <sync.h> +#include <txmempool.h> // For CTxMemPool::cs #include <versionbits.h> #include <algorithm> @@ -116,8 +117,6 @@ static const char* const DEFAULT_BLOCKFILTERINDEX = "0"; static const unsigned int DEFAULT_BANSCORE_THRESHOLD = 100; /** Default for -persistmempool */ static const bool DEFAULT_PERSIST_MEMPOOL = true; -/** Default for -mempoolreplacement */ -static const bool DEFAULT_ENABLE_REPLACEMENT = true; /** Default for using fee filter */ static const bool DEFAULT_FEEFILTER = true; @@ -160,7 +159,6 @@ extern size_t nCoinCacheUsage; extern CFeeRate minRelayTxFee; /** If the tip is older than this (in seconds), the node is considered to be in initial block download. */ extern int64_t nMaxTipAge; -extern bool fEnableReplacement; /** Block hash whose ancestors we will assume to have valid scripts without checking them. */ extern uint256 hashAssumeValid; @@ -556,7 +554,7 @@ public: CCoinsViewCache& view, const CChainParams& chainparams, bool fJustCheck = false) EXCLUSIVE_LOCKS_REQUIRED(cs_main); // Block disconnection on our pcoinsTip: - bool DisconnectTip(CValidationState& state, const CChainParams& chainparams, DisconnectedBlockTransactions* disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main); + bool DisconnectTip(CValidationState& state, const CChainParams& chainparams, DisconnectedBlockTransactions* disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, ::mempool.cs); // Manual block validity manipulation: bool PreciousBlock(CValidationState& state, const CChainParams& params, CBlockIndex* pindex) LOCKS_EXCLUDED(cs_main); @@ -575,8 +573,8 @@ public: bool IsInitialBlockDownload() const; private: - bool ActivateBestChainStep(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexMostWork, const std::shared_ptr<const CBlock>& pblock, bool& fInvalidFound, ConnectTrace& connectTrace) EXCLUSIVE_LOCKS_REQUIRED(cs_main); - bool ConnectTip(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexNew, const std::shared_ptr<const CBlock>& pblock, ConnectTrace& connectTrace, DisconnectedBlockTransactions &disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main); + bool ActivateBestChainStep(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexMostWork, const std::shared_ptr<const CBlock>& pblock, bool& fInvalidFound, ConnectTrace& connectTrace) EXCLUSIVE_LOCKS_REQUIRED(cs_main, ::mempool.cs); + bool ConnectTip(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexNew, const std::shared_ptr<const CBlock>& pblock, ConnectTrace& connectTrace, DisconnectedBlockTransactions& disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, ::mempool.cs); CBlockIndex* AddToBlockIndex(const CBlockHeader& block) EXCLUSIVE_LOCKS_REQUIRED(cs_main); /** Create a new block index entry for a given block hash */ diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp index 5d0ee1d1fc..59a620ab95 100644 --- a/src/validationinterface.cpp +++ b/src/validationinterface.cpp @@ -8,8 +8,6 @@ #include <primitives/block.h> #include <scheduler.h> #include <txmempool.h> -#include <util/system.h> -#include <validation.h> #include <list> #include <atomic> diff --git a/src/validationinterface.h b/src/validationinterface.h index ea1b2e7e76..3ce617b827 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -16,7 +16,6 @@ extern CCriticalSection cs_main; class CBlock; class CBlockIndex; struct CBlockLocator; -class CBlockIndex; class CConnman; class CValidationInterface; class CValidationState; diff --git a/src/wallet/coincontrol.cpp b/src/wallet/coincontrol.cpp index 87d2c4f06e..60bce66839 100644 --- a/src/wallet/coincontrol.cpp +++ b/src/wallet/coincontrol.cpp @@ -13,6 +13,7 @@ void CCoinControl::SetNull() fAllowOtherInputs = false; fAllowWatchOnly = false; m_avoid_partial_spends = gArgs.GetBoolArg("-avoidpartialspends", DEFAULT_AVOIDPARTIALSPENDS); + m_avoid_address_reuse = false; setSelected.clear(); m_feerate.reset(); fOverrideFeeRate = false; diff --git a/src/wallet/coincontrol.h b/src/wallet/coincontrol.h index 12ba032dff..249c402e4d 100644 --- a/src/wallet/coincontrol.h +++ b/src/wallet/coincontrol.h @@ -34,6 +34,8 @@ public: boost::optional<bool> m_signal_bip125_rbf; //! Avoid partial use of funds sent to a given address bool m_avoid_partial_spends; + //! Forbids inclusion of dirty (previously used) addresses + bool m_avoid_address_reuse; //! Fee estimation mode to control arguments to estimateSmartFee FeeEstimateMode m_fee_mode; //! Minimum chain depth value for coin availability diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index 8633d8701b..b5f90deabd 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -5,11 +5,7 @@ #include <wallet/db.h> -#include <addrman.h> -#include <hash.h> -#include <protocol.h> #include <util/strencodings.h> -#include <wallet/walletutil.h> #include <stdint.h> diff --git a/src/wallet/feebumper.cpp b/src/wallet/feebumper.cpp index 15ddd5cb97..46cf6b7616 100644 --- a/src/wallet/feebumper.cpp +++ b/src/wallet/feebumper.cpp @@ -10,14 +10,10 @@ #include <wallet/wallet.h> #include <policy/fees.h> #include <policy/policy.h> -#include <policy/rbf.h> -#include <validation.h> //for mempool access -#include <txmempool.h> #include <util/moneystr.h> #include <util/rbf.h> #include <util/system.h> #include <util/validation.h> -#include <net.h> //! Check whether transaction has descendant in wallet or mempool, or has been //! mined, or conflicts with a mined transaction. Return a feebumper::Result. diff --git a/src/wallet/fees.cpp b/src/wallet/fees.cpp index 59d05a771a..2792058f2a 100644 --- a/src/wallet/fees.cpp +++ b/src/wallet/fees.cpp @@ -5,9 +5,7 @@ #include <wallet/fees.h> -#include <policy/policy.h> #include <util/system.h> -#include <validation.h> #include <wallet/coincontrol.h> #include <wallet/wallet.h> @@ -20,14 +18,7 @@ CAmount GetRequiredFee(const CWallet& wallet, unsigned int nTxBytes) CAmount GetMinimumFee(const CWallet& wallet, unsigned int nTxBytes, const CCoinControl& coin_control, FeeCalculation* feeCalc) { - CAmount fee_needed = GetMinimumFeeRate(wallet, coin_control, feeCalc).GetFee(nTxBytes); - // Always obey the maximum - const CAmount max_tx_fee = wallet.m_default_max_tx_fee; - if (fee_needed > max_tx_fee) { - fee_needed = max_tx_fee; - if (feeCalc) feeCalc->reason = FeeReason::MAXTXFEE; - } - return fee_needed; + return GetMinimumFeeRate(wallet, coin_control, feeCalc).GetFee(nTxBytes); } CFeeRate GetRequiredFeeRate(const CWallet& wallet) diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp index 0b8afd5a5d..0265433863 100644 --- a/src/wallet/init.cpp +++ b/src/wallet/init.cpp @@ -3,18 +3,13 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include <chainparams.h> #include <init.h> #include <interfaces/chain.h> #include <net.h> -#include <scheduler.h> #include <outputtype.h> -#include <util/error.h> #include <util/system.h> #include <util/moneystr.h> -#include <validation.h> #include <walletinitinterface.h> -#include <wallet/rpcwallet.h> #include <wallet/wallet.h> #include <wallet/walletutil.h> @@ -39,7 +34,7 @@ const WalletInitInterface& g_wallet_init_interface = WalletInit(); void WalletInit::AddWalletOptions() const { gArgs.AddArg("-addresstype", strprintf("What type of addresses to use (\"legacy\", \"p2sh-segwit\", or \"bech32\", default: \"%s\")", FormatOutputType(DEFAULT_ADDRESS_TYPE)), false, OptionsCategory::WALLET); - gArgs.AddArg("-avoidpartialspends", strprintf("Group outputs by address, selecting all or none, instead of selecting on a per-output basis. Privacy is improved as an address is only used once (unless someone sends to it after spending from it), but may result in slightly higher fees as suboptimal coin selection may result due to the added limitation (default: %u)", DEFAULT_AVOIDPARTIALSPENDS), false, OptionsCategory::WALLET); + gArgs.AddArg("-avoidpartialspends", strprintf("Group outputs by address, selecting all or none, instead of selecting on a per-output basis. Privacy is improved as an address is only used once (unless someone sends to it after spending from it), but may result in slightly higher fees as suboptimal coin selection may result due to the added limitation (default: %u (always enabled for wallets with \"avoid_reuse\" enabled))", DEFAULT_AVOIDPARTIALSPENDS), false, OptionsCategory::WALLET); gArgs.AddArg("-changetype", "What type of change to use (\"legacy\", \"p2sh-segwit\", or \"bech32\"). Default is same as -addresstype, except when -addresstype=p2sh-segwit a native segwit output is used when sending to a native segwit address)", false, OptionsCategory::WALLET); gArgs.AddArg("-disablewallet", "Do not load the wallet and disable wallet RPC calls", false, OptionsCategory::WALLET); gArgs.AddArg("-discardfee=<amt>", strprintf("The fee rate (in %s/kB) that indicates your tolerance for discarding change by adding it to the fee (default: %s). " diff --git a/src/script/ismine.cpp b/src/wallet/ismine.cpp index 75fc2e84f1..6138d4ae44 100644 --- a/src/script/ismine.cpp +++ b/src/wallet/ismine.cpp @@ -3,13 +3,12 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include <script/ismine.h> +#include <wallet/ismine.h> #include <key.h> -#include <keystore.h> #include <script/script.h> #include <script/sign.h> - +#include <wallet/wallet.h> typedef std::vector<unsigned char> valtype; @@ -46,7 +45,7 @@ bool PermitsUncompressed(IsMineSigVersion sigversion) return sigversion == IsMineSigVersion::TOP || sigversion == IsMineSigVersion::P2SH; } -bool HaveKeys(const std::vector<valtype>& pubkeys, const CKeyStore& keystore) +bool HaveKeys(const std::vector<valtype>& pubkeys, const CWallet& keystore) { for (const valtype& pubkey : pubkeys) { CKeyID keyID = CPubKey(pubkey).GetID(); @@ -55,7 +54,7 @@ bool HaveKeys(const std::vector<valtype>& pubkeys, const CKeyStore& keystore) return true; } -IsMineResult IsMineInner(const CKeyStore& keystore, const CScript& scriptPubKey, IsMineSigVersion sigversion) +IsMineResult IsMineInner(const CWallet& keystore, const CScript& scriptPubKey, IsMineSigVersion sigversion) { IsMineResult ret = IsMineResult::NO; @@ -172,7 +171,7 @@ IsMineResult IsMineInner(const CKeyStore& keystore, const CScript& scriptPubKey, } // namespace -isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey) +isminetype IsMine(const CWallet& keystore, const CScript& scriptPubKey) { switch (IsMineInner(keystore, scriptPubKey, IsMineSigVersion::TOP)) { case IsMineResult::INVALID: @@ -186,7 +185,7 @@ isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey) assert(false); } -isminetype IsMine(const CKeyStore& keystore, const CTxDestination& dest) +isminetype IsMine(const CWallet& keystore, const CTxDestination& dest) { CScript script = GetScriptForDestination(dest); return IsMine(keystore, script); diff --git a/src/script/ismine.h b/src/wallet/ismine.h index 55e28e225a..41555fcb93 100644 --- a/src/script/ismine.h +++ b/src/wallet/ismine.h @@ -3,31 +3,33 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#ifndef BITCOIN_SCRIPT_ISMINE_H -#define BITCOIN_SCRIPT_ISMINE_H +#ifndef BITCOIN_WALLET_ISMINE_H +#define BITCOIN_WALLET_ISMINE_H #include <script/standard.h> #include <stdint.h> #include <bitset> -class CKeyStore; +class CWallet; class CScript; /** IsMine() return codes */ -enum isminetype +enum isminetype : unsigned int { ISMINE_NO = 0, ISMINE_WATCH_ONLY = 1 << 0, ISMINE_SPENDABLE = 1 << 1, + ISMINE_USED = 1 << 2, ISMINE_ALL = ISMINE_WATCH_ONLY | ISMINE_SPENDABLE, + ISMINE_ALL_USED = ISMINE_ALL | ISMINE_USED, ISMINE_ENUM_ELEMENTS, }; /** used for bitflags of isminetype */ typedef uint8_t isminefilter; -isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey); -isminetype IsMine(const CKeyStore& keystore, const CTxDestination& dest); +isminetype IsMine(const CWallet& wallet, const CScript& scriptPubKey); +isminetype IsMine(const CWallet& wallet, const CTxDestination& dest); /** * Cachable amount subdivided into watchonly and spendable parts. @@ -48,4 +50,4 @@ struct CachableAmount } }; -#endif // BITCOIN_SCRIPT_ISMINE_H +#endif // BITCOIN_WALLET_ISMINE_H diff --git a/src/wallet/psbtwallet.cpp b/src/wallet/psbtwallet.cpp index ce4788dee1..721a244afb 100644 --- a/src/wallet/psbtwallet.cpp +++ b/src/wallet/psbtwallet.cpp @@ -44,16 +44,7 @@ TransactionError FillPSBT(const CWallet* pwallet, PartiallySignedTransaction& ps // Fill in the bip32 keypaths and redeemscripts for the outputs so that hardware wallets can identify change for (unsigned int i = 0; i < psbtx.tx->vout.size(); ++i) { - const CTxOut& out = psbtx.tx->vout.at(i); - PSBTOutput& psbt_out = psbtx.outputs.at(i); - - // Fill a SignatureData with output info - SignatureData sigdata; - psbt_out.FillSignatureData(sigdata); - - MutableTransactionSignatureCreator creator(psbtx.tx.get_ptr(), 0, out.nValue, 1); - ProduceSignature(HidingSigningProvider(pwallet, true, !bip32derivs), creator, out.scriptPubKey, sigdata); - psbt_out.FromSignatureData(sigdata); + UpdatePSBTOutput(HidingSigningProvider(pwallet, true, !bip32derivs), psbtx, i); } return TransactionError::OK; diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index ee1b792f9b..3112dca9f5 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -16,7 +16,6 @@ #include <util/bip32.h> #include <util/system.h> #include <util/time.h> -#include <validation.h> #include <wallet/wallet.h> #include <wallet/rpcwallet.h> @@ -1166,8 +1165,7 @@ static UniValue ProcessImportDescriptor(ImportData& import_data, std::map<CKeyID const UniValue& priv_keys = data.exists("keys") ? data["keys"].get_array() : UniValue(); - // Expand all descriptors to get public keys and scripts. - // TODO: get private keys from descriptors too + // Expand all descriptors to get public keys and scripts, and private keys if available. for (int i = range_start; i <= range_end; ++i) { FlatSigningProvider out_keys; std::vector<CScript> scripts_temp; @@ -1181,7 +1179,10 @@ static UniValue ProcessImportDescriptor(ImportData& import_data, std::map<CKeyID import_data.import_scripts.emplace(x.second); } + parsed_desc->ExpandPrivate(i, keys, out_keys); + std::copy(out_keys.pubkeys.begin(), out_keys.pubkeys.end(), std::inserter(pubkey_map, pubkey_map.end())); + std::copy(out_keys.keys.begin(), out_keys.keys.end(), std::inserter(privkey_map, privkey_map.end())); import_data.key_origins.insert(out_keys.origins.begin(), out_keys.origins.end()); } diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index c158cd4e20..eae5f876ea 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4,33 +4,27 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <amount.h> -#include <chain.h> #include <consensus/validation.h> #include <core_io.h> #include <init.h> #include <interfaces/chain.h> #include <key_io.h> -#include <net.h> #include <node/transaction.h> #include <outputtype.h> #include <policy/feerate.h> #include <policy/fees.h> -#include <policy/policy.h> #include <policy/rbf.h> #include <rpc/rawtransaction_util.h> #include <rpc/server.h> #include <rpc/util.h> #include <script/descriptor.h> #include <script/sign.h> -#include <shutdown.h> -#include <timedata.h> #include <util/bip32.h> #include <util/fees.h> #include <util/moneystr.h> #include <util/system.h> #include <util/url.h> #include <util/validation.h> -#include <validation.h> #include <wallet/coincontrol.h> #include <wallet/feebumper.h> #include <wallet/psbtwallet.h> @@ -47,6 +41,17 @@ static const std::string WALLET_ENDPOINT_BASE = "/wallet/"; +static inline bool GetAvoidReuseFlag(CWallet * const pwallet, const UniValue& param) { + bool can_avoid_reuse = pwallet->IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE); + bool avoid_reuse = param.isNull() ? can_avoid_reuse : param.get_bool(); + + if (avoid_reuse && !can_avoid_reuse) { + throw JSONRPCError(RPC_WALLET_ERROR, "wallet does not have the \"avoid reuse\" feature enabled"); + } + + return avoid_reuse; +} + bool GetWalletNameFromJSONRPCRequest(const JSONRPCRequest& request, std::string& wallet_name) { if (request.URI.substr(0, WALLET_ENDPOINT_BASE.size()) == WALLET_ENDPOINT_BASE) { @@ -310,7 +315,7 @@ static UniValue setlabel(const JSONRPCRequest& request) static CTransactionRef SendMoney(interfaces::Chain::Lock& locked_chain, CWallet * const pwallet, const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, const CCoinControl& coin_control, mapValue_t mapValue) { - CAmount curBalance = pwallet->GetBalance().m_mine_trusted; + CAmount curBalance = pwallet->GetBalance(0, coin_control.m_avoid_address_reuse).m_mine_trusted; // Check amount if (nValue <= 0) @@ -357,7 +362,7 @@ static UniValue sendtoaddress(const JSONRPCRequest& request) return NullUniValue; } - if (request.fHelp || request.params.size() < 2 || request.params.size() > 8) + if (request.fHelp || request.params.size() < 2 || request.params.size() > 9) throw std::runtime_error( RPCHelpMan{"sendtoaddress", "\nSend an amount to a given address." + @@ -378,6 +383,8 @@ static UniValue sendtoaddress(const JSONRPCRequest& request) " \"UNSET\"\n" " \"ECONOMICAL\"\n" " \"CONSERVATIVE\""}, + {"avoid_reuse", RPCArg::Type::BOOL, /* default */ "true", "(only available if avoid_reuse wallet flag is set) Avoid spending from dirty addresses; addresses are considered\n" + " dirty if they have previously been used in a transaction."}, }, RPCResult{ "\"txid\" (string) The transaction id.\n" @@ -434,6 +441,9 @@ static UniValue sendtoaddress(const JSONRPCRequest& request) } } + coin_control.m_avoid_address_reuse = GetAvoidReuseFlag(pwallet, request.params[8]); + // We also enable partial spend avoidance if reuse avoidance is set. + coin_control.m_avoid_partial_spends |= coin_control.m_avoid_address_reuse; EnsureWalletIsUnlocked(pwallet); @@ -723,7 +733,7 @@ static UniValue getbalance(const JSONRPCRequest& request) return NullUniValue; } - if (request.fHelp || (request.params.size() > 3 )) + if (request.fHelp || request.params.size() > 4) throw std::runtime_error( RPCHelpMan{"getbalance", "\nReturns the total available balance.\n" @@ -733,6 +743,7 @@ static UniValue getbalance(const JSONRPCRequest& request) {"dummy", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "Remains for backward compatibility. Must be excluded or set to \"*\"."}, {"minconf", RPCArg::Type::NUM, /* default */ "0", "Only include transactions confirmed at least this many times."}, {"include_watchonly", RPCArg::Type::BOOL, /* default */ "false", "Also include balance in watch-only addresses (see 'importaddress')"}, + {"avoid_reuse", RPCArg::Type::BOOL, /* default */ "true", "(only available if avoid_reuse wallet flag is set) Do not include balance in dirty outputs; addresses are considered dirty if they have previously been used in a transaction."}, }, RPCResult{ "amount (numeric) The total amount in " + CURRENCY_UNIT + " received for this wallet.\n" @@ -769,7 +780,9 @@ static UniValue getbalance(const JSONRPCRequest& request) include_watchonly = true; } - const auto bal = pwallet->GetBalance(min_depth); + bool avoid_reuse = GetAvoidReuseFlag(pwallet, request.params[3]); + + const auto bal = pwallet->GetBalance(min_depth, avoid_reuse); return ValueFromAmount(bal.m_mine_trusted + (include_watchonly ? bal.m_watchonly_trusted : 0)); } @@ -1023,8 +1036,8 @@ static UniValue addmultisigaddress(const JSONRPCRequest& request) } // Construct using pay-to-script-hash: - CScript inner = CreateMultisigRedeemscript(required, pubkeys); - CTxDestination dest = AddAndGetDestinationForScript(*pwallet, inner, output_type); + CScript inner; + CTxDestination dest = AddAndGetMultisigDestination(required, pubkeys, output_type, *pwallet, inner); pwallet->SetAddressBook(dest, label, "send"); UniValue result(UniValue::VOBJ); @@ -2396,6 +2409,7 @@ static UniValue getbalances(const JSONRPCRequest& request) " \"trusted\": xxx (numeric) trusted balance (outputs created by the wallet or confirmed outputs)\n" " \"untrusted_pending\": xxx (numeric) untrusted pending balance (outputs created by others that are in the mempool)\n" " \"immature\": xxx (numeric) balance from immature coinbase outputs\n" + " \"used\": xxx (numeric) (only present if avoid_reuse is set) balance from coins sent to addresses that were previously spent from (potentially privacy violating)\n" " },\n" " \"watchonly\": { (object) watchonly balances (not present if wallet does not watch anything)\n" " \"trusted\": xxx (numeric) trusted balance (outputs created by the wallet or confirmed outputs)\n" @@ -2428,6 +2442,12 @@ static UniValue getbalances(const JSONRPCRequest& request) balances_mine.pushKV("trusted", ValueFromAmount(bal.m_mine_trusted)); balances_mine.pushKV("untrusted_pending", ValueFromAmount(bal.m_mine_untrusted_pending)); balances_mine.pushKV("immature", ValueFromAmount(bal.m_mine_immature)); + if (wallet.IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE)) { + // If the AVOID_REUSE flag is set, bal has been set to just the un-reused address balance. Get + // the total balance, and then subtract bal to get the reused address balance. + const auto full_bal = wallet.GetBalance(0, false); + balances_mine.pushKV("used", ValueFromAmount(full_bal.m_mine_trusted + full_bal.m_mine_untrusted_pending - bal.m_mine_trusted - bal.m_mine_untrusted_pending)); + } balances.pushKV("mine", balances_mine); } if (wallet.HaveWatchOnly()) { @@ -2467,6 +2487,7 @@ static UniValue getwalletinfo(const JSONRPCRequest& request) " \"paytxfee\": x.xxxx, (numeric) the transaction fee configuration, set in " + CURRENCY_UNIT + "/kB\n" " \"hdseedid\": \"<hash160>\" (string, optional) the Hash160 of the HD seed (only present when HD is enabled)\n" " \"private_keys_enabled\": true|false (boolean) false if privatekeys are disabled for this wallet (enforced watch-only wallet)\n" + " \"avoid_reuse\": true|false (boolean) whether this wallet tracks clean/dirty coins in terms of reuse\n" " \"scanning\": (json object) current scanning details, or false if no scan is in progress\n" " {\n" " \"duration\" : xxxx (numeric) elapsed seconds since scan start\n" @@ -2515,6 +2536,7 @@ static UniValue getwalletinfo(const JSONRPCRequest& request) obj.pushKV("hdseedid", seed_id.GetHex()); } obj.pushKV("private_keys_enabled", !pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)); + obj.pushKV("avoid_reuse", pwallet->IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE)); if (pwallet->IsScanning()) { UniValue scanning(UniValue::VOBJ); scanning.pushKV("duration", pwallet->ScanningDuration() / 1000); @@ -2643,6 +2665,76 @@ static UniValue loadwallet(const JSONRPCRequest& request) return obj; } +static UniValue setwalletflag(const JSONRPCRequest& request) +{ + std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); + CWallet* const pwallet = wallet.get(); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { + return NullUniValue; + } + + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) { + std::string flags = ""; + for (auto& it : WALLET_FLAG_MAP) + if (it.second & MUTABLE_WALLET_FLAGS) + flags += (flags == "" ? "" : ", ") + it.first; + throw std::runtime_error( + RPCHelpMan{"setwalletflag", + "\nChange the state of the given wallet flag for a wallet.\n", + { + {"flag", RPCArg::Type::STR, RPCArg::Optional::NO, "The name of the flag to change. Current available flags: " + flags}, + {"value", RPCArg::Type::BOOL, /* default */ "true", "The new state."}, + }, + RPCResult{ + "{\n" + " \"flag_name\": string (string) The name of the flag that was modified\n" + " \"flag_state\": bool (bool) The new state of the flag\n" + " \"warnings\": string (string) Any warnings associated with the change\n" + "}\n" + }, + RPCExamples{ + HelpExampleCli("setwalletflag", "avoid_reuse") + + HelpExampleRpc("setwalletflag", "\"avoid_reuse\"") + }, + }.ToString()); + } + + std::string flag_str = request.params[0].get_str(); + bool value = request.params[1].isNull() || request.params[1].get_bool(); + + if (!WALLET_FLAG_MAP.count(flag_str)) { + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Unknown wallet flag: %s", flag_str)); + } + + auto flag = WALLET_FLAG_MAP.at(flag_str); + + if (!(flag & MUTABLE_WALLET_FLAGS)) { + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Wallet flag is immutable: %s", flag_str)); + } + + UniValue res(UniValue::VOBJ); + + if (pwallet->IsWalletFlagSet(flag) == value) { + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Wallet flag is already set to %s: %s", value ? "true" : "false", flag_str)); + } + + res.pushKV("flag_name", flag_str); + res.pushKV("flag_state", value); + + if (value) { + pwallet->SetWalletFlag(flag); + } else { + pwallet->UnsetWalletFlag(flag); + } + + if (flag && value && WALLET_FLAG_CAVEATS.count(flag)) { + res.pushKV("warnings", WALLET_FLAG_CAVEATS.at(flag)); + } + + return res; +} + static UniValue createwallet(const JSONRPCRequest& request) { const RPCHelpMan help{ @@ -2653,6 +2745,7 @@ static UniValue createwallet(const JSONRPCRequest& request) {"disable_private_keys", RPCArg::Type::BOOL, /* default */ "false", "Disable the possibility of private keys (only watchonlys are possible in this mode)."}, {"blank", RPCArg::Type::BOOL, /* default */ "false", "Create a blank wallet. A blank wallet has no keys or HD seed. One can be set using sethdseed."}, {"passphrase", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "Encrypt the wallet with this passphrase."}, + {"avoid_reuse", RPCArg::Type::BOOL, /* default */ "false", "Keep track of coin reuse, and treat dirty and clean coins differently with privacy considerations in mind."}, }, RPCResult{ "{\n" @@ -2694,6 +2787,10 @@ static UniValue createwallet(const JSONRPCRequest& request) flags |= WALLET_FLAG_BLANK_WALLET; } + if (!request.params[4].isNull() && request.params[4].get_bool()) { + flags |= WALLET_FLAG_AVOID_REUSE; + } + WalletLocation location(request.params[0].get_str()); if (location.Exists()) { throw JSONRPCError(RPC_WALLET_ERROR, "Wallet " + location.GetName() + " already exists."); @@ -2795,9 +2892,8 @@ static UniValue listunspent(const JSONRPCRequest& request) return NullUniValue; } - if (request.fHelp || request.params.size() > 5) - throw std::runtime_error( - RPCHelpMan{"listunspent", + const RPCHelpMan help{ + "listunspent", "\nReturns array of unspent transaction outputs\n" "with between minconf and maxconf (inclusive) confirmations.\n" "Optionally filter to only include txouts paid to specified addresses.\n", @@ -2834,6 +2930,7 @@ static UniValue listunspent(const JSONRPCRequest& request) " \"witnessScript\" : \"script\" (string) witnessScript if the scriptPubKey is P2WSH or P2SH-P2WSH\n" " \"spendable\" : xxx, (bool) Whether we have the private keys to spend this output\n" " \"solvable\" : xxx, (bool) Whether we know how to spend this output, ignoring the lack of keys\n" + " \"reused\" : xxx, (bool) (only present if avoid_reuse is set) Whether this output is reused/dirty (sent to an address that was previously spent from)\n" " \"desc\" : xxx, (string, only when solvable) A descriptor for spending this output\n" " \"safe\" : xxx (bool) Whether this output is considered safe to spend. Unconfirmed transactions\n" " from outside keys and unconfirmed replacement transactions are considered unsafe\n" @@ -2849,7 +2946,11 @@ static UniValue listunspent(const JSONRPCRequest& request) + HelpExampleCli("listunspent", "6 9999999 '[]' true '{ \"minimumAmount\": 0.005 }'") + HelpExampleRpc("listunspent", "6, 9999999, [] , true, { \"minimumAmount\": 0.005 } ") }, - }.ToString()); + }; + + if (request.fHelp || !help.IsValidNumArgs(request.params.size())) { + throw std::runtime_error(help.ToString()); + } int nMinDepth = 1; if (!request.params[0].isNull()) { @@ -2913,17 +3014,22 @@ static UniValue listunspent(const JSONRPCRequest& request) UniValue results(UniValue::VARR); std::vector<COutput> vecOutputs; { + CCoinControl cctl; + cctl.m_avoid_address_reuse = false; auto locked_chain = pwallet->chain().lock(); LOCK(pwallet->cs_wallet); - pwallet->AvailableCoins(*locked_chain, vecOutputs, !include_unsafe, nullptr, nMinimumAmount, nMaximumAmount, nMinimumSumAmount, nMaximumCount, nMinDepth, nMaxDepth); + pwallet->AvailableCoins(*locked_chain, vecOutputs, !include_unsafe, &cctl, nMinimumAmount, nMaximumAmount, nMinimumSumAmount, nMaximumCount, nMinDepth, nMaxDepth); } LOCK(pwallet->cs_wallet); + const bool avoid_reuse = pwallet->IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE); + for (const COutput& out : vecOutputs) { CTxDestination address; const CScript& scriptPubKey = out.tx->tx->vout[out.i].scriptPubKey; bool fValidAddress = ExtractDestination(scriptPubKey, address); + bool reused = avoid_reuse && pwallet->IsUsedDestination(address); if (destinations.size() && (!fValidAddress || !destinations.count(address))) continue; @@ -2980,6 +3086,7 @@ static UniValue listunspent(const JSONRPCRequest& request) auto descriptor = InferDescriptor(scriptPubKey, *pwallet); entry.pushKV("desc", descriptor->ToString()); } + if (avoid_reuse) entry.pushKV("reused", reused); entry.pushKV("safe", out.fSafe); results.push_back(entry); } @@ -3112,9 +3219,7 @@ static UniValue fundrawtransaction(const JSONRPCRequest& request) return NullUniValue; } - if (request.fHelp || request.params.size() < 1 || request.params.size() > 3) - throw std::runtime_error( - RPCHelpMan{"fundrawtransaction", + const RPCHelpMan help{"fundrawtransaction", "\nAdd inputs to a transaction until it has enough in value to meet its out value.\n" "This will not modify existing inputs, and will add at most one change output to the outputs.\n" "No existing outputs will be modified unless \"subtractFeeFromOutputs\" is specified.\n" @@ -3153,8 +3258,13 @@ static UniValue fundrawtransaction(const JSONRPCRequest& request) " \"CONSERVATIVE\""}, }, "options"}, - {"iswitness", RPCArg::Type::BOOL, /* default */ "depends on heuristic tests", "Whether the transaction hex is a serialized witness transaction \n" - " If iswitness is not present, heuristic tests will be used in decoding"}, + {"iswitness", RPCArg::Type::BOOL, /* default */ "depends on heuristic tests", "Whether the transaction hex is a serialized witness transaction.\n" + "If iswitness is not present, heuristic tests will be used in decoding.\n" + "If true, only witness deserialization will be tried.\n" + "If false, only non-witness deserialization will be tried.\n" + "This boolean should reflect whether the transaction has inputs\n" + "(e.g. fully valid, or on-chain transactions), if known by the caller." + }, }, RPCResult{ "{\n" @@ -3173,7 +3283,11 @@ static UniValue fundrawtransaction(const JSONRPCRequest& request) "\nSend the transaction\n" + HelpExampleCli("sendrawtransaction", "\"signedtransactionhex\"") }, - }.ToString()); + }; + + if (request.fHelp || !help.IsValidNumArgs(request.params.size())) { + throw std::runtime_error(help.ToString()); + } RPCTypeCheck(request.params, {UniValue::VSTR, UniValueType(), UniValue::VBOOL}); @@ -4184,13 +4298,13 @@ static const CRPCCommand commands[] = { "wallet", "addmultisigaddress", &addmultisigaddress, {"nrequired","keys","label","address_type"} }, { "wallet", "backupwallet", &backupwallet, {"destination"} }, { "wallet", "bumpfee", &bumpfee, {"txid", "options"} }, - { "wallet", "createwallet", &createwallet, {"wallet_name", "disable_private_keys", "blank", "passphrase"} }, + { "wallet", "createwallet", &createwallet, {"wallet_name", "disable_private_keys", "blank", "passphrase", "avoid_reuse"} }, { "wallet", "dumpprivkey", &dumpprivkey, {"address"} }, { "wallet", "dumpwallet", &dumpwallet, {"filename"} }, { "wallet", "encryptwallet", &encryptwallet, {"passphrase"} }, { "wallet", "getaddressesbylabel", &getaddressesbylabel, {"label"} }, { "wallet", "getaddressinfo", &getaddressinfo, {"address"} }, - { "wallet", "getbalance", &getbalance, {"dummy","minconf","include_watchonly"} }, + { "wallet", "getbalance", &getbalance, {"dummy","minconf","include_watchonly","avoid_reuse"} }, { "wallet", "getnewaddress", &getnewaddress, {"label","address_type"} }, { "wallet", "getrawchangeaddress", &getrawchangeaddress, {"address_type"} }, { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, {"address","minconf"} }, @@ -4221,10 +4335,11 @@ static const CRPCCommand commands[] = { "wallet", "removeprunedfunds", &removeprunedfunds, {"txid"} }, { "wallet", "rescanblockchain", &rescanblockchain, {"start_height", "stop_height"} }, { "wallet", "sendmany", &sendmany, {"dummy","amounts","minconf","comment","subtractfeefrom","replaceable","conf_target","estimate_mode"} }, - { "wallet", "sendtoaddress", &sendtoaddress, {"address","amount","comment","comment_to","subtractfeefromamount","replaceable","conf_target","estimate_mode"} }, + { "wallet", "sendtoaddress", &sendtoaddress, {"address","amount","comment","comment_to","subtractfeefromamount","replaceable","conf_target","estimate_mode","avoid_reuse"} }, { "wallet", "sethdseed", &sethdseed, {"newkeypool","seed"} }, { "wallet", "setlabel", &setlabel, {"address","label"} }, { "wallet", "settxfee", &settxfee, {"amount"} }, + { "wallet", "setwalletflag", &setwalletflag, {"flag","value"} }, { "wallet", "signmessage", &signmessage, {"address","message"} }, { "wallet", "signrawtransactionwithwallet", &signrawtransactionwithwallet, {"hexstring","prevtxs","sighashtype"} }, { "wallet", "unloadwallet", &unloadwallet, {"wallet_name"} }, diff --git a/src/wallet/test/db_tests.cpp b/src/wallet/test/db_tests.cpp index e4950af4e5..c961456572 100644 --- a/src/wallet/test/db_tests.cpp +++ b/src/wallet/test/db_tests.cpp @@ -16,7 +16,7 @@ BOOST_FIXTURE_TEST_SUITE(db_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(getwalletenv_file) { std::string test_name = "test_name.dat"; - fs::path datadir = SetDataDir("tempdir"); + const fs::path datadir = GetDataDir(); fs::path file_path = datadir / test_name; std::ofstream f(file_path.BOOST_FILESYSTEM_C_STR); f.close(); @@ -30,7 +30,7 @@ BOOST_AUTO_TEST_CASE(getwalletenv_file) BOOST_AUTO_TEST_CASE(getwalletenv_directory) { std::string expected_name = "wallet.dat"; - fs::path datadir = SetDataDir("tempdir"); + const fs::path datadir = GetDataDir(); std::string filename; std::shared_ptr<BerkeleyEnvironment> env = GetWalletEnv(datadir, filename); @@ -40,8 +40,8 @@ BOOST_AUTO_TEST_CASE(getwalletenv_directory) BOOST_AUTO_TEST_CASE(getwalletenv_g_dbenvs_multiple) { - fs::path datadir = SetDataDir("tempdir"); - fs::path datadir_2 = SetDataDir("tempdir_2"); + fs::path datadir = GetDataDir() / "1"; + fs::path datadir_2 = GetDataDir() / "2"; std::string filename; std::shared_ptr<BerkeleyEnvironment> env_1 = GetWalletEnv(datadir, filename); @@ -54,8 +54,8 @@ BOOST_AUTO_TEST_CASE(getwalletenv_g_dbenvs_multiple) BOOST_AUTO_TEST_CASE(getwalletenv_g_dbenvs_free_instance) { - fs::path datadir = SetDataDir("tempdir"); - fs::path datadir_2 = SetDataDir("tempdir_2"); + fs::path datadir = GetDataDir() / "1"; + fs::path datadir_2 = GetDataDir() / "2"; std::string filename; std::shared_ptr <BerkeleyEnvironment> env_1_a = GetWalletEnv(datadir, filename); diff --git a/src/wallet/test/init_test_fixture.cpp b/src/wallet/test/init_test_fixture.cpp index 3b828d57f9..86ba0013fe 100644 --- a/src/wallet/test/init_test_fixture.cpp +++ b/src/wallet/test/init_test_fixture.cpp @@ -3,6 +3,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <fs.h> +#include <util/system.h> #include <wallet/test/init_test_fixture.h> @@ -13,7 +14,7 @@ InitWalletDirTestingSetup::InitWalletDirTestingSetup(const std::string& chainNam std::string sep; sep += fs::path::preferred_separator; - m_datadir = SetDataDir("tempdir"); + m_datadir = GetDataDir(); m_cwd = fs::current_path(); m_walletdir_path_cases["default"] = m_datadir / "wallets"; @@ -41,4 +42,4 @@ InitWalletDirTestingSetup::~InitWalletDirTestingSetup() void InitWalletDirTestingSetup::SetWalletDir(const fs::path& walletdir_path) { gArgs.ForceSetArg("-walletdir", walletdir_path.string()); -}
\ No newline at end of file +} diff --git a/src/wallet/test/init_tests.cpp b/src/wallet/test/init_tests.cpp index 9e5208b453..1816fca257 100644 --- a/src/wallet/test/init_tests.cpp +++ b/src/wallet/test/init_tests.cpp @@ -5,13 +5,9 @@ #include <boost/test/unit_test.hpp> #include <test/setup_common.h> +#include <util/system.h> #include <wallet/test/init_test_fixture.h> -#include <init.h> -#include <walletinitinterface.h> -#include <wallet/wallet.h> - - BOOST_FIXTURE_TEST_SUITE(init_tests, InitWalletDirTestingSetup) BOOST_AUTO_TEST_CASE(walletinit_verify_walletdir_default) diff --git a/src/wallet/test/ismine_tests.cpp b/src/wallet/test/ismine_tests.cpp new file mode 100644 index 0000000000..062fef7748 --- /dev/null +++ b/src/wallet/test/ismine_tests.cpp @@ -0,0 +1,398 @@ +// Copyright (c) 2017-2019 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 <key.h> +#include <script/script.h> +#include <script/standard.h> +#include <test/setup_common.h> +#include <wallet/ismine.h> +#include <wallet/wallet.h> + +#include <boost/test/unit_test.hpp> + + +BOOST_FIXTURE_TEST_SUITE(ismine_tests, BasicTestingSetup) + +BOOST_AUTO_TEST_CASE(ismine_standard) +{ + CKey keys[2]; + CPubKey pubkeys[2]; + for (int i = 0; i < 2; i++) { + keys[i].MakeNewKey(true); + pubkeys[i] = keys[i].GetPubKey(); + } + + CKey uncompressedKey; + uncompressedKey.MakeNewKey(false); + CPubKey uncompressedPubkey = uncompressedKey.GetPubKey(); + std::unique_ptr<interfaces::Chain> chain = interfaces::MakeChain(); + + CScript scriptPubKey; + isminetype result; + + // P2PK compressed + { + CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); + LOCK(keystore.cs_wallet); + scriptPubKey = GetScriptForRawPubKey(pubkeys[0]); + + // Keystore does not have key + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_NO); + + // Keystore has key + BOOST_CHECK(keystore.AddKey(keys[0])); + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + } + + // P2PK uncompressed + { + CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); + LOCK(keystore.cs_wallet); + scriptPubKey = GetScriptForRawPubKey(uncompressedPubkey); + + // Keystore does not have key + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_NO); + + // Keystore has key + BOOST_CHECK(keystore.AddKey(uncompressedKey)); + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + } + + // P2PKH compressed + { + CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); + LOCK(keystore.cs_wallet); + scriptPubKey = GetScriptForDestination(PKHash(pubkeys[0])); + + // Keystore does not have key + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_NO); + + // Keystore has key + BOOST_CHECK(keystore.AddKey(keys[0])); + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + } + + // P2PKH uncompressed + { + CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); + LOCK(keystore.cs_wallet); + scriptPubKey = GetScriptForDestination(PKHash(uncompressedPubkey)); + + // Keystore does not have key + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_NO); + + // Keystore has key + BOOST_CHECK(keystore.AddKey(uncompressedKey)); + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + } + + // P2SH + { + CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); + LOCK(keystore.cs_wallet); + + CScript redeemScript = GetScriptForDestination(PKHash(pubkeys[0])); + scriptPubKey = GetScriptForDestination(ScriptHash(redeemScript)); + + // Keystore does not have redeemScript or key + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_NO); + + // Keystore has redeemScript but no key + BOOST_CHECK(keystore.AddCScript(redeemScript)); + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_NO); + + // Keystore has redeemScript and key + BOOST_CHECK(keystore.AddKey(keys[0])); + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + } + + // (P2PKH inside) P2SH inside P2SH (invalid) + { + CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); + LOCK(keystore.cs_wallet); + + CScript redeemscript_inner = GetScriptForDestination(PKHash(pubkeys[0])); + CScript redeemscript = GetScriptForDestination(ScriptHash(redeemscript_inner)); + scriptPubKey = GetScriptForDestination(ScriptHash(redeemscript)); + + BOOST_CHECK(keystore.AddCScript(redeemscript)); + BOOST_CHECK(keystore.AddCScript(redeemscript_inner)); + BOOST_CHECK(keystore.AddCScript(scriptPubKey)); + BOOST_CHECK(keystore.AddKey(keys[0])); + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_NO); + } + + // (P2PKH inside) P2SH inside P2WSH (invalid) + { + CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); + LOCK(keystore.cs_wallet); + + CScript redeemscript = GetScriptForDestination(PKHash(pubkeys[0])); + CScript witnessscript = GetScriptForDestination(ScriptHash(redeemscript)); + scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash(witnessscript)); + + BOOST_CHECK(keystore.AddCScript(witnessscript)); + BOOST_CHECK(keystore.AddCScript(redeemscript)); + BOOST_CHECK(keystore.AddCScript(scriptPubKey)); + BOOST_CHECK(keystore.AddKey(keys[0])); + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_NO); + } + + // P2WPKH inside P2WSH (invalid) + { + CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); + LOCK(keystore.cs_wallet); + + CScript witnessscript = GetScriptForDestination(WitnessV0KeyHash(PKHash(pubkeys[0]))); + scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash(witnessscript)); + + BOOST_CHECK(keystore.AddCScript(witnessscript)); + BOOST_CHECK(keystore.AddCScript(scriptPubKey)); + BOOST_CHECK(keystore.AddKey(keys[0])); + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_NO); + } + + // (P2PKH inside) P2WSH inside P2WSH (invalid) + { + CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); + LOCK(keystore.cs_wallet); + + CScript witnessscript_inner = GetScriptForDestination(PKHash(pubkeys[0])); + CScript witnessscript = GetScriptForDestination(WitnessV0ScriptHash(witnessscript_inner)); + scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash(witnessscript)); + + BOOST_CHECK(keystore.AddCScript(witnessscript_inner)); + BOOST_CHECK(keystore.AddCScript(witnessscript)); + BOOST_CHECK(keystore.AddCScript(scriptPubKey)); + BOOST_CHECK(keystore.AddKey(keys[0])); + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_NO); + } + + // P2WPKH compressed + { + CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); + LOCK(keystore.cs_wallet); + BOOST_CHECK(keystore.AddKey(keys[0])); + + scriptPubKey = GetScriptForDestination(WitnessV0KeyHash(PKHash(pubkeys[0]))); + + // Keystore implicitly has key and P2SH redeemScript + BOOST_CHECK(keystore.AddCScript(scriptPubKey)); + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + } + + // P2WPKH uncompressed + { + CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); + LOCK(keystore.cs_wallet); + BOOST_CHECK(keystore.AddKey(uncompressedKey)); + + scriptPubKey = GetScriptForDestination(WitnessV0KeyHash(PKHash(uncompressedPubkey))); + + // Keystore has key, but no P2SH redeemScript + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_NO); + + // Keystore has key and P2SH redeemScript + BOOST_CHECK(keystore.AddCScript(scriptPubKey)); + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_NO); + } + + // scriptPubKey multisig + { + CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); + LOCK(keystore.cs_wallet); + + scriptPubKey = GetScriptForMultisig(2, {uncompressedPubkey, pubkeys[1]}); + + // Keystore does not have any keys + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_NO); + + // Keystore has 1/2 keys + BOOST_CHECK(keystore.AddKey(uncompressedKey)); + + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_NO); + + // Keystore has 2/2 keys + BOOST_CHECK(keystore.AddKey(keys[1])); + + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_NO); + + // Keystore has 2/2 keys and the script + BOOST_CHECK(keystore.AddCScript(scriptPubKey)); + + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_NO); + } + + // P2SH multisig + { + CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); + LOCK(keystore.cs_wallet); + BOOST_CHECK(keystore.AddKey(uncompressedKey)); + BOOST_CHECK(keystore.AddKey(keys[1])); + + CScript redeemScript = GetScriptForMultisig(2, {uncompressedPubkey, pubkeys[1]}); + scriptPubKey = GetScriptForDestination(ScriptHash(redeemScript)); + + // Keystore has no redeemScript + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_NO); + + // Keystore has redeemScript + BOOST_CHECK(keystore.AddCScript(redeemScript)); + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + } + + // P2WSH multisig with compressed keys + { + CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); + LOCK(keystore.cs_wallet); + BOOST_CHECK(keystore.AddKey(keys[0])); + BOOST_CHECK(keystore.AddKey(keys[1])); + + CScript witnessScript = GetScriptForMultisig(2, {pubkeys[0], pubkeys[1]}); + scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash(witnessScript)); + + // Keystore has keys, but no witnessScript or P2SH redeemScript + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_NO); + + // Keystore has keys and witnessScript, but no P2SH redeemScript + BOOST_CHECK(keystore.AddCScript(witnessScript)); + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_NO); + + // Keystore has keys, witnessScript, P2SH redeemScript + BOOST_CHECK(keystore.AddCScript(scriptPubKey)); + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + } + + // P2WSH multisig with uncompressed key + { + CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); + LOCK(keystore.cs_wallet); + BOOST_CHECK(keystore.AddKey(uncompressedKey)); + BOOST_CHECK(keystore.AddKey(keys[1])); + + CScript witnessScript = GetScriptForMultisig(2, {uncompressedPubkey, pubkeys[1]}); + scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash(witnessScript)); + + // Keystore has keys, but no witnessScript or P2SH redeemScript + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_NO); + + // Keystore has keys and witnessScript, but no P2SH redeemScript + BOOST_CHECK(keystore.AddCScript(witnessScript)); + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_NO); + + // Keystore has keys, witnessScript, P2SH redeemScript + BOOST_CHECK(keystore.AddCScript(scriptPubKey)); + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_NO); + } + + // P2WSH multisig wrapped in P2SH + { + CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); + LOCK(keystore.cs_wallet); + + CScript witnessScript = GetScriptForMultisig(2, {pubkeys[0], pubkeys[1]}); + CScript redeemScript = GetScriptForDestination(WitnessV0ScriptHash(witnessScript)); + scriptPubKey = GetScriptForDestination(ScriptHash(redeemScript)); + + // Keystore has no witnessScript, P2SH redeemScript, or keys + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_NO); + + // Keystore has witnessScript and P2SH redeemScript, but no keys + BOOST_CHECK(keystore.AddCScript(redeemScript)); + BOOST_CHECK(keystore.AddCScript(witnessScript)); + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_NO); + + // Keystore has keys, witnessScript, P2SH redeemScript + BOOST_CHECK(keystore.AddKey(keys[0])); + BOOST_CHECK(keystore.AddKey(keys[1])); + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + } + + // OP_RETURN + { + CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); + LOCK(keystore.cs_wallet); + BOOST_CHECK(keystore.AddKey(keys[0])); + + scriptPubKey.clear(); + scriptPubKey << OP_RETURN << ToByteVector(pubkeys[0]); + + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_NO); + } + + // witness unspendable + { + CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); + LOCK(keystore.cs_wallet); + BOOST_CHECK(keystore.AddKey(keys[0])); + + scriptPubKey.clear(); + scriptPubKey << OP_0 << ToByteVector(ParseHex("aabb")); + + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_NO); + } + + // witness unknown + { + CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); + LOCK(keystore.cs_wallet); + BOOST_CHECK(keystore.AddKey(keys[0])); + + scriptPubKey.clear(); + scriptPubKey << OP_16 << ToByteVector(ParseHex("aabb")); + + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_NO); + } + + // Nonstandard + { + CWallet keystore(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); + LOCK(keystore.cs_wallet); + BOOST_CHECK(keystore.AddKey(keys[0])); + + scriptPubKey.clear(); + scriptPubKey << OP_9 << OP_ADD << OP_11 << OP_EQUAL; + + result = IsMine(keystore, scriptPubKey); + BOOST_CHECK_EQUAL(result, ISMINE_NO); + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/wallet/test/psbt_wallet_tests.cpp b/src/wallet/test/psbt_wallet_tests.cpp index 4753c7f313..0400f1207c 100644 --- a/src/wallet/test/psbt_wallet_tests.cpp +++ b/src/wallet/test/psbt_wallet_tests.cpp @@ -3,13 +3,10 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <key_io.h> -#include <script/sign.h> #include <util/bip32.h> #include <util/strencodings.h> #include <wallet/psbtwallet.h> -#include <wallet/rpcwallet.h> #include <wallet/wallet.h> -#include <univalue.h> #include <boost/test/unit_test.hpp> #include <test/setup_common.h> diff --git a/src/wallet/test/wallet_test_fixture.cpp b/src/wallet/test/wallet_test_fixture.cpp index e352c81519..ba0843f352 100644 --- a/src/wallet/test/wallet_test_fixture.cpp +++ b/src/wallet/test/wallet_test_fixture.cpp @@ -4,10 +4,6 @@ #include <wallet/test/wallet_test_fixture.h> -#include <rpc/server.h> -#include <wallet/db.h> -#include <wallet/rpcwallet.h> - WalletTestingSetup::WalletTestingSetup(const std::string& chainName) : TestingSetup(chainName), m_wallet(m_chain.get(), WalletLocation(), WalletDatabase::CreateMock()) diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index 922bb0fe65..ef95d0544f 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -5,9 +5,7 @@ #include <wallet/wallet.h> #include <memory> -#include <set> #include <stdint.h> -#include <utility> #include <vector> #include <consensus/validation.h> @@ -192,7 +190,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup) auto locked_chain = chain->lock(); LockAssertion lock(::cs_main); - std::string backup_file = (SetDataDir("importwallet_rescan") / "wallet.backup").string(); + std::string backup_file = (GetDataDir() / "wallet.backup").string(); // Import key into wallet and call dumpwallet to create backup file. { diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index e86147b5d0..8807acb6b7 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -14,17 +14,12 @@ #include <key.h> #include <key_io.h> #include <keystore.h> -#include <net.h> #include <policy/fees.h> #include <policy/policy.h> -#include <policy/rbf.h> #include <primitives/block.h> #include <primitives/transaction.h> #include <script/descriptor.h> #include <script/script.h> -#include <shutdown.h> -#include <timedata.h> -#include <txmempool.h> #include <util/bip32.h> #include <util/error.h> #include <util/fees.h> @@ -41,6 +36,14 @@ #include <boost/algorithm/string/replace.hpp> +const std::map<uint64_t,std::string> WALLET_FLAG_CAVEATS{ + {WALLET_FLAG_AVOID_REUSE, + "You need to rescan the blockchain in order to correctly mark used " + "destinations in the past. Until this is done, some destinations may " + "be considered unused, even if the opposite is the case." + }, +}; + static const size_t OUTPUT_GROUP_MAX_ENTRIES = 10; static CCriticalSection cs_wallets; @@ -937,6 +940,37 @@ bool CWallet::MarkReplaced(const uint256& originalHash, const uint256& newHash) return success; } +void CWallet::SetUsedDestinationState(const uint256& hash, unsigned int n, bool used) +{ + const CWalletTx* srctx = GetWalletTx(hash); + if (!srctx) return; + + CTxDestination dst; + if (ExtractDestination(srctx->tx->vout[n].scriptPubKey, dst)) { + if (::IsMine(*this, dst)) { + LOCK(cs_wallet); + if (used && !GetDestData(dst, "used", nullptr)) { + AddDestData(dst, "used", "p"); // p for "present", opposite of absent (null) + } else if (!used && GetDestData(dst, "used", nullptr)) { + EraseDestData(dst, "used"); + } + } + } +} + +bool CWallet::IsUsedDestination(const CTxDestination& dst) const +{ + LOCK(cs_wallet); + return ::IsMine(*this, dst) && GetDestData(dst, "used", nullptr); +} + +bool CWallet::IsUsedDestination(const uint256& hash, unsigned int n) const +{ + CTxDestination dst; + const CWalletTx* srctx = GetWalletTx(hash); + return srctx && ExtractDestination(srctx->tx->vout[n].scriptPubKey, dst) && IsUsedDestination(dst); +} + bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose) { LOCK(cs_wallet); @@ -945,6 +979,14 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose) uint256 hash = wtxIn.GetHash(); + if (IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE)) { + // Mark used destinations + for (const CTxIn& txin : wtxIn.tx->vin) { + const COutPoint& op = txin.prevout; + SetUsedDestinationState(op.hash, op.n, true); + } + } + // Inserts only if not already there, returns tx inserted or tx found std::pair<std::map<uint256, CWalletTx>::iterator, bool> ret = mapWallet.insert(std::make_pair(hash, wtxIn)); CWalletTx& wtx = (*ret.first).second; @@ -1562,7 +1604,7 @@ void CWallet::UnsetWalletFlagWithDB(WalletBatch& batch, uint64_t flag) throw std::runtime_error(std::string(__func__) + ": writing wallet flags failed"); } -bool CWallet::IsWalletFlagSet(uint64_t flag) +bool CWallet::IsWalletFlagSet(uint64_t flag) const { return (m_wallet_flags & flag); } @@ -1571,7 +1613,7 @@ bool CWallet::SetWalletFlags(uint64_t overwriteFlags, bool memonly) { LOCK(cs_wallet); m_wallet_flags = overwriteFlags; - if (((overwriteFlags & g_known_wallet_flags) >> 32) ^ (overwriteFlags >> 32)) { + if (((overwriteFlags & KNOWN_WALLET_FLAGS) >> 32) ^ (overwriteFlags >> 32)) { // contains unknown non-tolerable wallet flags return false; } @@ -2064,7 +2106,7 @@ CAmount CWalletTx::GetAvailableCredit(interfaces::Chain::Lock& locked_chain, boo return 0; // Avoid caching ismine for NO or ALL cases (could remove this check and simplify in the future). - bool allow_cache = filter == ISMINE_SPENDABLE || filter == ISMINE_WATCH_ONLY; + bool allow_cache = (filter & ISMINE_ALL) && (filter & ISMINE_ALL) != ISMINE_ALL; // Must wait until coinbase is safely deep enough in the chain before valuing it if (IsImmatureCoinBase(locked_chain)) @@ -2074,12 +2116,12 @@ CAmount CWalletTx::GetAvailableCredit(interfaces::Chain::Lock& locked_chain, boo return m_amounts[AVAILABLE_CREDIT].m_value[filter]; } + bool allow_used_addresses = (filter & ISMINE_USED) || !pwallet->IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE); CAmount nCredit = 0; uint256 hashTx = GetHash(); for (unsigned int i = 0; i < tx->vout.size(); i++) { - if (!pwallet->IsSpent(locked_chain, hashTx, i)) - { + if (!pwallet->IsSpent(locked_chain, hashTx, i) && (allow_used_addresses || !pwallet->IsUsedDestination(hashTx, i))) { const CTxOut &txout = tx->vout[i]; nCredit += pwallet->GetCredit(txout, filter); if (!MoneyRange(nCredit)) @@ -2221,9 +2263,10 @@ void MaybeResendWalletTxs() */ -CWallet::Balance CWallet::GetBalance(const int min_depth) const +CWallet::Balance CWallet::GetBalance(const int min_depth, bool avoid_reuse) const { Balance ret; + isminefilter reuse_filter = avoid_reuse ? ISMINE_NO : ISMINE_USED; { auto locked_chain = chain().lock(); LOCK(cs_wallet); @@ -2232,8 +2275,8 @@ CWallet::Balance CWallet::GetBalance(const int min_depth) const const CWalletTx& wtx = entry.second; const bool is_trusted{wtx.IsTrusted(*locked_chain)}; const int tx_depth{wtx.GetDepthInMainChain(*locked_chain)}; - const CAmount tx_credit_mine{wtx.GetAvailableCredit(*locked_chain, /* fUseCache */ true, ISMINE_SPENDABLE)}; - const CAmount tx_credit_watchonly{wtx.GetAvailableCredit(*locked_chain, /* fUseCache */ true, ISMINE_WATCH_ONLY)}; + const CAmount tx_credit_mine{wtx.GetAvailableCredit(*locked_chain, /* fUseCache */ true, ISMINE_SPENDABLE | reuse_filter)}; + const CAmount tx_credit_watchonly{wtx.GetAvailableCredit(*locked_chain, /* fUseCache */ true, ISMINE_WATCH_ONLY | reuse_filter)}; if (is_trusted && tx_depth >= min_depth) { ret.m_mine_trusted += tx_credit_mine; ret.m_watchonly_trusted += tx_credit_watchonly; @@ -2271,6 +2314,9 @@ void CWallet::AvailableCoins(interfaces::Chain::Lock& locked_chain, std::vector< vCoins.clear(); CAmount nTotal = 0; + // Either the WALLET_FLAG_AVOID_REUSE flag is not set (in which case we always allow), or we default to avoiding, and only in the case where + // a coin control object is provided, and has the avoid address reuse flag set to false, do we allow already used addresses + bool allow_used_addresses = !IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE) || (coinControl && !coinControl->m_avoid_address_reuse); for (const auto& entry : mapWallet) { @@ -2352,6 +2398,10 @@ void CWallet::AvailableCoins(interfaces::Chain::Lock& locked_chain, std::vector< continue; } + if (!allow_used_addresses && IsUsedDestination(wtxid, i)) { + continue; + } + bool solvable = IsSolvable(*this, wtx.tx->vout[i].scriptPubKey); bool spendable = ((mine & ISMINE_SPENDABLE) != ISMINE_NO) || (((mine & ISMINE_WATCH_ONLY) != ISMINE_NO) && (coinControl && coinControl->fAllowWatchOnly && solvable)); @@ -2644,6 +2694,11 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nC } } + if (nFeeRet > this->m_default_max_tx_fee) { + strFailReason = TransactionErrorString(TransactionError::MAX_FEE_EXCEEDED); + return false; + } + return true; } @@ -4142,16 +4197,12 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain, // ensure this wallet.dat can only be opened by clients supporting HD with chain split and expects no default key walletInstance->SetMinVersion(FEATURE_LATEST); - if ((wallet_creation_flags & WALLET_FLAG_DISABLE_PRIVATE_KEYS)) { - //selective allow to set flags - walletInstance->SetWalletFlag(WALLET_FLAG_DISABLE_PRIVATE_KEYS); - } else if (wallet_creation_flags & WALLET_FLAG_BLANK_WALLET) { - walletInstance->SetWalletFlag(WALLET_FLAG_BLANK_WALLET); - } else { + walletInstance->SetWalletFlags(wallet_creation_flags, false); + if (!(wallet_creation_flags & (WALLET_FLAG_DISABLE_PRIVATE_KEYS | WALLET_FLAG_BLANK_WALLET))) { // generate a new seed CPubKey seed = walletInstance->GenerateNewSeed(); walletInstance->SetHDSeed(seed); - } // Otherwise, do not generate a new seed + } // Top up the keypool if (walletInstance->CanGenerateKeys() && !walletInstance->TopUpKeyPool()) { diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 87aff09039..7b5465c219 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -11,7 +11,6 @@ #include <interfaces/handler.h> #include <outputtype.h> #include <policy/feerate.h> -#include <script/ismine.h> #include <script/sign.h> #include <streams.h> #include <tinyformat.h> @@ -21,6 +20,7 @@ #include <validationinterface.h> #include <wallet/coinselection.h> #include <wallet/crypter.h> +#include <wallet/ismine.h> #include <wallet/walletdb.h> #include <wallet/walletutil.h> @@ -120,6 +120,10 @@ enum WalletFlags : uint64_t { // wallet flags in the upper section (> 1 << 31) will lead to not opening the wallet if flag is unknown // unknown wallet flags in the lower section <= (1 << 31) will be tolerated + // will categorize coins as clean (not reused) and dirty (reused), and handle + // them with privacy considerations in mind + WALLET_FLAG_AVOID_REUSE = (1ULL << 0), + // Indicates that the metadata has already been upgraded to contain key origins WALLET_FLAG_KEY_ORIGIN_METADATA = (1ULL << 1), @@ -139,7 +143,23 @@ enum WalletFlags : uint64_t { WALLET_FLAG_BLANK_WALLET = (1ULL << 33), }; -static constexpr uint64_t g_known_wallet_flags = WALLET_FLAG_DISABLE_PRIVATE_KEYS | WALLET_FLAG_BLANK_WALLET | WALLET_FLAG_KEY_ORIGIN_METADATA; +static constexpr uint64_t KNOWN_WALLET_FLAGS = + WALLET_FLAG_AVOID_REUSE + | WALLET_FLAG_BLANK_WALLET + | WALLET_FLAG_KEY_ORIGIN_METADATA + | WALLET_FLAG_DISABLE_PRIVATE_KEYS; + +static constexpr uint64_t MUTABLE_WALLET_FLAGS = + WALLET_FLAG_AVOID_REUSE; + +static const std::map<std::string,WalletFlags> WALLET_FLAG_MAP{ + {"avoid_reuse", WALLET_FLAG_AVOID_REUSE}, + {"blank", WALLET_FLAG_BLANK_WALLET}, + {"key_origin_metadata", WALLET_FLAG_KEY_ORIGIN_METADATA}, + {"disable_private_keys", WALLET_FLAG_DISABLE_PRIVATE_KEYS}, +}; + +extern const std::map<uint64_t,std::string> WALLET_FLAG_CAVEATS; /** A key from a CWallet's keypool * @@ -924,6 +944,12 @@ public: std::set<CInputCoin>& setCoinsRet, CAmount& nValueRet, const CoinSelectionParams& coin_selection_params, bool& bnb_used) const; bool IsSpent(interfaces::Chain::Lock& locked_chain, const uint256& hash, unsigned int n) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); + + // Whether this or any UTXO with the same CTxDestination has been spent. + bool IsUsedDestination(const CTxDestination& dst) const; + bool IsUsedDestination(const uint256& hash, unsigned int n) const; + void SetUsedDestinationState(const uint256& hash, unsigned int n, bool used); + std::vector<OutputGroup> GroupOutputs(const std::vector<COutput>& outputs, bool single_coin) const; bool IsLockedCoin(uint256 hash, unsigned int n) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); @@ -1036,7 +1062,7 @@ public: CAmount m_watchonly_untrusted_pending{0}; CAmount m_watchonly_immature{0}; }; - Balance GetBalance(int min_depth = 0) const; + Balance GetBalance(int min_depth = 0, bool avoid_reuse = true) const; CAmount GetAvailableBalance(const CCoinControl* coinControl = nullptr) const; OutputType TransactionChangeType(OutputType change_type, const std::vector<CRecipient>& vecSend); @@ -1288,7 +1314,7 @@ public: void UnsetWalletFlag(uint64_t flag); /** check if a certain wallet flag is set */ - bool IsWalletFlagSet(uint64_t flag); + bool IsWalletFlagSet(uint64_t flag) const; /** overwrite all flags by the given uint64_t returns false if unknown, non-tolerable flags are present */ diff --git a/src/wallet/wallettool.cpp b/src/wallet/wallettool.cpp index c6132a2686..0843194511 100644 --- a/src/wallet/wallettool.cpp +++ b/src/wallet/wallettool.cpp @@ -2,7 +2,6 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include <base58.h> #include <fs.h> #include <util/system.h> #include <wallet/wallet.h> @@ -23,7 +22,7 @@ static void WalletToolReleaseWallet(CWallet* wallet) static std::shared_ptr<CWallet> CreateWallet(const std::string& name, const fs::path& path) { if (fs::exists(path)) { - fprintf(stderr, "Error: File exists already\n"); + tfm::format(std::cerr, "Error: File exists already\n"); return nullptr; } // dummy chain interface @@ -31,7 +30,7 @@ static std::shared_ptr<CWallet> CreateWallet(const std::string& name, const fs:: bool first_run = true; DBErrors load_wallet_ret = wallet_instance->LoadWallet(first_run); if (load_wallet_ret != DBErrors::LOAD_OK) { - fprintf(stderr, "Error creating %s", name.c_str()); + tfm::format(std::cerr, "Error creating %s", name.c_str()); return nullptr; } @@ -41,7 +40,7 @@ static std::shared_ptr<CWallet> CreateWallet(const std::string& name, const fs:: CPubKey seed = wallet_instance->GenerateNewSeed(); wallet_instance->SetHDSeed(seed); - fprintf(stdout, "Topping up keypool...\n"); + tfm::format(std::cout, "Topping up keypool...\n"); wallet_instance->TopUpKeyPool(); return wallet_instance; } @@ -49,7 +48,7 @@ static std::shared_ptr<CWallet> CreateWallet(const std::string& name, const fs:: static std::shared_ptr<CWallet> LoadWallet(const std::string& name, const fs::path& path) { if (!fs::exists(path)) { - fprintf(stderr, "Error: Wallet files does not exist\n"); + tfm::format(std::cerr, "Error: Wallet files does not exist\n"); return nullptr; } @@ -60,28 +59,28 @@ static std::shared_ptr<CWallet> LoadWallet(const std::string& name, const fs::pa bool first_run; load_wallet_ret = wallet_instance->LoadWallet(first_run); } catch (const std::runtime_error&) { - fprintf(stderr, "Error loading %s. Is wallet being used by another process?\n", name.c_str()); + tfm::format(std::cerr, "Error loading %s. Is wallet being used by another process?\n", name.c_str()); return nullptr; } if (load_wallet_ret != DBErrors::LOAD_OK) { wallet_instance = nullptr; if (load_wallet_ret == DBErrors::CORRUPT) { - fprintf(stderr, "Error loading %s: Wallet corrupted", name.c_str()); + tfm::format(std::cerr, "Error loading %s: Wallet corrupted", name.c_str()); return nullptr; } else if (load_wallet_ret == DBErrors::NONCRITICAL_ERROR) { - fprintf(stderr, "Error reading %s! All keys read correctly, but transaction data" + tfm::format(std::cerr, "Error reading %s! All keys read correctly, but transaction data" " or address book entries might be missing or incorrect.", name.c_str()); } else if (load_wallet_ret == DBErrors::TOO_NEW) { - fprintf(stderr, "Error loading %s: Wallet requires newer version of %s", + tfm::format(std::cerr, "Error loading %s: Wallet requires newer version of %s", name.c_str(), PACKAGE_NAME); return nullptr; } else if (load_wallet_ret == DBErrors::NEED_REWRITE) { - fprintf(stderr, "Wallet needed to be rewritten: restart %s to complete", PACKAGE_NAME); + tfm::format(std::cerr, "Wallet needed to be rewritten: restart %s to complete", PACKAGE_NAME); return nullptr; } else { - fprintf(stderr, "Error loading %s", name.c_str()); + tfm::format(std::cerr, "Error loading %s", name.c_str()); return nullptr; } } @@ -93,12 +92,12 @@ static void WalletShowInfo(CWallet* wallet_instance) { LOCK(wallet_instance->cs_wallet); - fprintf(stdout, "Wallet info\n===========\n"); - fprintf(stdout, "Encrypted: %s\n", wallet_instance->IsCrypted() ? "yes" : "no"); - fprintf(stdout, "HD (hd seed available): %s\n", wallet_instance->GetHDChain().seed_id.IsNull() ? "no" : "yes"); - fprintf(stdout, "Keypool Size: %u\n", wallet_instance->GetKeyPoolSize()); - fprintf(stdout, "Transactions: %zu\n", wallet_instance->mapWallet.size()); - fprintf(stdout, "Address Book: %zu\n", wallet_instance->mapAddressBook.size()); + tfm::format(std::cout, "Wallet info\n===========\n"); + tfm::format(std::cout, "Encrypted: %s\n", wallet_instance->IsCrypted() ? "yes" : "no"); + tfm::format(std::cout, "HD (hd seed available): %s\n", wallet_instance->GetHDChain().seed_id.IsNull() ? "no" : "yes"); + tfm::format(std::cout, "Keypool Size: %u\n", wallet_instance->GetKeyPoolSize()); + tfm::format(std::cout, "Transactions: %zu\n", wallet_instance->mapWallet.size()); + tfm::format(std::cout, "Address Book: %zu\n", wallet_instance->mapAddressBook.size()); } bool ExecuteWalletToolFunc(const std::string& command, const std::string& name) @@ -113,12 +112,12 @@ bool ExecuteWalletToolFunc(const std::string& command, const std::string& name) } } else if (command == "info") { if (!fs::exists(path)) { - fprintf(stderr, "Error: no wallet file at %s\n", name.c_str()); + tfm::format(std::cerr, "Error: no wallet file at %s\n", name.c_str()); return false; } std::string error; if (!WalletBatch::VerifyEnvironment(path, error)) { - fprintf(stderr, "Error loading %s. Is wallet being used by other process?\n", name.c_str()); + tfm::format(std::cerr, "Error loading %s. Is wallet being used by other process?\n", name.c_str()); return false; } std::shared_ptr<CWallet> wallet_instance = LoadWallet(name, path); @@ -126,7 +125,7 @@ bool ExecuteWalletToolFunc(const std::string& command, const std::string& name) WalletShowInfo(wallet_instance.get()); wallet_instance->Flush(true); } else { - fprintf(stderr, "Invalid command: %s\n", command.c_str()); + tfm::format(std::cerr, "Invalid command: %s\n", command.c_str()); return false; } diff --git a/src/wallet/wallettool.h b/src/wallet/wallettool.h index da848a747b..7ee2505631 100644 --- a/src/wallet/wallettool.h +++ b/src/wallet/wallettool.h @@ -5,7 +5,7 @@ #ifndef BITCOIN_WALLET_WALLETTOOL_H #define BITCOIN_WALLET_WALLETTOOL_H -#include <script/ismine.h> +#include <wallet/ismine.h> #include <wallet/wallet.h> namespace WalletTool { diff --git a/src/warnings.cpp b/src/warnings.cpp index 8ac9ee09db..5542412a7f 100644 --- a/src/warnings.cpp +++ b/src/warnings.cpp @@ -4,7 +4,6 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <sync.h> -#include <clientversion.h> #include <util/system.h> #include <warnings.h> diff --git a/src/zmq/zmqabstractnotifier.cpp b/src/zmq/zmqabstractnotifier.cpp index 6a9661e3e8..a5f3be8f5b 100644 --- a/src/zmq/zmqabstractnotifier.cpp +++ b/src/zmq/zmqabstractnotifier.cpp @@ -3,7 +3,6 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <zmq/zmqabstractnotifier.h> -#include <util/system.h> const int CZMQAbstractNotifier::DEFAULT_ZMQ_SNDHWM; diff --git a/src/zmq/zmqnotificationinterface.cpp b/src/zmq/zmqnotificationinterface.cpp index 6826cf62d6..de59b71b8f 100644 --- a/src/zmq/zmqnotificationinterface.cpp +++ b/src/zmq/zmqnotificationinterface.cpp @@ -7,7 +7,6 @@ #include <version.h> #include <validation.h> -#include <streams.h> #include <util/system.h> void zmqError(const char *str) diff --git a/test/README.md b/test/README.md index 9d4351b1de..ecea3213ab 100644 --- a/test/README.md +++ b/test/README.md @@ -13,8 +13,7 @@ bitcoin-tx. - [lint](/test/lint/) which perform various static analysis checks. The util tests are run as part of `make check` target. The functional -tests and lint scripts are run by the travis continuous build process whenever a pull -request is opened. All sets of tests can also be run locally. +tests and lint scripts can be run as explained in the sections below. # Running tests locally diff --git a/test/functional/feature_bip68_sequence.py b/test/functional/feature_bip68_sequence.py index fdb60fb0e8..d38eca6cbe 100755 --- a/test/functional/feature_bip68_sequence.py +++ b/test/functional/feature_bip68_sequence.py @@ -378,7 +378,7 @@ class BIP68Test(BitcoinTestFramework): add_witness_commitment(block) block.solve() - self.nodes[0].submitblock(block.serialize(True).hex()) + self.nodes[0].submitblock(block.serialize().hex()) assert_equal(self.nodes[0].getbestblockhash(), block.hash) def activateCSV(self): diff --git a/test/functional/feature_config_args.py b/test/functional/feature_config_args.py index 2b93e3c24d..f0d6bc21e6 100755 --- a/test/functional/feature_config_args.py +++ b/test/functional/feature_config_args.py @@ -21,6 +21,16 @@ class ConfArgsTest(BitcoinTestFramework): with open(os.path.join(self.nodes[0].datadir, 'bitcoin.conf'), 'a', encoding='utf-8') as conf: conf.write('includeconf={}\n'.format(inc_conf_file_path)) + self.nodes[0].assert_start_raises_init_error( + expected_msg='Error parsing command line arguments: Invalid parameter -dash_cli', + extra_args=['-dash_cli=1'], + ) + with open(inc_conf_file_path, 'w', encoding='utf-8') as conf: + conf.write('dash_conf=1\n') + with self.nodes[0].assert_debug_log(expected_msgs=['Ignoring unknown configuration value dash_conf']): + self.start_node(0) + self.stop_node(0) + with open(inc_conf_file_path, 'w', encoding='utf-8') as conf: conf.write('-dash=1\n') self.nodes[0].assert_start_raises_init_error(expected_msg='Error reading configuration file: parse error on line 1: -dash=1, options in configuration file must be specified without leading -') @@ -61,9 +71,16 @@ class ConfArgsTest(BitcoinTestFramework): with open(inc_conf_file2_path, 'w', encoding='utf-8') as conf: conf.write('') # clear + def test_log_buffer(self): + with self.nodes[0].assert_debug_log(expected_msgs=['Warning: parsed potentially confusing double-negative -connect=0']): + self.start_node(0, extra_args=['-noconnect=0']) + self.stop_node(0) + def run_test(self): self.stop_node(0) + self.test_log_buffer() + self.test_config_file_parser() # Remove the -datadir argument so it doesn't override the config file diff --git a/test/functional/feature_nulldummy.py b/test/functional/feature_nulldummy.py index a56c983ccc..60a703c48f 100755 --- a/test/functional/feature_nulldummy.py +++ b/test/functional/feature_nulldummy.py @@ -108,7 +108,7 @@ class NULLDUMMYTest(BitcoinTestFramework): witness and add_witness_commitment(block) block.rehash() block.solve() - node.submitblock(block.serialize(True).hex()) + node.submitblock(block.serialize().hex()) if (accept): assert_equal(node.getbestblockhash(), block.hash) self.tip = block.sha256 diff --git a/test/functional/feature_pruning.py b/test/functional/feature_pruning.py index e2b3b2d544..66c395d7a2 100755 --- a/test/functional/feature_pruning.py +++ b/test/functional/feature_pruning.py @@ -23,8 +23,6 @@ from test_framework.util import ( wait_until, ) -MIN_BLOCKS_TO_KEEP = 288 - # Rescans start at the earliest block up to 2 hours before a key timestamp, so # the manual prune RPC avoids pruning blocks in the same window to be # compatible with pruning based on key creation time. @@ -273,20 +271,9 @@ class PruneTest(BitcoinTestFramework): else: return index - def prune(index, expected_ret=None): + def prune(index): ret = node.pruneblockchain(height=height(index)) - # Check the return value. When use_timestamp is True, just check - # that the return value is less than or equal to the expected - # value, because when more than one block is generated per second, - # a timestamp will not be granular enough to uniquely identify an - # individual block. - if expected_ret is None: - expected_ret = index - if use_timestamp: - assert_greater_than(ret, 0) - assert_greater_than(expected_ret + 1, ret) - else: - assert_equal(ret, expected_ret) + assert_equal(ret, node.getblockchaininfo()['pruneheight']) def has_block(index): return os.path.isfile(os.path.join(self.nodes[node_number].datadir, "regtest", "blocks", "blk{:05}.dat".format(index))) @@ -326,7 +313,7 @@ class PruneTest(BitcoinTestFramework): assert not has_block(1), "blk00001.dat is still there, should be pruned by now" # height=1000 should not prune anything more, because tip-288 is in blk00002.dat. - prune(1000, 1001 - MIN_BLOCKS_TO_KEEP) + prune(1000) assert has_block(2), "blk00002.dat is still there, should be pruned by now" # advance the tip so blk00002.dat and blk00003.dat can be pruned (the last 288 blocks should now be in blk00004.dat) diff --git a/test/functional/feature_rbf.py b/test/functional/feature_rbf.py index ccba547a1c..1496c5d958 100755 --- a/test/functional/feature_rbf.py +++ b/test/functional/feature_rbf.py @@ -64,7 +64,7 @@ def make_utxo(node, amount, confirmed=True, scriptPubKey=CScript([1])): class ReplaceByFeeTest(BitcoinTestFramework): def set_test_params(self): - self.num_nodes = 2 + self.num_nodes = 1 self.extra_args = [ [ "-maxorphantx=1000", @@ -74,9 +74,6 @@ class ReplaceByFeeTest(BitcoinTestFramework): "-limitdescendantcount=200", "-limitdescendantsize=101", ], - [ - "-mempoolreplacement=0", - ], ] def skip_test_if_missing_module(self): @@ -148,16 +145,12 @@ class ReplaceByFeeTest(BitcoinTestFramework): # This will raise an exception due to insufficient fee assert_raises_rpc_error(-26, "insufficient fee", self.nodes[0].sendrawtransaction, tx1b_hex, 0) - # This will raise an exception due to transaction replacement being disabled - assert_raises_rpc_error(-26, "txn-mempool-conflict", self.nodes[1].sendrawtransaction, tx1b_hex, 0) # Extra 0.1 BTC fee tx1b = CTransaction() tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)] tx1b.vout = [CTxOut(int(0.9 * COIN), CScript([b'b' * 35]))] tx1b_hex = txToHex(tx1b) - # Replacement still disabled even with "enough fee" - assert_raises_rpc_error(-26, "txn-mempool-conflict", self.nodes[1].sendrawtransaction, tx1b_hex, 0) # Works when enabled tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, 0) @@ -168,11 +161,6 @@ class ReplaceByFeeTest(BitcoinTestFramework): assert_equal(tx1b_hex, self.nodes[0].getrawtransaction(tx1b_txid)) - # Second node is running mempoolreplacement=0, will not replace originally-seen txn - mempool = self.nodes[1].getrawmempool() - assert tx1a_txid in mempool - assert tx1b_txid not in mempool - def test_doublespend_chain(self): """Doublespend of a long chain""" diff --git a/test/functional/p2p_compactblocks.py b/test/functional/p2p_compactblocks.py index 3ca6bec254..0994857912 100755 --- a/test/functional/p2p_compactblocks.py +++ b/test/functional/p2p_compactblocks.py @@ -10,7 +10,7 @@ Version 2 compact blocks are post-segwit (wtxids) import random from test_framework.blocktools import create_block, create_coinbase, add_witness_commitment -from test_framework.messages import BlockTransactions, BlockTransactionsRequest, calculate_shortid, CBlock, CBlockHeader, CInv, COutPoint, CTransaction, CTxIn, CTxInWitness, CTxOut, FromHex, HeaderAndShortIDs, msg_block, msg_blocktxn, msg_cmpctblock, msg_getblocktxn, msg_getdata, msg_getheaders, msg_headers, msg_inv, msg_sendcmpct, msg_sendheaders, msg_tx, msg_witness_block, msg_witness_blocktxn, MSG_WITNESS_FLAG, NODE_NETWORK, P2PHeaderAndShortIDs, PrefilledTransaction, ser_uint256, ToHex +from test_framework.messages import BlockTransactions, BlockTransactionsRequest, calculate_shortid, CBlock, CBlockHeader, CInv, COutPoint, CTransaction, CTxIn, CTxInWitness, CTxOut, FromHex, HeaderAndShortIDs, msg_no_witness_block, msg_no_witness_blocktxn, msg_cmpctblock, msg_getblocktxn, msg_getdata, msg_getheaders, msg_headers, msg_inv, msg_sendcmpct, msg_sendheaders, msg_tx, msg_block, msg_blocktxn, MSG_WITNESS_FLAG, NODE_NETWORK, P2PHeaderAndShortIDs, PrefilledTransaction, ser_uint256, ToHex from test_framework.mininode import mininode_lock, P2PInterface from test_framework.script import CScript, OP_TRUE, OP_DROP from test_framework.test_framework import BitcoinTestFramework @@ -114,7 +114,7 @@ class CompactBlocksTest(BitcoinTestFramework): # Create 10 more anyone-can-spend utxo's for testing. def make_utxos(self): block = self.build_block_on_tip(self.nodes[0]) - self.segwit_node.send_and_ping(msg_block(block)) + self.segwit_node.send_and_ping(msg_no_witness_block(block)) assert int(self.nodes[0].getbestblockhash(), 16) == block.sha256 self.nodes[0].generatetoaddress(100, self.nodes[0].getnewaddress(address_type="bech32")) @@ -130,7 +130,7 @@ class CompactBlocksTest(BitcoinTestFramework): block2.vtx.append(tx) block2.hashMerkleRoot = block2.calc_merkle_root() block2.solve() - self.segwit_node.send_and_ping(msg_block(block2)) + self.segwit_node.send_and_ping(msg_no_witness_block(block2)) assert_equal(int(self.nodes[0].getbestblockhash(), 16), block2.sha256) self.utxos.extend([[tx.sha256, i, out_value] for i in range(10)]) @@ -408,9 +408,9 @@ class CompactBlocksTest(BitcoinTestFramework): # Send the coinbase, and verify that the tip advances. if version == 2: - msg = msg_witness_blocktxn() - else: msg = msg_blocktxn() + else: + msg = msg_no_witness_blocktxn() msg.block_transactions.blockhash = block.sha256 msg.block_transactions.transactions = [block.vtx[0]] test_node.send_and_ping(msg) @@ -463,9 +463,9 @@ class CompactBlocksTest(BitcoinTestFramework): test_getblocktxn_response(comp_block, test_node, [1, 2, 3, 4, 5]) - msg_bt = msg_blocktxn() + msg_bt = msg_no_witness_blocktxn() if with_witness: - msg_bt = msg_witness_blocktxn() # serialize with witnesses + msg_bt = msg_blocktxn() # serialize with witnesses msg_bt.block_transactions = BlockTransactions(block.sha256, block.vtx[1:]) test_tip_after_message(node, test_node, msg_bt, block.sha256) @@ -554,9 +554,9 @@ class CompactBlocksTest(BitcoinTestFramework): # different peer provide the block further down, so that we're still # verifying that the block isn't marked bad permanently. This is good # enough for now. - msg = msg_blocktxn() + msg = msg_no_witness_blocktxn() if version == 2: - msg = msg_witness_blocktxn() + msg = msg_blocktxn() msg.block_transactions = BlockTransactions(block.sha256, [block.vtx[5]] + block.vtx[7:]) test_node.send_and_ping(msg) @@ -571,9 +571,9 @@ class CompactBlocksTest(BitcoinTestFramework): # Deliver the block if version == 2: - test_node.send_and_ping(msg_witness_block(block)) - else: test_node.send_and_ping(msg_block(block)) + else: + test_node.send_and_ping(msg_no_witness_block(block)) assert_equal(int(node.getbestblockhash(), 16), block.sha256) def test_getblocktxn_handler(self, test_node): @@ -785,7 +785,7 @@ class CompactBlocksTest(BitcoinTestFramework): delivery_peer.send_and_ping(msg_cmpctblock(cmpct_block.to_p2p())) assert int(node.getbestblockhash(), 16) != block.sha256 - msg = msg_blocktxn() + msg = msg_no_witness_blocktxn() msg.block_transactions.blockhash = block.sha256 msg.block_transactions.transactions = block.vtx[1:] stalling_peer.send_and_ping(msg) diff --git a/test/functional/p2p_segwit.py b/test/functional/p2p_segwit.py index df0f9fa365..b7fa42f593 100755 --- a/test/functional/p2p_segwit.py +++ b/test/functional/p2p_segwit.py @@ -25,12 +25,12 @@ from test_framework.messages import ( MSG_WITNESS_FLAG, NODE_NETWORK, NODE_WITNESS, - msg_block, + msg_no_witness_block, msg_getdata, msg_headers, msg_inv, msg_tx, - msg_witness_block, + msg_block, msg_witness_tx, ser_uint256, ser_vector, @@ -111,7 +111,7 @@ def get_virtual_size(witness_block): Virtual size is base + witness/4.""" base_size = len(witness_block.serialize(with_witness=False)) - total_size = len(witness_block.serialize(with_witness=True)) + total_size = len(witness_block.serialize()) # the "+3" is so we round up vsize = int((3 * base_size + total_size + 3) / 4) return vsize @@ -134,7 +134,7 @@ def test_witness_block(node, p2p, block, accepted, with_witness=True, reason=Non - use the getbestblockhash rpc to check for acceptance.""" reason = [reason] if reason else [] with node.assert_debug_log(expected_msgs=reason): - p2p.send_message(msg_witness_block(block) if with_witness else msg_block(block)) + p2p.send_message(msg_block(block) if with_witness else msg_no_witness_block(block)) p2p.sync_with_ping() assert_equal(node.getbestblockhash() == block.hash, accepted) @@ -298,7 +298,7 @@ class SegWitTest(BitcoinTestFramework): block = self.build_next_block(version=1) block.solve() - self.test_node.send_message(msg_block(block)) + self.test_node.send_message(msg_no_witness_block(block)) self.test_node.sync_with_ping() # make sure the block was processed txid = block.vtx[0].sha256 @@ -345,7 +345,7 @@ class SegWitTest(BitcoinTestFramework): # But it should not be permanently marked bad... # Resend without witness information. - self.test_node.send_message(msg_block(block)) + self.test_node.send_message(msg_no_witness_block(block)) self.test_node.sync_with_ping() assert_equal(self.nodes[0].getbestblockhash(), block.hash) @@ -403,7 +403,7 @@ class SegWitTest(BitcoinTestFramework): block_hash = int(block_hash, 16) block = self.test_node.request_block(block_hash, 2) wit_block = self.test_node.request_block(block_hash, 2 | MSG_WITNESS_FLAG) - assert_equal(block.serialize(True), wit_block.serialize(True)) + assert_equal(block.serialize(), wit_block.serialize()) assert_equal(block.serialize(), hex_str_to_bytes(rpc_block)) else: # After activation, witness blocks and non-witness blocks should @@ -419,15 +419,15 @@ class SegWitTest(BitcoinTestFramework): rpc_block = self.nodes[0].getblock(block.hash, False) non_wit_block = self.test_node.request_block(block.sha256, 2) wit_block = self.test_node.request_block(block.sha256, 2 | MSG_WITNESS_FLAG) - assert_equal(wit_block.serialize(True), hex_str_to_bytes(rpc_block)) + assert_equal(wit_block.serialize(), hex_str_to_bytes(rpc_block)) assert_equal(wit_block.serialize(False), non_wit_block.serialize()) - assert_equal(wit_block.serialize(True), block.serialize(True)) + assert_equal(wit_block.serialize(), block.serialize()) # Test size, vsize, weight rpc_details = self.nodes[0].getblock(block.hash, True) - assert_equal(rpc_details["size"], len(block.serialize(True))) + assert_equal(rpc_details["size"], len(block.serialize())) assert_equal(rpc_details["strippedsize"], len(block.serialize(False))) - weight = 3 * len(block.serialize(False)) + len(block.serialize(True)) + weight = 3 * len(block.serialize(False)) + len(block.serialize()) assert_equal(rpc_details["weight"], weight) # Upgraded node should not ask for blocks from unupgraded @@ -791,7 +791,7 @@ class SegWitTest(BitcoinTestFramework): block.solve() # Test the test -- witness serialization should be different - assert msg_witness_block(block).serialize() != msg_block(block).serialize() + assert msg_block(block).serialize() != msg_no_witness_block(block).serialize() # This empty block should be valid. test_witness_block(self.nodes[0], self.test_node, block, accepted=True) @@ -884,13 +884,13 @@ class SegWitTest(BitcoinTestFramework): # We can't send over the p2p network, because this is too big to relay # TODO: repeat this test with a block that can be relayed - self.nodes[0].submitblock(block.serialize(True).hex()) + self.nodes[0].submitblock(block.serialize().hex()) assert self.nodes[0].getbestblockhash() != block.hash block.vtx[0].wit.vtxinwit[0].scriptWitness.stack.pop() assert get_virtual_size(block) < MAX_BLOCK_BASE_SIZE - self.nodes[0].submitblock(block.serialize(True).hex()) + self.nodes[0].submitblock(block.serialize().hex()) assert self.nodes[0].getbestblockhash() == block.hash @@ -969,7 +969,7 @@ class SegWitTest(BitcoinTestFramework): assert_equal(vsize, MAX_BLOCK_BASE_SIZE + 1) # Make sure that our test case would exceed the old max-network-message # limit - assert len(block.serialize(True)) > 2 * 1024 * 1024 + assert len(block.serialize()) > 2 * 1024 * 1024 test_witness_block(self.nodes[0], self.test_node, block, accepted=False) @@ -997,14 +997,14 @@ class SegWitTest(BitcoinTestFramework): add_witness_commitment(block, nonce=1) block.vtx[0].wit = CTxWitness() # drop the nonce block.solve() - self.nodes[0].submitblock(block.serialize(True).hex()) + self.nodes[0].submitblock(block.serialize().hex()) assert self.nodes[0].getbestblockhash() != block.hash # Now redo commitment with the standard nonce, but let bitcoind fill it in. add_witness_commitment(block, nonce=0) block.vtx[0].wit = CTxWitness() block.solve() - self.nodes[0].submitblock(block.serialize(True).hex()) + self.nodes[0].submitblock(block.serialize().hex()) assert_equal(self.nodes[0].getbestblockhash(), block.hash) # This time, add a tx with non-empty witness, but don't supply @@ -1019,7 +1019,7 @@ class SegWitTest(BitcoinTestFramework): block_2.vtx[0].vout.pop() block_2.vtx[0].wit = CTxWitness() - self.nodes[0].submitblock(block_2.serialize(True).hex()) + self.nodes[0].submitblock(block_2.serialize().hex()) # Tip should not advance! assert self.nodes[0].getbestblockhash() != block_2.hash diff --git a/test/functional/rpc_createmultisig.py b/test/functional/rpc_createmultisig.py index 7abcd71bb8..62f3843756 100755 --- a/test/functional/rpc_createmultisig.py +++ b/test/functional/rpc_createmultisig.py @@ -7,9 +7,13 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_raises_rpc_error, + assert_equal, ) -import decimal +from test_framework.key import ECPubKey +import binascii +import decimal +import itertools class RpcCreateMultiSigTest(BitcoinTestFramework): def set_test_params(self): @@ -44,6 +48,30 @@ class RpcCreateMultiSigTest(BitcoinTestFramework): self.checkbalances() + # Test mixed compressed and uncompressed pubkeys + self.log.info('Mixed compressed and uncompressed multisigs are not allowed') + pk0 = node0.getaddressinfo(node0.getnewaddress())['pubkey'] + pk1 = node1.getaddressinfo(node1.getnewaddress())['pubkey'] + pk2 = node2.getaddressinfo(node2.getnewaddress())['pubkey'] + + # decompress pk2 + pk_obj = ECPubKey() + pk_obj.set(binascii.unhexlify(pk2)) + pk_obj.compressed = False + pk2 = binascii.hexlify(pk_obj.get_bytes()).decode() + + # Check all permutations of keys because order matters apparently + for keys in itertools.permutations([pk0, pk1, pk2]): + # Results should be the same as this legacy one + legacy_addr = node0.createmultisig(2, keys, 'legacy')['address'] + assert_equal(legacy_addr, node0.addmultisigaddress(2, keys, '', 'legacy')['address']) + + # Generate addresses with the segwit types. These should all make legacy addresses + assert_equal(legacy_addr, node0.createmultisig(2, keys, 'bech32')['address']) + assert_equal(legacy_addr, node0.createmultisig(2, keys, 'p2sh-segwit')['address']) + assert_equal(legacy_addr, node0.addmultisigaddress(2, keys, '', 'bech32')['address']) + assert_equal(legacy_addr, node0.addmultisigaddress(2, keys, '', 'p2sh-segwit')['address']) + def check_addmultisigaddress_errors(self): self.log.info('Check that addmultisigaddress fails when the private keys are missing') addresses = [self.nodes[1].getnewaddress(address_type='legacy') for _ in range(2)] @@ -101,6 +129,11 @@ class RpcCreateMultiSigTest(BitcoinTestFramework): outval = value - decimal.Decimal("0.00001000") rawtx = node2.createrawtransaction([{"txid": txid, "vout": vout}], [{self.final: outval}]) + prevtx_err = dict(prevtxs[0]) + del prevtx_err["redeemScript"] + + assert_raises_rpc_error(-8, "Missing redeemScript/witnessScript", node2.signrawtransactionwithkey, rawtx, self.priv[0:self.nsigs-1], [prevtx_err]) + rawtx2 = node2.signrawtransactionwithkey(rawtx, self.priv[0:self.nsigs - 1], prevtxs) rawtx3 = node2.signrawtransactionwithkey(rawtx2["hex"], [self.priv[-1]], prevtxs) diff --git a/test/functional/rpc_fundrawtransaction.py b/test/functional/rpc_fundrawtransaction.py index d89fd6461f..cdf636e200 100755 --- a/test/functional/rpc_fundrawtransaction.py +++ b/test/functional/rpc_fundrawtransaction.py @@ -662,6 +662,7 @@ class RawTransactionsTest(BitcoinTestFramework): result = self.nodes[3].fundrawtransaction(rawtx) # uses min_relay_tx_fee (set by settxfee) result2 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 2*min_relay_tx_fee}) result3 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 10*min_relay_tx_fee}) + assert_raises_rpc_error(-4, "Fee exceeds maximum configured by -maxtxfee", self.nodes[3].fundrawtransaction, rawtx, {"feeRate": 1}) result_fee_rate = result['fee'] * 1000 / count_bytes(result['hex']) assert_fee_amount(result2['fee'], count_bytes(result2['hex']), 2 * result_fee_rate) assert_fee_amount(result3['fee'], count_bytes(result3['hex']), 10 * result_fee_rate) diff --git a/test/functional/rpc_psbt.py b/test/functional/rpc_psbt.py index 8a7ea7aa58..2fffe96ebe 100755 --- a/test/functional/rpc_psbt.py +++ b/test/functional/rpc_psbt.py @@ -9,6 +9,7 @@ from decimal import Decimal from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, + assert_greater_than, assert_raises_rpc_error, connect_nodes_bi, disconnect_nodes, @@ -129,6 +130,15 @@ class PSBTTest(BitcoinTestFramework): assert_equal(walletprocesspsbt_out['complete'], True) self.nodes[1].sendrawtransaction(self.nodes[1].finalizepsbt(walletprocesspsbt_out['psbt'])['hex']) + # feeRate of 0.1 BTC / KB produces a total fee slightly below -maxtxfee (~0.05280000): + res = self.nodes[1].walletcreatefundedpsbt([{"txid":txid,"vout":p2wpkh_pos},{"txid":txid,"vout":p2sh_p2wpkh_pos},{"txid":txid,"vout":p2pkh_pos}], {self.nodes[1].getnewaddress():29.99}, 0, {"feeRate": 0.1}) + assert_greater_than(res["fee"], 0.05) + assert_greater_than(0.06, res["fee"]) + + # feeRate of 10 BTC / KB produces a total fee well above -maxtxfee + # previously this was silenty capped at -maxtxfee + assert_raises_rpc_error(-4, "Fee exceeds maximum configured by -maxtxfee", self.nodes[1].walletcreatefundedpsbt, [{"txid":txid,"vout":p2wpkh_pos},{"txid":txid,"vout":p2sh_p2wpkh_pos},{"txid":txid,"vout":p2pkh_pos}], {self.nodes[1].getnewaddress():29.99}, 0, {"feeRate": 10}) + # partially sign multisig things with node 1 psbtx = self.nodes[1].walletcreatefundedpsbt([{"txid":txid,"vout":p2wsh_pos},{"txid":txid,"vout":p2sh_pos},{"txid":txid,"vout":p2sh_p2wsh_pos}], {self.nodes[1].getnewaddress():29.99})['psbt'] walletprocesspsbt_out = self.nodes[1].walletprocesspsbt(psbtx) @@ -152,9 +162,10 @@ class PSBTTest(BitcoinTestFramework): # Make sure that a non-psbt with signatures cannot be converted # Error could be either "TX decode failed" (segwit inputs causes parsing to fail) or "Inputs must not have scriptSigs and scriptWitnesses" + # We must set iswitness=True because the serialized transaction has inputs and is therefore a witness transaction signedtx = self.nodes[0].signrawtransactionwithwallet(rawtx['hex']) - assert_raises_rpc_error(-22, "", self.nodes[0].converttopsbt, signedtx['hex']) - assert_raises_rpc_error(-22, "", self.nodes[0].converttopsbt, signedtx['hex'], False) + assert_raises_rpc_error(-22, "", self.nodes[0].converttopsbt, hexstring=signedtx['hex'], iswitness=True) + assert_raises_rpc_error(-22, "", self.nodes[0].converttopsbt, hexstring=signedtx['hex'], permitsigdata=False, iswitness=True) # Unless we allow it to convert and strip signatures self.nodes[0].converttopsbt(signedtx['hex'], True) @@ -314,18 +325,32 @@ class PSBTTest(BitcoinTestFramework): vout3 = find_output(self.nodes[0], txid3, 11) self.sync_all() - # Update a PSBT with UTXOs from the node - # Bech32 inputs should be filled with witness UTXO. Other inputs should not be filled because they are non-witness + def test_psbt_input_keys(psbt_input, keys): + """Check that the psbt input has only the expected keys.""" + assert_equal(set(keys), set(psbt_input.keys())) + + # Create a PSBT. None of the inputs are filled initially psbt = self.nodes[1].createpsbt([{"txid":txid1, "vout":vout1},{"txid":txid2, "vout":vout2},{"txid":txid3, "vout":vout3}], {self.nodes[0].getnewaddress():32.999}) decoded = self.nodes[1].decodepsbt(psbt) - assert "witness_utxo" not in decoded['inputs'][0] and "non_witness_utxo" not in decoded['inputs'][0] - assert "witness_utxo" not in decoded['inputs'][1] and "non_witness_utxo" not in decoded['inputs'][1] - assert "witness_utxo" not in decoded['inputs'][2] and "non_witness_utxo" not in decoded['inputs'][2] + test_psbt_input_keys(decoded['inputs'][0], []) + test_psbt_input_keys(decoded['inputs'][1], []) + test_psbt_input_keys(decoded['inputs'][2], []) + + # Update a PSBT with UTXOs from the node + # Bech32 inputs should be filled with witness UTXO. Other inputs should not be filled because they are non-witness updated = self.nodes[1].utxoupdatepsbt(psbt) decoded = self.nodes[1].decodepsbt(updated) - assert "witness_utxo" in decoded['inputs'][0] and "non_witness_utxo" not in decoded['inputs'][0] - assert "witness_utxo" not in decoded['inputs'][1] and "non_witness_utxo" not in decoded['inputs'][1] - assert "witness_utxo" not in decoded['inputs'][2] and "non_witness_utxo" not in decoded['inputs'][2] + test_psbt_input_keys(decoded['inputs'][0], ['witness_utxo']) + test_psbt_input_keys(decoded['inputs'][1], []) + test_psbt_input_keys(decoded['inputs'][2], []) + + # Try again, now while providing descriptors, making P2SH-segwit work, and causing bip32_derivs and redeem_script to be filled in + descs = [self.nodes[1].getaddressinfo(addr)['desc'] for addr in [addr1,addr2,addr3]] + updated = self.nodes[1].utxoupdatepsbt(psbt, descs) + decoded = self.nodes[1].decodepsbt(updated) + test_psbt_input_keys(decoded['inputs'][0], ['witness_utxo', 'bip32_derivs']) + test_psbt_input_keys(decoded['inputs'][1], []) + test_psbt_input_keys(decoded['inputs'][2], ['witness_utxo', 'bip32_derivs', 'redeem_script']) # Two PSBTs with a common input should not be joinable psbt1 = self.nodes[1].createpsbt([{"txid":txid1, "vout":vout1}], {self.nodes[0].getnewaddress():Decimal('10.999')}) diff --git a/test/functional/test_framework/messages.py b/test/functional/test_framework/messages.py index 954ae3c4df..e454ed5987 100755 --- a/test/functional/test_framework/messages.py +++ b/test/functional/test_framework/messages.py @@ -1130,7 +1130,7 @@ class msg_block: self.block.deserialize(f) def serialize(self): - return self.block.serialize(with_witness=False) + return self.block.serialize() def __repr__(self): return "msg_block(block=%s)" % (repr(self.block)) @@ -1152,11 +1152,10 @@ class msg_generic: return "msg_generic()" -class msg_witness_block(msg_block): +class msg_no_witness_block(msg_block): __slots__ = () def serialize(self): - r = self.block.serialize(with_witness=True) - return r + return self.block.serialize(with_witness=False) class msg_getaddr: @@ -1442,17 +1441,15 @@ class msg_blocktxn: def serialize(self): r = b"" - r += self.block_transactions.serialize(with_witness=False) + r += self.block_transactions.serialize() return r def __repr__(self): return "msg_blocktxn(block_transactions=%s)" % (repr(self.block_transactions)) -class msg_witness_blocktxn(msg_blocktxn): +class msg_no_witness_blocktxn(msg_blocktxn): __slots__ = () def serialize(self): - r = b"" - r += self.block_transactions.serialize(with_witness=True) - return r + return self.block_transactions.serialize(with_witness=False) diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index 80dced733e..462547f44f 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -67,14 +67,14 @@ TEST_EXIT_PASSED = 0 TEST_EXIT_SKIPPED = 77 EXTENDED_SCRIPTS = [ - # These tests are not run by the travis build process. + # These tests are not run by default. # Longest test should go first, to favor running tests in parallel 'feature_pruning.py', 'feature_dbcrash.py', ] BASE_SCRIPTS = [ - # Scripts that are run by the travis build process. + # Scripts that are run by default. # Longest test should go first, to favor running tests in parallel 'feature_fee_estimation.py', 'wallet_hd.py', @@ -120,6 +120,7 @@ BASE_SCRIPTS = [ 'rpc_misc.py', 'interface_rest.py', 'mempool_spend_coinbase.py', + 'wallet_avoidreuse.py', 'mempool_reorg.py', 'mempool_persist.py', 'wallet_multiwallet.py', @@ -494,7 +495,8 @@ class TestHandler: for job in self.jobs: (name, start_time, proc, testdir, log_out, log_err) = job if int(time.time() - start_time) > self.timeout_duration: - # In travis, timeout individual tests (to stop tests hanging and not providing useful output). + # Timeout individual tests if timeout is specified (to stop + # tests hanging and not providing useful output). proc.send_signal(signal.SIGINT) if proc.poll() is not None: log_out.seek(0), log_err.seek(0) @@ -582,7 +584,7 @@ def check_script_list(*, src_dir, fail_on_warn): if len(missed_tests) != 0: print("%sWARNING!%s The following scripts are not being run: %s. Check the test lists in test_runner.py." % (BOLD[1], BOLD[0], str(missed_tests))) if fail_on_warn: - # On travis this warning is an error to prevent merging incomplete commits into master + # On CI this warning is an error to prevent merging incomplete commits into master sys.exit(1) diff --git a/test/functional/wallet_avoidreuse.py b/test/functional/wallet_avoidreuse.py new file mode 100755 index 0000000000..58ad835d39 --- /dev/null +++ b/test/functional/wallet_avoidreuse.py @@ -0,0 +1,241 @@ +#!/usr/bin/env python3 +# 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. +"""Test the avoid_reuse and setwalletflag features.""" + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + assert_equal, + assert_raises_rpc_error, + connect_nodes_bi, +) + +# TODO: Copied from wallet_groups.py -- should perhaps move into util.py +def assert_approx(v, vexp, vspan=0.00001): + if v < vexp - vspan: + raise AssertionError("%s < [%s..%s]" % (str(v), str(vexp - vspan), str(vexp + vspan))) + if v > vexp + vspan: + raise AssertionError("%s > [%s..%s]" % (str(v), str(vexp - vspan), str(vexp + vspan))) + +def reset_balance(node, discardaddr): + '''Throw away all owned coins by the node so it gets a balance of 0.''' + balance = node.getbalance(avoid_reuse=False) + if balance > 0.5: + node.sendtoaddress(address=discardaddr, amount=balance, subtractfeefromamount=True, avoid_reuse=False) + +def count_unspent(node): + '''Count the unspent outputs for the given node and return various statistics''' + r = { + "total": { + "count": 0, + "sum": 0, + }, + "reused": { + "count": 0, + "sum": 0, + }, + } + supports_reused = True + for utxo in node.listunspent(minconf=0): + r["total"]["count"] += 1 + r["total"]["sum"] += utxo["amount"] + if supports_reused and "reused" in utxo: + if utxo["reused"]: + r["reused"]["count"] += 1 + r["reused"]["sum"] += utxo["amount"] + else: + supports_reused = False + r["reused"]["supported"] = supports_reused + return r + +def assert_unspent(node, total_count=None, total_sum=None, reused_supported=None, reused_count=None, reused_sum=None): + '''Make assertions about a node's unspent output statistics''' + stats = count_unspent(node) + if total_count is not None: + assert_equal(stats["total"]["count"], total_count) + if total_sum is not None: + assert_approx(stats["total"]["sum"], total_sum, 0.001) + if reused_supported is not None: + assert_equal(stats["reused"]["supported"], reused_supported) + if reused_count is not None: + assert_equal(stats["reused"]["count"], reused_count) + if reused_sum is not None: + assert_approx(stats["reused"]["sum"], reused_sum, 0.001) + +def assert_balances(node, mine): + '''Make assertions about a node's getbalances output''' + got = node.getbalances()["mine"] + for k,v in mine.items(): + assert_approx(got[k], v, 0.001) + +class AvoidReuseTest(BitcoinTestFramework): + + def set_test_params(self): + self.setup_clean_chain = False + self.num_nodes = 2 + + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + + def run_test(self): + '''Set up initial chain and run tests defined below''' + + self.test_persistence() + self.test_immutable() + + self.nodes[0].generate(110) + self.sync_all() + reset_balance(self.nodes[1], self.nodes[0].getnewaddress()) + self.test_fund_send_fund_senddirty() + reset_balance(self.nodes[1], self.nodes[0].getnewaddress()) + self.test_fund_send_fund_send() + + def test_persistence(self): + '''Test that wallet files persist the avoid_reuse flag.''' + # Configure node 1 to use avoid_reuse + self.nodes[1].setwalletflag('avoid_reuse') + + # Flags should be node1.avoid_reuse=false, node2.avoid_reuse=true + assert_equal(self.nodes[0].getwalletinfo()["avoid_reuse"], False) + assert_equal(self.nodes[1].getwalletinfo()["avoid_reuse"], True) + + # Stop and restart node 1 + self.stop_node(1) + self.start_node(1) + connect_nodes_bi(self.nodes, 0, 1) + + # Flags should still be node1.avoid_reuse=false, node2.avoid_reuse=true + assert_equal(self.nodes[0].getwalletinfo()["avoid_reuse"], False) + assert_equal(self.nodes[1].getwalletinfo()["avoid_reuse"], True) + + # Attempting to set flag to its current state should throw + assert_raises_rpc_error(-8, "Wallet flag is already set to false", self.nodes[0].setwalletflag, 'avoid_reuse', False) + assert_raises_rpc_error(-8, "Wallet flag is already set to true", self.nodes[1].setwalletflag, 'avoid_reuse', True) + + def test_immutable(self): + '''Test immutable wallet flags''' + # Attempt to set the disable_private_keys flag; this should not work + assert_raises_rpc_error(-8, "Wallet flag is immutable", self.nodes[1].setwalletflag, 'disable_private_keys') + + tempwallet = ".wallet_avoidreuse.py_test_immutable_wallet.dat" + + # Create a wallet with disable_private_keys set; this should work + self.nodes[1].createwallet(tempwallet, True) + w = self.nodes[1].get_wallet_rpc(tempwallet) + + # Attempt to unset the disable_private_keys flag; this should not work + assert_raises_rpc_error(-8, "Wallet flag is immutable", w.setwalletflag, 'disable_private_keys', False) + + # Unload temp wallet + self.nodes[1].unloadwallet(tempwallet) + + def test_fund_send_fund_senddirty(self): + ''' + Test the same as test_fund_send_fund_send, except send the 10 BTC with + the avoid_reuse flag set to false. This means the 10 BTC send should succeed, + where it fails in test_fund_send_fund_send. + ''' + + fundaddr = self.nodes[1].getnewaddress() + retaddr = self.nodes[0].getnewaddress() + + self.nodes[0].sendtoaddress(fundaddr, 10) + self.nodes[0].generate(1) + self.sync_all() + + # listunspent should show 1 single, unused 10 btc output + assert_unspent(self.nodes[1], total_count=1, total_sum=10, reused_supported=True, reused_count=0) + # getbalances should show no used, 10 btc trusted + assert_balances(self.nodes[1], mine={"used": 0, "trusted": 10}) + # node 0 should not show a used entry, as it does not enable avoid_reuse + assert("used" not in self.nodes[0].getbalances()["mine"]) + + self.nodes[1].sendtoaddress(retaddr, 5) + self.nodes[0].generate(1) + self.sync_all() + + # listunspent should show 1 single, unused 5 btc output + assert_unspent(self.nodes[1], total_count=1, total_sum=5, reused_supported=True, reused_count=0) + # getbalances should show no used, 5 btc trusted + assert_balances(self.nodes[1], mine={"used": 0, "trusted": 5}) + + self.nodes[0].sendtoaddress(fundaddr, 10) + self.nodes[0].generate(1) + self.sync_all() + + # listunspent should show 2 total outputs (5, 10 btc), one unused (5), one reused (10) + assert_unspent(self.nodes[1], total_count=2, total_sum=15, reused_count=1, reused_sum=10) + # getbalances should show 10 used, 5 btc trusted + assert_balances(self.nodes[1], mine={"used": 10, "trusted": 5}) + + self.nodes[1].sendtoaddress(address=retaddr, amount=10, avoid_reuse=False) + + # listunspent should show 1 total outputs (5 btc), unused + assert_unspent(self.nodes[1], total_count=1, total_sum=5, reused_count=0) + # getbalances should show no used, 5 btc trusted + assert_balances(self.nodes[1], mine={"used": 0, "trusted": 5}) + + # node 1 should now have about 5 btc left (for both cases) + assert_approx(self.nodes[1].getbalance(), 5, 0.001) + assert_approx(self.nodes[1].getbalance(avoid_reuse=False), 5, 0.001) + + def test_fund_send_fund_send(self): + ''' + Test the simple case where [1] generates a new address A, then + [0] sends 10 BTC to A. + [1] spends 5 BTC from A. (leaving roughly 5 BTC useable) + [0] sends 10 BTC to A again. + [1] tries to spend 10 BTC (fails; dirty). + [1] tries to spend 4 BTC (succeeds; change address sufficient) + ''' + + fundaddr = self.nodes[1].getnewaddress() + retaddr = self.nodes[0].getnewaddress() + + self.nodes[0].sendtoaddress(fundaddr, 10) + self.nodes[0].generate(1) + self.sync_all() + + # listunspent should show 1 single, unused 10 btc output + assert_unspent(self.nodes[1], total_count=1, total_sum=10, reused_supported=True, reused_count=0) + # getbalances should show no used, 10 btc trusted + assert_balances(self.nodes[1], mine={"used": 0, "trusted": 10}) + + self.nodes[1].sendtoaddress(retaddr, 5) + self.nodes[0].generate(1) + self.sync_all() + + # listunspent should show 1 single, unused 5 btc output + assert_unspent(self.nodes[1], total_count=1, total_sum=5, reused_supported=True, reused_count=0) + # getbalances should show no used, 5 btc trusted + assert_balances(self.nodes[1], mine={"used": 0, "trusted": 5}) + + self.nodes[0].sendtoaddress(fundaddr, 10) + self.nodes[0].generate(1) + self.sync_all() + + # listunspent should show 2 total outputs (5, 10 btc), one unused (5), one reused (10) + assert_unspent(self.nodes[1], total_count=2, total_sum=15, reused_count=1, reused_sum=10) + # getbalances should show 10 used, 5 btc trusted + assert_balances(self.nodes[1], mine={"used": 10, "trusted": 5}) + + # node 1 should now have a balance of 5 (no dirty) or 15 (including dirty) + assert_approx(self.nodes[1].getbalance(), 5, 0.001) + assert_approx(self.nodes[1].getbalance(avoid_reuse=False), 15, 0.001) + + assert_raises_rpc_error(-6, "Insufficient funds", self.nodes[1].sendtoaddress, retaddr, 10) + + self.nodes[1].sendtoaddress(retaddr, 4) + + # listunspent should show 2 total outputs (1, 10 btc), one unused (1), one reused (10) + assert_unspent(self.nodes[1], total_count=2, total_sum=11, reused_count=1, reused_sum=10) + # getbalances should show 10 used, 1 btc trusted + assert_balances(self.nodes[1], mine={"used": 10, "trusted": 1}) + + # node 1 should now have about 1 btc left (no dirty) and 11 (including dirty) + assert_approx(self.nodes[1].getbalance(), 1, 0.001) + assert_approx(self.nodes[1].getbalance(avoid_reuse=False), 11, 0.001) + +if __name__ == '__main__': + AvoidReuseTest().main() diff --git a/test/functional/wallet_balance.py b/test/functional/wallet_balance.py index 15f2195e21..137c77a51e 100755 --- a/test/functional/wallet_balance.py +++ b/test/functional/wallet_balance.py @@ -203,6 +203,8 @@ class WalletTest(BitcoinTestFramework): self.log.info('Put txs back into mempool of node 1 (not node 0)') self.nodes[0].invalidateblock(block_reorg) self.nodes[1].invalidateblock(block_reorg) + self.sync_blocks() + self.nodes[0].syncwithvalidationinterfacequeue() assert_equal(self.nodes[0].getbalance(minconf=0), 0) # wallet txs not in the mempool are untrusted self.nodes[0].generatetoaddress(1, ADDRESS_WATCHONLY) assert_equal(self.nodes[0].getbalance(minconf=0), 0) # wallet txs not in the mempool are untrusted diff --git a/test/functional/wallet_bumpfee.py b/test/functional/wallet_bumpfee.py index 568b1f28d8..1fe029a6fb 100755 --- a/test/functional/wallet_bumpfee.py +++ b/test/functional/wallet_bumpfee.py @@ -304,7 +304,9 @@ def test_unconfirmed_not_spendable(rbf_node, rbf_node_address): def test_bumpfee_metadata(rbf_node, dest_address): - rbfid = rbf_node.sendtoaddress(dest_address, Decimal("0.00100000"), "comment value", "to value") + assert(rbf_node.getbalance() < 49) + rbf_node.generatetoaddress(101, rbf_node.getnewaddress()) + rbfid = rbf_node.sendtoaddress(dest_address, 49, "comment value", "to value") bumped_tx = rbf_node.bumpfee(rbfid) bumped_wtx = rbf_node.gettransaction(bumped_tx["txid"]) assert_equal(bumped_wtx["comment"], "comment value") @@ -360,7 +362,7 @@ def submit_block_with_tx(node, tx): block.hashMerkleRoot = block.calc_merkle_root() add_witness_commitment(block) block.solve() - node.submitblock(block.serialize(True).hex()) + node.submitblock(block.serialize().hex()) return block def test_no_more_inputs_fails(rbf_node, dest_address): diff --git a/test/functional/wallet_importmulti.py b/test/functional/wallet_importmulti.py index 7d652a7825..e19c7919a9 100755 --- a/test/functional/wallet_importmulti.py +++ b/test/functional/wallet_importmulti.py @@ -571,6 +571,7 @@ class ImportMultiTest(BitcoinTestFramework): # Test ranged descriptor fails if range is not specified xpriv = "tprv8ZgxMBicQKsPeuVhWwi6wuMQGfPKi9Li5GtX35jVNknACgqe3CY4g5xgkfDDJcmtF7o1QnxWDRYw4H5P26PXq7sbcUkEqeR4fg3Kxp2tigg" addresses = ["2N7yv4p8G8yEaPddJxY41kPihnWvs39qCMf", "2MsHxyb2JS3pAySeNUsJ7mNnurtpeenDzLA"] # hdkeypath=m/0'/0'/0' and 1' + addresses += ["bcrt1qrd3n235cj2czsfmsuvqqpr3lu6lg0ju7scl8gn", "bcrt1qfqeppuvj0ww98r6qghmdkj70tv8qpchehegrg8"] # wpkh subscripts corresponding to the above addresses desc = "sh(wpkh(" + xpriv + "/0'/0'/*'" + "))" self.log.info("Ranged descriptor import should fail without a specified range") self.test_importmulti({"desc": descsum_create(desc), @@ -579,17 +580,17 @@ class ImportMultiTest(BitcoinTestFramework): error_code=-8, error_message='Descriptor is ranged, please specify the range') - # Test importing of a ranged descriptor without keys + # Test importing of a ranged descriptor with xpriv self.log.info("Should import the ranged descriptor with specified range as solvable") self.test_importmulti({"desc": descsum_create(desc), "timestamp": "now", "range": 1}, - success=True, - warnings=["Some private keys are missing, outputs will be considered watchonly. If this is intentional, specify the watchonly flag."]) + success=True) for address in addresses: test_address(self.nodes[1], - key.p2sh_p2wpkh_addr, - solvable=True) + address, + solvable=True, + ismine=True) self.test_importmulti({"desc": descsum_create(desc), "timestamp": "now", "range": -1}, success=False, error_code=-8, error_message='End of range is too high') @@ -606,6 +607,23 @@ class ImportMultiTest(BitcoinTestFramework): self.test_importmulti({"desc": descsum_create(desc), "timestamp": "now", "range": [0, 1000001]}, success=False, error_code=-8, error_message='Range is too large') + # Test importing a descriptor containing a WIF private key + wif_priv = "cTe1f5rdT8A8DFgVWTjyPwACsDPJM9ff4QngFxUixCSvvbg1x6sh" + address = "2MuhcG52uHPknxDgmGPsV18jSHFBnnRgjPg" + desc = "sh(wpkh(" + wif_priv + "))" + self.log.info("Should import a descriptor with a WIF private key as spendable") + self.test_importmulti({"desc": descsum_create(desc), + "timestamp": "now"}, + success=True) + test_address(self.nodes[1], + address, + solvable=True, + ismine=True) + + # dump the private key to ensure it matches what was imported + privkey = self.nodes[1].dumpprivkey(address) + assert_equal(privkey, wif_priv) + # Test importing of a P2PKH address via descriptor key = get_key(self.nodes[0]) self.log.info("Should import a p2pkh address from descriptor") diff --git a/test/fuzz/test_runner.py b/test/fuzz/test_runner.py index 1869f71753..f19cf924d2 100755 --- a/test/fuzz/test_runner.py +++ b/test/fuzz/test_runner.py @@ -106,8 +106,10 @@ def run_once(*, corpus, test_list, build_dir, export_coverage): os.path.join(corpus, t), ] logging.debug('Run {} with args {}'.format(t, args)) - output = subprocess.run(args, check=True, stderr=subprocess.PIPE, universal_newlines=True).stderr + result = subprocess.run(args, stderr=subprocess.PIPE, universal_newlines=True) + output = result.stderr logging.debug('Output: {}'.format(output)) + result.check_returncode() if not export_coverage: continue for l in output.splitlines(): diff --git a/test/lint/lint-circular-dependencies.sh b/test/lint/lint-circular-dependencies.sh index e1a99abc49..70cc16337e 100755 --- a/test/lint/lint-circular-dependencies.sh +++ b/test/lint/lint-circular-dependencies.sh @@ -12,7 +12,6 @@ EXPECTED_CIRCULAR_DEPENDENCIES=( "chainparamsbase -> util/system -> chainparamsbase" "index/txindex -> validation -> index/txindex" "policy/fees -> txmempool -> policy/fees" - "policy/policy -> policy/settings -> policy/policy" "qt/addresstablemodel -> qt/walletmodel -> qt/addresstablemodel" "qt/bantablemodel -> qt/clientmodel -> qt/bantablemodel" "qt/bitcoingui -> qt/utilitydialog -> qt/bitcoingui" @@ -25,18 +24,13 @@ EXPECTED_CIRCULAR_DEPENDENCIES=( "qt/transactiontablemodel -> qt/walletmodel -> qt/transactiontablemodel" "qt/walletmodel -> qt/walletmodeltransaction -> qt/walletmodel" "txmempool -> validation -> txmempool" - "validation -> validationinterface -> validation" "wallet/coincontrol -> wallet/wallet -> wallet/coincontrol" "wallet/fees -> wallet/wallet -> wallet/fees" "wallet/wallet -> wallet/walletdb -> wallet/wallet" "policy/fees -> txmempool -> validation -> policy/fees" - "policy/rbf -> txmempool -> validation -> policy/rbf" - "qt/addressbookpage -> qt/bitcoingui -> qt/walletview -> qt/addressbookpage" "qt/guiutil -> qt/walletmodel -> qt/optionsmodel -> qt/guiutil" "txmempool -> validation -> validationinterface -> txmempool" - "qt/addressbookpage -> qt/bitcoingui -> qt/walletview -> qt/receivecoinsdialog -> qt/addressbookpage" - "qt/addressbookpage -> qt/bitcoingui -> qt/walletview -> qt/signverifymessagedialog -> qt/addressbookpage" - "qt/addressbookpage -> qt/bitcoingui -> qt/walletview -> qt/sendcoinsdialog -> qt/sendcoinsentry -> qt/addressbookpage" + "wallet/ismine -> wallet/wallet -> wallet/ismine" ) EXIT_CODE=0 diff --git a/test/lint/lint-format-strings.sh b/test/lint/lint-format-strings.sh index c994ae3f4d..cb630c78ad 100755 --- a/test/lint/lint-format-strings.sh +++ b/test/lint/lint-format-strings.sh @@ -13,6 +13,7 @@ export LC_ALL=C FUNCTION_NAMES_AND_NUMBER_OF_LEADING_ARGUMENTS=( "FatalError,0" "fprintf,1" + "tfm::format,1" # Assuming tfm::::format(std::ostream&, ... "LogConnectFailure,1" "LogPrint,1" "LogPrintf,0" diff --git a/test/lint/lint-locale-dependence.sh b/test/lint/lint-locale-dependence.sh index 2b6c78c2c8..9a1aa766f7 100755 --- a/test/lint/lint-locale-dependence.sh +++ b/test/lint/lint-locale-dependence.sh @@ -8,7 +8,6 @@ KNOWN_VIOLATIONS=( "src/dbwrapper.cpp:.*vsnprintf" "src/httprpc.cpp.*trim" "src/init.cpp:.*atoi" - "src/init.cpp:.*fprintf" "src/qt/rpcconsole.cpp:.*atoi" "src/rest.cpp:.*strtol" "src/test/dbwrapper_tests.cpp:.*snprintf" @@ -85,7 +84,7 @@ LOCALE_DEPENDENT_FUNCTIONS=( mbtowc # LC_CTYPE mktime normalize # boost::locale::normalize -# printf # LC_NUMERIC + printf # LC_NUMERIC putwc putwchar scanf # LC_NUMERIC @@ -189,8 +188,7 @@ GIT_GREP_OUTPUT=$(git grep -E "[^a-zA-Z0-9_\`'\"<>](${REGEXP_LOCALE_DEPENDENT_FU EXIT_CODE=0 for LOCALE_DEPENDENT_FUNCTION in "${LOCALE_DEPENDENT_FUNCTIONS[@]}"; do MATCHES=$(grep -E "[^a-zA-Z0-9_\`'\"<>]${LOCALE_DEPENDENT_FUNCTION}(_r|_s)?[^a-zA-Z0-9_\`'\"<>]" <<< "${GIT_GREP_OUTPUT}" | \ - grep -vE "\.(c|cpp|h):\s*(//|\*|/\*|\").*${LOCALE_DEPENDENT_FUNCTION}" | \ - grep -vE 'fprintf\(.*(stdout|stderr)') + grep -vE "\.(c|cpp|h):\s*(//|\*|/\*|\").*${LOCALE_DEPENDENT_FUNCTION}") if [[ ${REGEXP_IGNORE_EXTERNAL_DEPENDENCIES} != "" ]]; then MATCHES=$(grep -vE "${REGEXP_IGNORE_EXTERNAL_DEPENDENCIES}" <<< "${MATCHES}") fi diff --git a/test/lint/lint-spelling.ignore-words.txt b/test/lint/lint-spelling.ignore-words.txt index f0415443db..a25de2435b 100644 --- a/test/lint/lint-spelling.ignore-words.txt +++ b/test/lint/lint-spelling.ignore-words.txt @@ -5,3 +5,10 @@ mut objext unselect useable +wit +unparseable +copyable +cachable +errorstring +keyserver +homogenous diff --git a/test/sanitizer_suppressions/lsan b/test/sanitizer_suppressions/lsan index 6f15c0f1d4..90a92a5115 100644 --- a/test/sanitizer_suppressions/lsan +++ b/test/sanitizer_suppressions/lsan @@ -4,3 +4,6 @@ leak:libqminimal leak:libQt5Core leak:libQt5Gui leak:libQt5Widgets + +# false-positive due to use of secure_allocator<> +leak:GetRNGState |