aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml2
-rw-r--r--.github/PULL_REQUEST_TEMPLATE.md10
-rw-r--r--.travis.yml1
-rw-r--r--build-aux/m4/ax_boost_base.m43
-rw-r--r--build-aux/m4/ax_boost_chrono.m44
-rw-r--r--build-aux/m4/ax_boost_filesystem.m47
-rw-r--r--build-aux/m4/ax_boost_system.m44
-rw-r--r--build-aux/m4/ax_boost_thread.m4153
-rw-r--r--build-aux/m4/ax_boost_unit_test_framework.m44
-rwxr-xr-xci/lint/04_install.sh1
-rwxr-xr-xci/test/00_setup_env.sh23
-rw-r--r--depends/packages/qt.mk6
-rw-r--r--doc/Doxyfile.in4
-rw-r--r--doc/README_doxygen.md15
-rw-r--r--doc/translation_process.md8
-rw-r--r--src/Makefile.qt.include88
-rw-r--r--src/Makefile.qt_locale.include87
-rw-r--r--src/bitcoind.cpp18
-rw-r--r--src/chainparams.cpp3
-rw-r--r--src/coins.h10
-rw-r--r--src/consensus/params.h3
-rw-r--r--src/net.cpp61
-rw-r--r--src/qt/forms/receivecoinsdialog.ui8
-rw-r--r--src/qt/intro.cpp1
-rw-r--r--src/qt/locale/bitcoin_en.ts24
-rw-r--r--src/qt/receivecoinsdialog.cpp8
-rw-r--r--src/rpc/blockchain.cpp4
-rw-r--r--src/rpc/rawtransaction.cpp6
-rw-r--r--src/streams.h24
-rw-r--r--src/test/README.md42
-rw-r--r--src/test/streams_tests.cpp244
-rw-r--r--src/validation.cpp7
-rw-r--r--src/validation.h3
-rw-r--r--test/README.md26
-rw-r--r--test/functional/README.md2
-rwxr-xr-xtest/functional/feature_segwit.py6
-rwxr-xr-xtest/functional/rpc_blockchain.py2
-rwxr-xr-xtest/functional/rpc_rawtransaction.py18
-rw-r--r--test/functional/test_framework/util.py5
-rwxr-xr-xtest/functional/wallet_basic.py6
-rw-r--r--test/lint/lint-python-dead-code-whitelist46
-rwxr-xr-xtest/lint/lint-python-dead-code.sh23
42 files changed, 637 insertions, 383 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index 1e6e6937da..9464ec1685 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -9,6 +9,7 @@ task:
MAKEJOBS: "-j9"
CONFIGURE_OPTS: "--disable-dependency-tracking"
GOAL: "install"
+ TEST_RUNNER_PORT_MIN: "14000" # Must be larger than 12321, which is used for the http cache. See https://cirrus-ci.org/guide/writing-tasks/#http-cache
CCACHE_SIZE: "200M"
CCACHE_COMPRESS: 1
CCACHE_DIR: "/tmp/ccache_dir"
@@ -37,6 +38,7 @@ task:
env:
MAKEJOBS: "-j9"
RUN_CI_ON_HOST: "1"
+ TEST_RUNNER_PORT_MIN: "14000" # Must be larger than 12321, which is used for the http cache. See https://cirrus-ci.org/guide/writing-tasks/#http-cache
CCACHE_SIZE: "200M"
CCACHE_DIR: "/tmp/ccache_dir"
ccache_cache:
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 00d5478c4e..d2c3b23375 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,9 +1,14 @@
+<!--
+*** Please remove the following help text before submitting: ***
+
Pull requests without a rationale and clear improvement may be closed
immediately.
+-->
+<!--
Please provide clear motivation for your patch and explain how it improves
Bitcoin Core user experience or Bitcoin Core developer experience
-significantly.
+significantly:
* Any test improvements or new tests that improve coverage are always welcome.
* All other changes should have accompanying unit tests (see `src/test/`) or
@@ -24,8 +29,11 @@ significantly.
is often a subjective matter. Unless they are explicitly mentioned to be
preferred in the [developer notes](/doc/developer-notes.md), stylistic code
changes are usually rejected.
+-->
+<!--
Bitcoin Core has a thorough review process and even the most trivial change
needs to pass a lot of eyes and requires non-zero or even substantial time
effort to review. There is a huge lack of active reviewers on the project, so
patches often sit for a long time.
+-->
diff --git a/.travis.yml b/.travis.yml
index ec08ab2efb..e93f6ca0dc 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -117,6 +117,7 @@ jobs:
name: 'x86_64 Linux [GOAL: install] [xenial] [no depends, only system libs, sanitizers: thread (TSan), no wallet]'
env: >-
FILE_ENV="./ci/test/00_setup_env_amd64_tsan.sh"
+ TEST_RUNNER_EXTRA="--exclude feature_block" # Not enough memory on travis machines
- stage: test
name: 'x86_64 Linux [GOAL: install] [bionic] [no depends, only system libs, sanitizers: address/leak (ASan + LSan) + undefined (UBSan) + integer]'
diff --git a/build-aux/m4/ax_boost_base.m4 b/build-aux/m4/ax_boost_base.m4
index d540395763..16fa69b41f 100644
--- a/build-aux/m4/ax_boost_base.m4
+++ b/build-aux/m4/ax_boost_base.m4
@@ -33,7 +33,7 @@
# and this notice are preserved. This file is offered as-is, without any
# warranty.
-#serial 45
+#serial 47
# example boost program (need to pass version)
m4_define([_AX_BOOST_BASE_PROGRAM],
@@ -113,6 +113,7 @@ AC_DEFUN([_AX_BOOST_BASE_RUNDETECT],[
dnl are found, e.g. when only header-only libraries are installed!
AS_CASE([${host_cpu}],
[x86_64],[libsubdirs="lib64 libx32 lib lib64"],
+ [mips*64*],[libsubdirs="lib64 lib32 lib lib64"],
[ppc64|powerpc64|s390x|sparc64|aarch64|ppc64le|powerpc64le|riscv64],[libsubdirs="lib64 lib lib64"],
[libsubdirs="lib"]
)
diff --git a/build-aux/m4/ax_boost_chrono.m4 b/build-aux/m4/ax_boost_chrono.m4
index 6ea77b9b3e..4cd3b86041 100644
--- a/build-aux/m4/ax_boost_chrono.m4
+++ b/build-aux/m4/ax_boost_chrono.m4
@@ -29,7 +29,7 @@
# and this notice are preserved. This file is offered as-is, without any
# warranty.
-#serial 4
+#serial 5
AC_DEFUN([AX_BOOST_CHRONO],
[
@@ -105,7 +105,7 @@ AC_DEFUN([AX_BOOST_CHRONO],
fi
if test "x$ax_lib" = "x"; then
- AC_MSG_ERROR(Could not find a version of the library!)
+ AC_MSG_ERROR(Could not find a version of the Boost::Chrono library!)
fi
if test "x$link_chrono" = "xno"; then
AC_MSG_ERROR(Could not link against $ax_lib !)
diff --git a/build-aux/m4/ax_boost_filesystem.m4 b/build-aux/m4/ax_boost_filesystem.m4
index f5c9d56470..12f7bc5e2e 100644
--- a/build-aux/m4/ax_boost_filesystem.m4
+++ b/build-aux/m4/ax_boost_filesystem.m4
@@ -1,5 +1,5 @@
# ===========================================================================
-# http://www.gnu.org/software/autoconf-archive/ax_boost_filesystem.html
+# https://www.gnu.org/software/autoconf-archive/ax_boost_filesystem.html
# ===========================================================================
#
# SYNOPSIS
@@ -31,7 +31,7 @@
# and this notice are preserved. This file is offered as-is, without any
# warranty.
-#serial 26
+#serial 28
AC_DEFUN([AX_BOOST_FILESYSTEM],
[
@@ -80,7 +80,6 @@ AC_DEFUN([AX_BOOST_FILESYSTEM],
if test "x$ax_cv_boost_filesystem" = "xyes"; then
AC_DEFINE(HAVE_BOOST_FILESYSTEM,,[define if the Boost::Filesystem library is available])
BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'`
- ax_lib=
if test "x$ax_boost_user_filesystem_lib" = "x"; then
for libextension in `ls -r $BOOSTLIBDIR/libboost_filesystem* 2>/dev/null | sed 's,.*/lib,,' | sed 's,\..*,,'` ; do
ax_lib=${libextension}
@@ -105,7 +104,7 @@ AC_DEFUN([AX_BOOST_FILESYSTEM],
fi
if test "x$ax_lib" = "x"; then
- AC_MSG_ERROR(Could not find a version of the boost_filesystem library!)
+ AC_MSG_ERROR(Could not find a version of the Boost::Filesystem library!)
fi
if test "x$link_filesystem" != "xyes"; then
AC_MSG_ERROR(Could not link against $ax_lib !)
diff --git a/build-aux/m4/ax_boost_system.m4 b/build-aux/m4/ax_boost_system.m4
index 207d7be8de..323e2a676a 100644
--- a/build-aux/m4/ax_boost_system.m4
+++ b/build-aux/m4/ax_boost_system.m4
@@ -31,7 +31,7 @@
# and this notice are preserved. This file is offered as-is, without any
# warranty.
-#serial 19
+#serial 20
AC_DEFUN([AX_BOOST_SYSTEM],
[
@@ -108,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 library!)
+ AC_MSG_ERROR(Could not find a version of the Boost::System library!)
fi
if test "x$link_system" = "xno"; then
AC_MSG_ERROR(Could not link against $ax_lib !)
diff --git a/build-aux/m4/ax_boost_thread.m4 b/build-aux/m4/ax_boost_thread.m4
index 9f0bd0b23c..e9dea43535 100644
--- a/build-aux/m4/ax_boost_thread.m4
+++ b/build-aux/m4/ax_boost_thread.m4
@@ -1,5 +1,5 @@
# ===========================================================================
-# http://www.gnu.org/software/autoconf-archive/ax_boost_thread.html
+# https://www.gnu.org/software/autoconf-archive/ax_boost_thread.html
# ===========================================================================
#
# SYNOPSIS
@@ -30,73 +30,75 @@
# and this notice are preserved. This file is offered as-is, without any
# warranty.
-#serial 27
+#serial 32
AC_DEFUN([AX_BOOST_THREAD],
[
- AC_ARG_WITH([boost-thread],
- AS_HELP_STRING([--with-boost-thread@<:@=special-lib@:>@],
- [use the Thread library from boost - it is possible to specify a certain library for the linker
- e.g. --with-boost-thread=boost_thread-gcc-mt ]),
+ AC_ARG_WITH([boost-thread],
+ AS_HELP_STRING([--with-boost-thread@<:@=special-lib@:>@],
+ [use the Thread library from boost -
+ it is possible to specify a certain library for the linker
+ e.g. --with-boost-thread=boost_thread-gcc-mt ]),
[
- if test "$withval" = "no"; then
- want_boost="no"
- elif test "$withval" = "yes"; then
+ if test "$withval" = "yes"; then
want_boost="yes"
ax_boost_user_thread_lib=""
else
- want_boost="yes"
- ax_boost_user_thread_lib="$withval"
- fi
+ want_boost="yes"
+ ax_boost_user_thread_lib="$withval"
+ fi
],
[want_boost="yes"]
- )
+ )
- if test "x$want_boost" = "xyes"; then
+ if test "x$want_boost" = "xyes"; then
AC_REQUIRE([AC_PROG_CC])
AC_REQUIRE([AC_CANONICAL_BUILD])
- CPPFLAGS_SAVED="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
- export CPPFLAGS
+ CPPFLAGS_SAVED="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+ export CPPFLAGS
- LDFLAGS_SAVED="$LDFLAGS"
- LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
- export LDFLAGS
+ LDFLAGS_SAVED="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
+ export LDFLAGS
AC_CACHE_CHECK(whether the Boost::Thread library is available,
- ax_cv_boost_thread,
+ ax_cv_boost_thread,
[AC_LANG_PUSH([C++])
- CXXFLAGS_SAVE=$CXXFLAGS
+ CXXFLAGS_SAVE=$CXXFLAGS
- if test "x$host_os" = "xsolaris" ; then
- CXXFLAGS="-pthreads $CXXFLAGS"
- elif test "x$host_os" = "xmingw32" ; then
- CXXFLAGS="-mthreads $CXXFLAGS"
- else
- CXXFLAGS="-pthread $CXXFLAGS"
- fi
- AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <boost/thread/thread.hpp>]],
- [[boost::thread_group thrds;
- return 0;]])],
- ax_cv_boost_thread=yes, ax_cv_boost_thread=no)
- CXXFLAGS=$CXXFLAGS_SAVE
+ if test "x$host_os" = "xsolaris" ; then
+ CXXFLAGS="-pthreads $CXXFLAGS"
+ elif test "x$host_os" = "xmingw32" ; then
+ CXXFLAGS="-mthreads $CXXFLAGS"
+ else
+ CXXFLAGS="-pthread $CXXFLAGS"
+ fi
+ AC_COMPILE_IFELSE([
+ AC_LANG_PROGRAM(
+ [[@%:@include <boost/thread/thread.hpp>]],
+ [[boost::thread_group thrds;
+ return 0;]])],
+ ax_cv_boost_thread=yes, ax_cv_boost_thread=no)
+ CXXFLAGS=$CXXFLAGS_SAVE
AC_LANG_POP([C++])
- ])
- if test "x$ax_cv_boost_thread" = "xyes"; then
+ ])
+ if test "x$ax_cv_boost_thread" = "xyes"; then
if test "x$host_os" = "xsolaris" ; then
- BOOST_CPPFLAGS="-pthreads $BOOST_CPPFLAGS"
- elif test "x$host_os" = "xmingw32" ; then
- BOOST_CPPFLAGS="-mthreads $BOOST_CPPFLAGS"
- else
- BOOST_CPPFLAGS="-pthread $BOOST_CPPFLAGS"
- fi
+ BOOST_CPPFLAGS="-pthreads $BOOST_CPPFLAGS"
+ elif test "x$host_os" = "xmingw32" ; then
+ BOOST_CPPFLAGS="-mthreads $BOOST_CPPFLAGS"
+ else
+ BOOST_CPPFLAGS="-pthread $BOOST_CPPFLAGS"
+ fi
- AC_SUBST(BOOST_CPPFLAGS)
+ AC_SUBST(BOOST_CPPFLAGS)
- AC_DEFINE(HAVE_BOOST_THREAD,,[define if the Boost::Thread library is available])
+ AC_DEFINE(HAVE_BOOST_THREAD,,
+ [define if the Boost::Thread library is available])
BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'`
- LDFLAGS_SAVE=$LDFLAGS
+ LDFLAGS_SAVE=$LDFLAGS
case "x$host_os" in
*bsd* )
LDFLAGS="-pthread $LDFLAGS"
@@ -104,47 +106,58 @@ AC_DEFUN([AX_BOOST_THREAD],
;;
esac
if test "x$ax_boost_user_thread_lib" = "x"; then
- ax_lib=
for libextension in `ls -r $BOOSTLIBDIR/libboost_thread* 2>/dev/null | sed 's,.*/lib,,' | sed 's,\..*,,'`; do
ax_lib=${libextension}
- AC_CHECK_LIB($ax_lib, exit,
- [BOOST_THREAD_LIB="-l$ax_lib"; AC_SUBST(BOOST_THREAD_LIB) link_thread="yes"; break],
+ AC_CHECK_LIB($ax_lib, exit,
+ [link_thread="yes"; break],
[link_thread="no"])
- done
+ done
if test "x$link_thread" != "xyes"; then
for libextension in `ls -r $BOOSTLIBDIR/boost_thread* 2>/dev/null | sed 's,.*/,,' | sed 's,\..*,,'`; do
ax_lib=${libextension}
- AC_CHECK_LIB($ax_lib, exit,
- [BOOST_THREAD_LIB="-l$ax_lib"; AC_SUBST(BOOST_THREAD_LIB) link_thread="yes"; break],
+ AC_CHECK_LIB($ax_lib, exit,
+ [link_thread="yes"; break],
[link_thread="no"])
- done
+ done
fi
else
for ax_lib in $ax_boost_user_thread_lib boost_thread-$ax_boost_user_thread_lib; do
- AC_CHECK_LIB($ax_lib, exit,
- [BOOST_THREAD_LIB="-l$ax_lib"; AC_SUBST(BOOST_THREAD_LIB) link_thread="yes"; break],
+ AC_CHECK_LIB($ax_lib, exit,
+ [link_thread="yes"; break],
[link_thread="no"])
done
fi
if test "x$ax_lib" = "x"; then
- AC_MSG_ERROR(Could not find a version of the boost_thread library!)
+ AC_MSG_ERROR(Could not find a version of the Boost::Thread library!)
fi
- if test "x$link_thread" = "xno"; then
- AC_MSG_ERROR(Could not link against $ax_lib !)
- else
- case "x$host_os" in
- *bsd* )
- BOOST_LDFLAGS="-pthread $BOOST_LDFLAGS"
- break;
- ;;
- esac
-
- fi
- fi
+ if test "x$link_thread" = "xno"; then
+ AC_MSG_ERROR(Could not link against $ax_lib !)
+ else
+ BOOST_THREAD_LIB="-l$ax_lib"
+ case "x$host_os" in
+ *bsd* )
+ BOOST_LDFLAGS="-pthread $BOOST_LDFLAGS"
+ break;
+ ;;
+ xsolaris )
+ BOOST_THREAD_LIB="$BOOST_THREAD_LIB -lpthread"
+ break;
+ ;;
+ xmingw32 )
+ break;
+ ;;
+ * )
+ BOOST_THREAD_LIB="$BOOST_THREAD_LIB -lpthread"
+ break;
+ ;;
+ esac
+ AC_SUBST(BOOST_THREAD_LIB)
+ fi
+ fi
- CPPFLAGS="$CPPFLAGS_SAVED"
- LDFLAGS="$LDFLAGS_SAVED"
- fi
+ CPPFLAGS="$CPPFLAGS_SAVED"
+ LDFLAGS="$LDFLAGS_SAVED"
+ fi
])
diff --git a/build-aux/m4/ax_boost_unit_test_framework.m4 b/build-aux/m4/ax_boost_unit_test_framework.m4
index 3d8e93e964..4cca32fcfd 100644
--- a/build-aux/m4/ax_boost_unit_test_framework.m4
+++ b/build-aux/m4/ax_boost_unit_test_framework.m4
@@ -29,7 +29,7 @@
# and this notice are preserved. This file is offered as-is, without any
# warranty.
-#serial 21
+#serial 22
AC_DEFUN([AX_BOOST_UNIT_TEST_FRAMEWORK],
[
@@ -124,7 +124,7 @@ AC_DEFUN([AX_BOOST_UNIT_TEST_FRAMEWORK],
done
fi
if test "x$ax_lib" = "x"; then
- AC_MSG_ERROR(Could not find a version of the library!)
+ AC_MSG_ERROR(Could not find a version of the Boost::Unit_Test_Framework library!)
fi
if test "x$link_unit_test_framework" != "xyes"; then
AC_MSG_ERROR(Could not link against $ax_lib !)
diff --git a/ci/lint/04_install.sh b/ci/lint/04_install.sh
index 6c3019a1aa..12c3bfce45 100755
--- a/ci/lint/04_install.sh
+++ b/ci/lint/04_install.sh
@@ -8,7 +8,6 @@ export LC_ALL=C
travis_retry pip3 install codespell==1.15.0
travis_retry pip3 install flake8==3.7.8
-travis_retry pip3 install vulture==1.0
SHELLCHECK_VERSION=v0.6.0
curl -s "https://storage.googleapis.com/shellcheck/shellcheck-${SHELLCHECK_VERSION}.linux.x86_64.tar.xz" | tar --xz -xf - --directory /tmp/
diff --git a/ci/test/00_setup_env.sh b/ci/test/00_setup_env.sh
index 51b5cfdd3f..94598835ac 100755
--- a/ci/test/00_setup_env.sh
+++ b/ci/test/00_setup_env.sh
@@ -6,11 +6,17 @@
export LC_ALL=C.UTF-8
-echo "Setting default values in env"
+echo "Setting specific values in env"
+if [ -n "${FILE_ENV}" ]; then
+ set -o errexit;
+ # shellcheck disable=SC1090
+ source "${FILE_ENV}"
+fi
BASE_ROOT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )"/../../ >/dev/null 2>&1 && pwd )
export BASE_ROOT_DIR
+echo "Fallback to default values in env (if not yet set)"
# The number of parallel jobs to pass down to make and test_runner.py
export MAKEJOBS=${MAKEJOBS:--j4}
# A folder for the ci system to put temporary files (ccache, datadirs for tests, ...)
@@ -20,12 +26,16 @@ export RUN_UNIT_TESTS=${RUN_UNIT_TESTS:-true}
export RUN_FUNCTIONAL_TESTS=${RUN_FUNCTIONAL_TESTS:-true}
export RUN_FUZZ_TESTS=${RUN_FUZZ_TESTS:-false}
export DOCKER_NAME_TAG=${DOCKER_NAME_TAG:-ubuntu:18.04}
-export BOOST_TEST_RANDOM=${BOOST_TEST_RANDOM:-1$TRAVIS_BUILD_ID}
+# Randomize test order.
+# See https://www.boost.org/doc/libs/1_71_0/libs/test/doc/html/boost_test/utf_reference/rt_param_reference/random.html
+export BOOST_TEST_RANDOM=${BOOST_TEST_RANDOM:-1}
export CCACHE_SIZE=${CCACHE_SIZE:-100M}
export CCACHE_TEMPDIR=${CCACHE_TEMPDIR:-/tmp/.ccache-temp}
export CCACHE_COMPRESS=${CCACHE_COMPRESS:-1}
export CCACHE_DIR=${CCACHE_DIR:-$BASE_SCRATCH_DIR/.ccache}
-export BASE_BUILD_DIR=${BASE_BUILD_DIR:-${TRAVIS_BUILD_DIR:-$BASE_ROOT_DIR}}
+# Folder where the build is done (depends and dist). Can not be changed and is equal to the root of the git repo
+export BASE_BUILD_DIR=${BASE_BUILD_DIR:-$BASE_ROOT_DIR}
+# Folder where the build is done (bin and lib). Can not be changed.
export BASE_OUTDIR=${BASE_OUTDIR:-$BASE_BUILD_DIR/out/$HOST}
export SDK_URL=${SDK_URL:-https://bitcoincore.org/depends-sources/sdks}
export WINEDEBUG=${WINEDEBUG:-fixme-all}
@@ -34,10 +44,3 @@ export GOAL=${GOAL:-install}
export DIR_QA_ASSETS=${DIR_QA_ASSETS:-${BASE_BUILD_DIR}/qa-assets}
export PATH=${BASE_ROOT_DIR}/ci/retry:$PATH
export CI_RETRY_EXE=${CI_RETRY_EXE:retry}
-
-echo "Setting specific values in env"
-if [ -n "${FILE_ENV}" ]; then
- set -o errexit;
- # shellcheck disable=SC1090
- source "${FILE_ENV}"
-fi
diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk
index 56045ade50..f4832b6168 100644
--- a/depends/packages/qt.mk
+++ b/depends/packages/qt.mk
@@ -176,9 +176,9 @@ define $(package)_preprocess_cmds
patch -p1 -i $($(package)_patch_dir)/no-xlib.patch &&\
echo "QMAKE_LINK_OBJECT_MAX = 10" >> qtbase/mkspecs/win32-g++/qmake.conf &&\
echo "QMAKE_LINK_OBJECT_SCRIPT = object_script" >> qtbase/mkspecs/win32-g++/qmake.conf &&\
- sed -i.old "s|QMAKE_CFLAGS = |!host_build: QMAKE_CFLAGS = $($(package)_cflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \
- sed -i.old "s|QMAKE_LFLAGS = |!host_build: QMAKE_LFLAGS = $($(package)_ldflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \
- sed -i.old "s|QMAKE_CXXFLAGS = |!host_build: QMAKE_CXXFLAGS = $($(package)_cxxflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \
+ sed -i.old "s|QMAKE_CFLAGS += |!host_build: QMAKE_CFLAGS = $($(package)_cflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \
+ sed -i.old "s|QMAKE_CXXFLAGS += |!host_build: QMAKE_CXXFLAGS = $($(package)_cxxflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \
+ sed -i.old "0,/^QMAKE_LFLAGS_/s|^QMAKE_LFLAGS_|!host_build: QMAKE_LFLAGS = $($(package)_ldflags)\n&|" qtbase/mkspecs/win32-g++/qmake.conf && \
sed -i.old "s/LIBRARY_PATH/(CROSS_)?\0/g" qtbase/mkspecs/features/toolchain.prf
endef
diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in
index 399d54eb85..cd7ccf80ab 100644
--- a/doc/Doxyfile.in
+++ b/doc/Doxyfile.in
@@ -790,7 +790,7 @@ WARN_LOGFILE =
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched.
-INPUT = src
+INPUT = src doc/README_doxygen.md
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
@@ -974,7 +974,7 @@ FILTER_SOURCE_PATTERNS =
# (index.html). This can be useful if you have a project on for instance GitHub
# and want to reuse the introduction page also for the doxygen output.
-USE_MDFILE_AS_MAINPAGE =
+USE_MDFILE_AS_MAINPAGE = doc/README_doxygen.md
#---------------------------------------------------------------------------
# Configuration options related to source browsing
diff --git a/doc/README_doxygen.md b/doc/README_doxygen.md
new file mode 100644
index 0000000000..6888383a98
--- /dev/null
+++ b/doc/README_doxygen.md
@@ -0,0 +1,15 @@
+\mainpage notitle
+
+\section intro_sec Introduction
+
+This is the developer documentation of the reference client for an experimental new digital currency called Bitcoin,
+which enables instant payments to anyone, anywhere in the world. Bitcoin uses peer-to-peer technology to operate
+with no central authority: managing transactions and issuing money are carried out collectively by the network.
+
+The software is a community-driven open source project, released under the MIT license.
+
+See https://github.com/bitcoin/bitcoin and https://bitcoincore.org/ for further information about the project.
+
+\section Navigation
+Use <a href="modules.html"><code>Modules</code></a>, <a href="namespaces.html"><code>Namespaces</code></a>, <a href="classes.html"><code>Classes</code></a>, or <a href="files.html"><code>Files</code></a> at the top of the page to start navigating the code.
+
diff --git a/doc/translation_process.md b/doc/translation_process.md
index 0e9245250f..39f878cea3 100644
--- a/doc/translation_process.md
+++ b/doc/translation_process.md
@@ -73,16 +73,10 @@ To assist in updating translations, a helper script is available in the [maintai
```bash
git ls-files src/qt/locale/*ts|xargs -n1 basename|sed 's/\(bitcoin_\(.*\)\).ts/ <file alias="\2">locale\/\1.qm<\/file>/'
```
-4. Update `src/Makefile.qt.include` manually or via
+4. Update `src/Makefile.qt_locale.include` manually or via
```bash
git ls-files src/qt/locale/*ts|xargs -n1 basename|sed 's/\(bitcoin_\(.*\)\).ts/ qt\/locale\/\1.ts \\/'
```
-5. Update `build_msvc/libbitcoin_qt/libbitcoin_qt.vcxproj` or via
-```bash
-git ls-files src/qt/locale/*ts|xargs -n1 basename |
- sed 's/@/%40/' |
- sed 's/\(bitcoin_\(.*\)\).ts/ <None Include="..\\..\\src\\qt\\locale\\\1.ts">\n <DeploymentContent>true<\/DeploymentContent>\n <\/None>/'
-```
**Do not directly download translations** one by one from the Transifex website, as we do a few post-processing steps before committing the translations.
diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include
index 7540122418..a8d3154107 100644
--- a/src/Makefile.qt.include
+++ b/src/Makefile.qt.include
@@ -6,93 +6,7 @@ bin_PROGRAMS += qt/bitcoin-qt
EXTRA_LIBRARIES += qt/libbitcoinqt.a
# bitcoin qt core #
-QT_TS = \
- qt/locale/bitcoin_af.ts \
- qt/locale/bitcoin_af_ZA.ts \
- qt/locale/bitcoin_ar.ts \
- qt/locale/bitcoin_be_BY.ts \
- qt/locale/bitcoin_bg_BG.ts \
- qt/locale/bitcoin_bg.ts \
- qt/locale/bitcoin_ca_ES.ts \
- qt/locale/bitcoin_ca.ts \
- qt/locale/bitcoin_ca@valencia.ts \
- qt/locale/bitcoin_cs.ts \
- qt/locale/bitcoin_cy.ts \
- qt/locale/bitcoin_da.ts \
- qt/locale/bitcoin_de.ts \
- qt/locale/bitcoin_el_GR.ts \
- qt/locale/bitcoin_el.ts \
- qt/locale/bitcoin_en_GB.ts \
- qt/locale/bitcoin_en.ts \
- qt/locale/bitcoin_eo.ts \
- qt/locale/bitcoin_es_AR.ts \
- qt/locale/bitcoin_es_CL.ts \
- qt/locale/bitcoin_es_CO.ts \
- qt/locale/bitcoin_es_DO.ts \
- qt/locale/bitcoin_es_ES.ts \
- qt/locale/bitcoin_es_MX.ts \
- qt/locale/bitcoin_es.ts \
- qt/locale/bitcoin_es_UY.ts \
- qt/locale/bitcoin_es_VE.ts \
- qt/locale/bitcoin_et_EE.ts \
- qt/locale/bitcoin_et.ts \
- qt/locale/bitcoin_eu_ES.ts \
- qt/locale/bitcoin_fa_IR.ts \
- qt/locale/bitcoin_fa.ts \
- qt/locale/bitcoin_fi.ts \
- qt/locale/bitcoin_fr_CA.ts \
- qt/locale/bitcoin_fr_FR.ts \
- qt/locale/bitcoin_fr.ts \
- qt/locale/bitcoin_gl.ts \
- qt/locale/bitcoin_he.ts \
- qt/locale/bitcoin_hi_IN.ts \
- qt/locale/bitcoin_hr.ts \
- qt/locale/bitcoin_hu.ts \
- qt/locale/bitcoin_id_ID.ts \
- qt/locale/bitcoin_it_IT.ts \
- qt/locale/bitcoin_it.ts \
- qt/locale/bitcoin_ja.ts \
- qt/locale/bitcoin_ka.ts \
- qt/locale/bitcoin_kk_KZ.ts \
- qt/locale/bitcoin_ko_KR.ts \
- qt/locale/bitcoin_ku_IQ.ts \
- qt/locale/bitcoin_ky.ts \
- qt/locale/bitcoin_la.ts \
- qt/locale/bitcoin_lt.ts \
- qt/locale/bitcoin_lv_LV.ts \
- qt/locale/bitcoin_mk_MK.ts \
- qt/locale/bitcoin_mn.ts \
- qt/locale/bitcoin_ms_MY.ts \
- qt/locale/bitcoin_nb.ts \
- qt/locale/bitcoin_ne.ts \
- qt/locale/bitcoin_nl.ts \
- qt/locale/bitcoin_pam.ts \
- qt/locale/bitcoin_pl.ts \
- qt/locale/bitcoin_pt_BR.ts \
- qt/locale/bitcoin_pt_PT.ts \
- qt/locale/bitcoin_ro_RO.ts \
- qt/locale/bitcoin_ro.ts \
- qt/locale/bitcoin_ru_RU.ts \
- qt/locale/bitcoin_ru.ts \
- qt/locale/bitcoin_sk.ts \
- qt/locale/bitcoin_sl_SI.ts \
- qt/locale/bitcoin_sq.ts \
- qt/locale/bitcoin_sr@latin.ts \
- qt/locale/bitcoin_sr.ts \
- qt/locale/bitcoin_sv.ts \
- qt/locale/bitcoin_ta.ts \
- qt/locale/bitcoin_th_TH.ts \
- qt/locale/bitcoin_tr_TR.ts \
- qt/locale/bitcoin_tr.ts \
- qt/locale/bitcoin_uk.ts \
- qt/locale/bitcoin_ur_PK.ts \
- qt/locale/bitcoin_uz@Cyrl.ts \
- qt/locale/bitcoin_vi.ts \
- qt/locale/bitcoin_vi_VN.ts \
- qt/locale/bitcoin_zh_CN.ts \
- qt/locale/bitcoin_zh_HK.ts \
- qt/locale/bitcoin_zh.ts \
- qt/locale/bitcoin_zh_TW.ts
+include Makefile.qt_locale.include
QT_FORMS_UI = \
qt/forms/addressbookpage.ui \
diff --git a/src/Makefile.qt_locale.include b/src/Makefile.qt_locale.include
new file mode 100644
index 0000000000..d9f23e8da2
--- /dev/null
+++ b/src/Makefile.qt_locale.include
@@ -0,0 +1,87 @@
+QT_TS = \
+ qt/locale/bitcoin_af.ts \
+ qt/locale/bitcoin_af_ZA.ts \
+ qt/locale/bitcoin_ar.ts \
+ qt/locale/bitcoin_be_BY.ts \
+ qt/locale/bitcoin_bg_BG.ts \
+ qt/locale/bitcoin_bg.ts \
+ qt/locale/bitcoin_ca_ES.ts \
+ qt/locale/bitcoin_ca.ts \
+ qt/locale/bitcoin_ca@valencia.ts \
+ qt/locale/bitcoin_cs.ts \
+ qt/locale/bitcoin_cy.ts \
+ qt/locale/bitcoin_da.ts \
+ qt/locale/bitcoin_de.ts \
+ qt/locale/bitcoin_el_GR.ts \
+ qt/locale/bitcoin_el.ts \
+ qt/locale/bitcoin_en_GB.ts \
+ qt/locale/bitcoin_en.ts \
+ qt/locale/bitcoin_eo.ts \
+ qt/locale/bitcoin_es_AR.ts \
+ qt/locale/bitcoin_es_CL.ts \
+ qt/locale/bitcoin_es_CO.ts \
+ qt/locale/bitcoin_es_DO.ts \
+ qt/locale/bitcoin_es_ES.ts \
+ qt/locale/bitcoin_es_MX.ts \
+ qt/locale/bitcoin_es.ts \
+ qt/locale/bitcoin_es_UY.ts \
+ qt/locale/bitcoin_es_VE.ts \
+ qt/locale/bitcoin_et_EE.ts \
+ qt/locale/bitcoin_et.ts \
+ qt/locale/bitcoin_eu_ES.ts \
+ qt/locale/bitcoin_fa_IR.ts \
+ qt/locale/bitcoin_fa.ts \
+ qt/locale/bitcoin_fi.ts \
+ qt/locale/bitcoin_fr_CA.ts \
+ qt/locale/bitcoin_fr_FR.ts \
+ qt/locale/bitcoin_fr.ts \
+ qt/locale/bitcoin_gl.ts \
+ qt/locale/bitcoin_he.ts \
+ qt/locale/bitcoin_hi_IN.ts \
+ qt/locale/bitcoin_hr.ts \
+ qt/locale/bitcoin_hu.ts \
+ qt/locale/bitcoin_id_ID.ts \
+ qt/locale/bitcoin_it_IT.ts \
+ qt/locale/bitcoin_it.ts \
+ qt/locale/bitcoin_ja.ts \
+ qt/locale/bitcoin_ka.ts \
+ qt/locale/bitcoin_kk_KZ.ts \
+ qt/locale/bitcoin_ko_KR.ts \
+ qt/locale/bitcoin_ku_IQ.ts \
+ qt/locale/bitcoin_ky.ts \
+ qt/locale/bitcoin_la.ts \
+ qt/locale/bitcoin_lt.ts \
+ qt/locale/bitcoin_lv_LV.ts \
+ qt/locale/bitcoin_mk_MK.ts \
+ qt/locale/bitcoin_mn.ts \
+ qt/locale/bitcoin_ms_MY.ts \
+ qt/locale/bitcoin_nb.ts \
+ qt/locale/bitcoin_ne.ts \
+ qt/locale/bitcoin_nl.ts \
+ qt/locale/bitcoin_pam.ts \
+ qt/locale/bitcoin_pl.ts \
+ qt/locale/bitcoin_pt_BR.ts \
+ qt/locale/bitcoin_pt_PT.ts \
+ qt/locale/bitcoin_ro_RO.ts \
+ qt/locale/bitcoin_ro.ts \
+ qt/locale/bitcoin_ru_RU.ts \
+ qt/locale/bitcoin_ru.ts \
+ qt/locale/bitcoin_sk.ts \
+ qt/locale/bitcoin_sl_SI.ts \
+ qt/locale/bitcoin_sq.ts \
+ qt/locale/bitcoin_sr@latin.ts \
+ qt/locale/bitcoin_sr.ts \
+ qt/locale/bitcoin_sv.ts \
+ qt/locale/bitcoin_ta.ts \
+ qt/locale/bitcoin_th_TH.ts \
+ qt/locale/bitcoin_tr_TR.ts \
+ qt/locale/bitcoin_tr.ts \
+ qt/locale/bitcoin_uk.ts \
+ qt/locale/bitcoin_ur_PK.ts \
+ qt/locale/bitcoin_uz@Cyrl.ts \
+ qt/locale/bitcoin_vi.ts \
+ qt/locale/bitcoin_vi_VN.ts \
+ qt/locale/bitcoin_zh_CN.ts \
+ qt/locale/bitcoin_zh_HK.ts \
+ qt/locale/bitcoin_zh.ts \
+ qt/locale/bitcoin_zh_TW.ts
diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp
index 83de684a2b..615b955f6e 100644
--- a/src/bitcoind.cpp
+++ b/src/bitcoind.cpp
@@ -25,24 +25,6 @@
const std::function<std::string(const char*)> G_TRANSLATION_FUN = nullptr;
-/* Introduction text for doxygen: */
-
-/*! \mainpage Developer documentation
- *
- * \section intro_sec Introduction
- *
- * This is the developer documentation of the reference client for an experimental new digital currency called Bitcoin,
- * which enables instant payments to anyone, anywhere in the world. Bitcoin uses peer-to-peer technology to operate
- * with no central authority: managing transactions and issuing money are carried out collectively by the network.
- *
- * The software is a community-driven open source project, released under the MIT license.
- *
- * See https://github.com/bitcoin/bitcoin and https://bitcoincore.org/ for further information about the project.
- *
- * \section Navigation
- * Use the buttons <code>Namespaces</code>, <code>Classes</code> or <code>Files</code> at the top of the page to start navigating the code.
- */
-
static void WaitForShutdown()
{
while (!ShutdownRequested())
diff --git a/src/chainparams.cpp b/src/chainparams.cpp
index ad766471dc..5964877eb8 100644
--- a/src/chainparams.cpp
+++ b/src/chainparams.cpp
@@ -71,6 +71,7 @@ public:
consensus.BIP66Height = 363725; // 00000000000000000379eaa19dce8c9b722d46ae6a57c2f1a988119488b50931
consensus.CSVHeight = 419328; // 000000000000000004a1b34462cb8aeebd5799177f7a29cf28f2d1961716b5b5
consensus.SegwitHeight = 481824; // 0000000000000000001c8018d9cb3b742ef25114f27563e3fc4a1902167f9893
+ consensus.MinBIP9WarningHeight = consensus.SegwitHeight + consensus.nMinerConfirmationWindow;
consensus.powLimit = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks
consensus.nPowTargetSpacing = 10 * 60;
@@ -177,6 +178,7 @@ public:
consensus.BIP66Height = 330776; // 000000002104c8c45e99a8853285a3b592602a3ccde2b832481da85e9e4ba182
consensus.CSVHeight = 770112; // 00000000025e930139bac5c6c31a403776da130831ab85be56578f3fa75369bb
consensus.SegwitHeight = 834624; // 00000000002b980fcd729daaa248fd9316a5200e9b367f4ff2c42453e84201ca
+ consensus.MinBIP9WarningHeight = consensus.SegwitHeight + consensus.nMinerConfirmationWindow;
consensus.powLimit = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks
consensus.nPowTargetSpacing = 10 * 60;
@@ -261,6 +263,7 @@ public:
consensus.BIP66Height = 1251; // BIP66 activated on regtest (Used in functional tests)
consensus.CSVHeight = 432; // CSV activated on regtest (Used in rpc activation tests)
consensus.SegwitHeight = 0; // SEGWIT is always activated on regtest unless overridden
+ consensus.MinBIP9WarningHeight = 0;
consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks
consensus.nPowTargetSpacing = 10 * 60;
diff --git a/src/coins.h b/src/coins.h
index dca1beabb6..d8135e0d9a 100644
--- a/src/coins.h
+++ b/src/coins.h
@@ -95,8 +95,16 @@ public:
* This *must* return size_t. With Boost 1.46 on 32-bit systems the
* unordered_map will behave unpredictably if the custom hasher returns a
* uint64_t, resulting in failures when syncing the chain (#4634).
+ *
+ * Having the hash noexcept allows libstdc++'s unordered_map to recalculate
+ * the hash during rehash, so it does not have to cache the value. This
+ * reduces node's memory by sizeof(size_t). The required recalculation has
+ * a slight performance penalty (around 1.6%), but this is compensated by
+ * memory savings of about 9% which allow for a larger dbcache setting.
+ *
+ * @see https://gcc.gnu.org/onlinedocs/gcc-9.2.0/libstdc++/manual/manual/unordered_associative.html
*/
- size_t operator()(const COutPoint& id) const {
+ size_t operator()(const COutPoint& id) const noexcept {
return SipHashUint256Extra(k0, k1, id.hash, id.n);
}
};
diff --git a/src/consensus/params.h b/src/consensus/params.h
index 8263b0fef4..2f8c490dc4 100644
--- a/src/consensus/params.h
+++ b/src/consensus/params.h
@@ -62,6 +62,9 @@ struct Params {
* Note that segwit v0 script rules are enforced on all blocks except the
* BIP 16 exception blocks. */
int SegwitHeight;
+ /** Don't warn about unknown BIP 9 activations below this height.
+ * This prevents us from warning about the CSV and segwit activations. */
+ int MinBIP9WarningHeight;
/**
* Minimum blocks including miner confirmation of the total of 2016 blocks in a retargeting period,
* (nPowTargetTimespan / nPowTargetSpacing) which is also used for BIP9 deployments.
diff --git a/src/net.cpp b/src/net.cpp
index 89f82aa3d2..63b7833822 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -50,6 +50,9 @@ static_assert(MINIUPNPC_API_VERSION >= 10, "miniUPnPc API version >= 10 assumed"
// Dump addresses to peers.dat every 15 minutes (900s)
static constexpr int DUMP_PEERS_INTERVAL = 15 * 60;
+/** Number of DNS seeds to query when the number of connections is low. */
+static constexpr int DNSSEEDS_TO_QUERY_AT_ONCE = 3;
+
// We add a random period time (0 to 1 seconds) to feeler connections to prevent synchronization.
#define FEELER_SLEEP_WINDOW 1
@@ -1535,35 +1538,41 @@ void StopMapPort()
void CConnman::ThreadDNSAddressSeed()
{
- // goal: only query DNS seeds if address need is acute
- // Avoiding DNS seeds when we don't need them improves user privacy by
- // creating fewer identifying DNS requests, reduces trust by giving seeds
- // less influence on the network topology, and reduces traffic to the seeds.
- if ((addrman.size() > 0) &&
- (!gArgs.GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED))) {
- if (!interruptNet.sleep_for(std::chrono::seconds(11)))
- return;
+ FastRandomContext rng;
+ std::vector<std::string> seeds = Params().DNSSeeds();
+ Shuffle(seeds.begin(), seeds.end(), rng);
+ int seeds_right_now = 0; // Number of seeds left before testing if we have enough connections
+ int found = 0;
- LOCK(cs_vNodes);
- int nRelevant = 0;
- for (const CNode* pnode : vNodes) {
- nRelevant += pnode->fSuccessfullyConnected && !pnode->fFeeler && !pnode->fOneShot && !pnode->m_manual_connection && !pnode->fInbound;
- }
- if (nRelevant >= 2) {
- LogPrintf("P2P peers available. Skipped DNS seeding.\n");
- return;
- }
+ if (gArgs.GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED)) {
+ // When -forcednsseed is provided, query all.
+ seeds_right_now = seeds.size();
}
- const std::vector<std::string> &vSeeds = Params().DNSSeeds();
- int found = 0;
+ for (const std::string& seed : seeds) {
+ // goal: only query DNS seed if address need is acute
+ // Avoiding DNS seeds when we don't need them improves user privacy by
+ // creating fewer identifying DNS requests, reduces trust by giving seeds
+ // less influence on the network topology, and reduces traffic to the seeds.
+ if (addrman.size() > 0 && seeds_right_now == 0) {
+ if (!interruptNet.sleep_for(std::chrono::seconds(11))) return;
- LogPrintf("Loading addresses from DNS seeds (could take a while)\n");
+ LOCK(cs_vNodes);
+ int nRelevant = 0;
+ for (const CNode* pnode : vNodes) {
+ nRelevant += pnode->fSuccessfullyConnected && !pnode->fFeeler && !pnode->fOneShot && !pnode->m_manual_connection && !pnode->fInbound;
+ }
+ if (nRelevant >= 2) {
+ LogPrintf("P2P peers available. Skipped DNS seeding.\n");
+ return;
+ }
+ seeds_right_now += DNSSEEDS_TO_QUERY_AT_ONCE;
+ }
- for (const std::string &seed : vSeeds) {
if (interruptNet) {
return;
}
+ LogPrintf("Loading addresses from DNS seed %s\n", seed);
if (HaveNameProxy()) {
AddOneShot(seed);
} else {
@@ -1576,13 +1585,11 @@ void CConnman::ThreadDNSAddressSeed()
continue;
}
unsigned int nMaxIPs = 256; // Limits number of IPs learned from a DNS seed
- if (LookupHost(host.c_str(), vIPs, nMaxIPs, true))
- {
- for (const CNetAddr& ip : vIPs)
- {
+ if (LookupHost(host.c_str(), vIPs, nMaxIPs, true)) {
+ for (const CNetAddr& ip : vIPs) {
int nOneDay = 24*3600;
CAddress addr = CAddress(CService(ip, Params().GetDefaultPort()), requiredServiceBits);
- addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
+ addr.nTime = GetTime() - 3*nOneDay - rng.randrange(4*nOneDay); // use a random age between 3 and 7 days old
vAdd.push_back(addr);
found++;
}
@@ -1593,8 +1600,8 @@ void CConnman::ThreadDNSAddressSeed()
AddOneShot(seed);
}
}
+ --seeds_right_now;
}
-
LogPrintf("%d addresses found from DNS seeds\n", found);
}
diff --git a/src/qt/forms/receivecoinsdialog.ui b/src/qt/forms/receivecoinsdialog.ui
index 0d280f2993..0214356eaa 100644
--- a/src/qt/forms/receivecoinsdialog.ui
+++ b/src/qt/forms/receivecoinsdialog.ui
@@ -189,7 +189,7 @@
</widget>
</item>
<item>
- <widget class="QCheckBox" name="useLegacyAddress">
+ <widget class="QCheckBox" name="useBech32">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
@@ -206,10 +206,10 @@
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
- <string>Native segwit addresses (aka Bech32 or BIP-173) reduce your transaction fees later on and offer better protection against typos, but old wallets don't support them. When checked, an address compatible with older wallets will be created instead.</string>
+ <string>Native segwit addresses (aka Bech32 or BIP-173) reduce your transaction fees later on and offer better protection against typos, but old wallets don't support them. When unchecked, an address compatible with older wallets will be created instead.</string>
</property>
<property name="text">
- <string>Generate legacy address</string>
+ <string>Generate native segwit (Bech32) address</string>
</property>
</widget>
</item>
@@ -360,7 +360,7 @@
<tabstops>
<tabstop>reqLabel</tabstop>
<tabstop>reqAmount</tabstop>
- <tabstop>useLegacyAddress</tabstop>
+ <tabstop>useBech32</tabstop>
<tabstop>reqMessage</tabstop>
<tabstop>receiveButton</tabstop>
<tabstop>clearButton</tabstop>
diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp
index 9e05c63aa0..53c80639b9 100644
--- a/src/qt/intro.cpp
+++ b/src/qt/intro.cpp
@@ -154,6 +154,7 @@ Intro::Intro(QWidget *parent, uint64_t blockchain_size, uint64_t chain_state_siz
storageRequiresMsg.arg(requiredSpace) + " " +
tr("The wallet will also be stored in this directory.")
);
+ this->adjustSize();
startThread();
}
diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts
index 7d9e7eab4e..d34fd9eb45 100644
--- a/src/qt/locale/bitcoin_en.ts
+++ b/src/qt/locale/bitcoin_en.ts
@@ -2696,17 +2696,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+136"/>
- <source>Native segwit addresses (aka Bech32 or BIP-173) reduce your transaction fees later on and offer better protection against typos, but old wallets don&apos;t support them. When checked, an address compatible with older wallets will be created instead.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+3"/>
- <source>Generate legacy address</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="-178"/>
+ <location line="-39"/>
<location line="+153"/>
<source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
<translation type="unfinished"></translation>
@@ -2727,7 +2717,17 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+142"/>
+ <location line="+78"/>
+ <source>Native segwit addresses (aka Bech32 or BIP-173) reduce your transaction fees later on and offer better protection against typos, but old wallets don&apos;t support them. When unchecked, an address compatible with older wallets will be created instead.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Generate native segwit (Bech32) address</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+61"/>
<source>Requested payments history</source>
<translation type="unfinished"></translation>
</message>
diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp
index e8cf432131..df8d5115d5 100644
--- a/src/qt/receivecoinsdialog.cpp
+++ b/src/qt/receivecoinsdialog.cpp
@@ -96,13 +96,13 @@ void ReceiveCoinsDialog::setModel(WalletModel *_model)
if (model->node().isAddressTypeSet()) {
// user explicitly set the type, use it
if (model->wallet().getDefaultAddressType() == OutputType::BECH32) {
- ui->useLegacyAddress->setCheckState(Qt::Unchecked);
+ ui->useBech32->setCheckState(Qt::Checked);
} else {
- ui->useLegacyAddress->setCheckState(Qt::Checked);
+ ui->useBech32->setCheckState(Qt::Unchecked);
}
} else {
// Always fall back to bech32 in the gui
- ui->useLegacyAddress->setCheckState(Qt::Unchecked);
+ ui->useBech32->setCheckState(Qt::Checked);
}
// Set the button to be enabled or disabled based on whether the wallet can give out new addresses.
@@ -155,7 +155,7 @@ void ReceiveCoinsDialog::on_receiveButton_clicked()
QString label = ui->reqLabel->text();
/* Generate new receiving address */
OutputType address_type;
- if (!ui->useLegacyAddress->isChecked()) {
+ if (ui->useBech32->isChecked()) {
address_type = OutputType::BECH32;
} else {
address_type = model->wallet().getDefaultAddressType();
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index 9513c2b9ac..02717fa80f 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -1159,7 +1159,7 @@ static void BIP9SoftForkDescPushBack(UniValue& softforks, const std::string &nam
{
bip9.pushKV("bit", consensusParams.vDeployments[id].bit);
}
- bip9.pushKV("startTime", consensusParams.vDeployments[id].nStartTime);
+ bip9.pushKV("start_time", consensusParams.vDeployments[id].nStartTime);
bip9.pushKV("timeout", consensusParams.vDeployments[id].nTimeout);
int64_t since_height = VersionBitsTipStateSinceHeight(consensusParams, id);
bip9.pushKV("since", since_height);
@@ -1213,7 +1213,7 @@ UniValue getblockchaininfo(const JSONRPCRequest& request)
" \"bip9\": { (object) status of bip9 softforks (only for \"bip9\" type)\n"
" \"status\": \"xxxx\", (string) one of \"defined\", \"started\", \"locked_in\", \"active\", \"failed\"\n"
" \"bit\": xx, (numeric) the bit (0-28) in the block version field used to signal this softfork (only for \"started\" status)\n"
- " \"startTime\": xx, (numeric) the minimum median time past of a block at which the bit gains its meaning\n"
+ " \"start_time\": xx, (numeric) the minimum median time past of a block at which the bit gains its meaning\n"
" \"timeout\": xx, (numeric) the median time past of a block at which the deployment is considered failed if not yet locked in\n"
" \"since\": xx, (numeric) height of the first block to which the status applies\n"
" \"statistics\": { (object) numeric statistics about BIP9 signalling for a softfork\n"
diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp
index 461e8025da..f548d356cf 100644
--- a/src/rpc/rawtransaction.cpp
+++ b/src/rpc/rawtransaction.cpp
@@ -39,9 +39,9 @@
#include <univalue.h>
-/** High fee rate for sendrawtransaction and testmempoolaccept.
- * By default, transaction with a fee rate higher than this will be rejected by
- * the RPCs. This can be overridden with the maxfeerate argument.
+/** Maximum fee rate for sendrawtransaction and testmempoolaccept.
+ * By default, a transaction with a fee rate higher than this will be rejected
+ * by the RPCs. This can be overridden with the maxfeerate argument.
*/
static const CFeeRate DEFAULT_MAX_RAW_TX_FEE_RATE{COIN / 10};
diff --git a/src/streams.h b/src/streams.h
index 4e600f1826..517eefc932 100644
--- a/src/streams.h
+++ b/src/streams.h
@@ -735,16 +735,17 @@ protected:
size_t nBytes = fread((void*)&vchBuf[pos], 1, readNow, src);
if (nBytes == 0) {
throw std::ios_base::failure(feof(src) ? "CBufferedFile::Fill: end of file" : "CBufferedFile::Fill: fread failed");
- } else {
- nSrcPos += nBytes;
- return true;
}
+ nSrcPos += nBytes;
+ return true;
}
public:
CBufferedFile(FILE *fileIn, uint64_t nBufSize, uint64_t nRewindIn, int nTypeIn, int nVersionIn) :
nType(nTypeIn), nVersion(nVersionIn), nSrcPos(0), nReadPos(0), nReadLimit(std::numeric_limits<uint64_t>::max()), nRewind(nRewindIn), vchBuf(nBufSize, 0)
{
+ if (nRewindIn >= nBufSize)
+ throw std::ios_base::failure("Rewind limit must be less than buffer size");
src = fileIn;
}
@@ -777,8 +778,6 @@ public:
void read(char *pch, size_t nSize) {
if (nSize + nReadPos > nReadLimit)
throw std::ios_base::failure("Read attempted past buffer limit");
- if (nSize + nRewind > vchBuf.size())
- throw std::ios_base::failure("Read larger than buffer size");
while (nSize > 0) {
if (nReadPos == nSrcPos)
Fill();
@@ -802,16 +801,19 @@ public:
//! rewind to a given reading position
bool SetPos(uint64_t nPos) {
- nReadPos = nPos;
- if (nReadPos + nRewind < nSrcPos) {
- nReadPos = nSrcPos - nRewind;
+ size_t bufsize = vchBuf.size();
+ if (nPos + bufsize < nSrcPos) {
+ // rewinding too far, rewind as far as possible
+ nReadPos = nSrcPos - bufsize;
return false;
- } else if (nReadPos > nSrcPos) {
+ }
+ if (nPos > nSrcPos) {
+ // can't go this far forward, go as far as possible
nReadPos = nSrcPos;
return false;
- } else {
- return true;
}
+ nReadPos = nPos;
+ return true;
}
bool Seek(uint64_t nPos) {
diff --git a/src/test/README.md b/src/test/README.md
index 8901fae7bd..96dcb072bc 100644
--- a/src/test/README.md
+++ b/src/test/README.md
@@ -1,3 +1,15 @@
+# Unit tests
+
+The sources in this directory are unit test cases. Boost includes a
+unit testing framework, and since Bitcoin Core already uses Boost, it makes
+sense to simply use this framework rather than require developers to
+configure some other framework (we want as few impediments to creating
+unit tests as possible).
+
+The build system is set up to compile an executable called `test_bitcoin`
+that runs all of the unit tests. The main source file is called
+`setup_common.cpp`.
+
### Compiling/running unit tests
Unit tests will be automatically compiled if dependencies were met in `./configure`
@@ -12,7 +24,7 @@ to run the bitcoind tests.
To add more bitcoind tests, add `BOOST_AUTO_TEST_CASE` functions to the existing
.cpp files in the `test/` directory or add new .cpp files that
-implement new BOOST_AUTO_TEST_SUITE sections.
+implement new `BOOST_AUTO_TEST_SUITE` sections.
To run the bitcoin-qt tests manually, launch `src/qt/test/test_bitcoin-qt`
@@ -32,20 +44,24 @@ example, to run just the getarg_tests verbosely:
Run `test_bitcoin --help` for the full list.
-### Note on adding test cases
-
-The sources in this directory are unit test cases. Boost includes a
-unit testing framework, and since bitcoin already uses boost, it makes
-sense to simply use this framework rather than require developers to
-configure some other framework (we want as few impediments to creating
-unit tests as possible).
+### Adding test cases
-The build system is setup to compile an executable called `test_bitcoin`
-that runs all of the unit tests. The main source file is called
-setup_common.cpp. To add a new unit test file to our test suite you need
+To add a new unit test file to our test suite you need
to add the file to `src/Makefile.test.include`. The pattern is to create
one test file for each class or source file for which you want to create
-unit tests. The file naming convention is `<source_filename>_tests.cpp`
+unit tests. The file naming convention is `<source_filename>_tests.cpp`
and such files should wrap their tests in a test suite
called `<source_filename>_tests`. For an example of this pattern,
-examine `uint256_tests.cpp`.
+see `uint256_tests.cpp`.
+
+### Logging and debugging in unit tests
+
+To write to logs from unit tests you need to use specific message methods
+provided by Boost. The simplest is `BOOST_TEST_MESSAGE`.
+
+For debugging you can launch the test_bitcoin executable with `gdb`or `lldb` and
+start debugging, just like you would with bitcoind:
+
+```bash
+gdb src/test/test_bitcoin
+```
diff --git a/src/test/streams_tests.cpp b/src/test/streams_tests.cpp
index b812cef801..638819d564 100644
--- a/src/test/streams_tests.cpp
+++ b/src/test/streams_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 <random.h>
#include <streams.h>
#include <test/setup_common.h>
@@ -202,4 +203,247 @@ BOOST_AUTO_TEST_CASE(streams_serializedata_xor)
std::string(ds.begin(), ds.end()));
}
+BOOST_AUTO_TEST_CASE(streams_buffered_file)
+{
+ FILE* file = fsbridge::fopen("streams_test_tmp", "w+b");
+ // The value at each offset is the offset.
+ for (uint8_t j = 0; j < 40; ++j) {
+ fwrite(&j, 1, 1, file);
+ }
+ rewind(file);
+
+ // The buffer size (second arg) must be greater than the rewind
+ // amount (third arg).
+ try {
+ CBufferedFile bfbad(file, 25, 25, 222, 333);
+ BOOST_CHECK(false);
+ } catch (const std::exception& e) {
+ BOOST_CHECK(strstr(e.what(),
+ "Rewind limit must be less than buffer size") != nullptr);
+ }
+
+ // The buffer is 25 bytes, allow rewinding 10 bytes.
+ CBufferedFile bf(file, 25, 10, 222, 333);
+ BOOST_CHECK(!bf.eof());
+
+ // These two members have no functional effect.
+ BOOST_CHECK_EQUAL(bf.GetType(), 222);
+ BOOST_CHECK_EQUAL(bf.GetVersion(), 333);
+
+ uint8_t i;
+ bf >> i;
+ BOOST_CHECK_EQUAL(i, 0);
+ bf >> i;
+ BOOST_CHECK_EQUAL(i, 1);
+
+ // After reading bytes 0 and 1, we're positioned at 2.
+ BOOST_CHECK_EQUAL(bf.GetPos(), 2);
+
+ // Rewind to offset 0, ok (within the 10 byte window).
+ BOOST_CHECK(bf.SetPos(0));
+ bf >> i;
+ BOOST_CHECK_EQUAL(i, 0);
+
+ // We can go forward to where we've been, but beyond may fail.
+ BOOST_CHECK(bf.SetPos(2));
+ bf >> i;
+ BOOST_CHECK_EQUAL(i, 2);
+
+ // If you know the maximum number of bytes that should be
+ // read to deserialize the variable, you can limit the read
+ // extent. The current file offset is 3, so the following
+ // SetLimit() allows zero bytes to be read.
+ BOOST_CHECK(bf.SetLimit(3));
+ try {
+ bf >> i;
+ BOOST_CHECK(false);
+ } catch (const std::exception& e) {
+ BOOST_CHECK(strstr(e.what(),
+ "Read attempted past buffer limit") != nullptr);
+ }
+ // The default argument removes the limit completely.
+ BOOST_CHECK(bf.SetLimit());
+ // The read position should still be at 3 (no change).
+ BOOST_CHECK_EQUAL(bf.GetPos(), 3);
+
+ // Read from current offset, 3, forward until position 10.
+ for (uint8_t j = 3; j < 10; ++j) {
+ bf >> i;
+ BOOST_CHECK_EQUAL(i, j);
+ }
+ BOOST_CHECK_EQUAL(bf.GetPos(), 10);
+
+ // We're guaranteed (just barely) to be able to rewind to zero.
+ BOOST_CHECK(bf.SetPos(0));
+ BOOST_CHECK_EQUAL(bf.GetPos(), 0);
+ bf >> i;
+ BOOST_CHECK_EQUAL(i, 0);
+
+ // We can set the position forward again up to the farthest
+ // into the stream we've been, but no farther. (Attempting
+ // to go farther may succeed, but it's not guaranteed.)
+ BOOST_CHECK(bf.SetPos(10));
+ bf >> i;
+ BOOST_CHECK_EQUAL(i, 10);
+ BOOST_CHECK_EQUAL(bf.GetPos(), 11);
+
+ // Now it's only guaranteed that we can rewind to offset 1
+ // (current read position, 11, minus rewind amount, 10).
+ BOOST_CHECK(bf.SetPos(1));
+ BOOST_CHECK_EQUAL(bf.GetPos(), 1);
+ bf >> i;
+ BOOST_CHECK_EQUAL(i, 1);
+
+ // We can stream into large variables, even larger than
+ // the buffer size.
+ BOOST_CHECK(bf.SetPos(11));
+ {
+ uint8_t a[40 - 11];
+ bf >> a;
+ for (uint8_t j = 0; j < sizeof(a); ++j) {
+ BOOST_CHECK_EQUAL(a[j], 11 + j);
+ }
+ }
+ BOOST_CHECK_EQUAL(bf.GetPos(), 40);
+
+ // We've read the entire file, the next read should throw.
+ try {
+ bf >> i;
+ BOOST_CHECK(false);
+ } catch (const std::exception& e) {
+ BOOST_CHECK(strstr(e.what(),
+ "CBufferedFile::Fill: end of file") != nullptr);
+ }
+ // Attempting to read beyond the end sets the EOF indicator.
+ BOOST_CHECK(bf.eof());
+
+ // Still at offset 40, we can go back 10, to 30.
+ BOOST_CHECK_EQUAL(bf.GetPos(), 40);
+ BOOST_CHECK(bf.SetPos(30));
+ bf >> i;
+ BOOST_CHECK_EQUAL(i, 30);
+ BOOST_CHECK_EQUAL(bf.GetPos(), 31);
+
+ // We're too far to rewind to position zero.
+ BOOST_CHECK(!bf.SetPos(0));
+ // But we should now be positioned at least as far back as allowed
+ // by the rewind window (relative to our farthest read position, 40).
+ BOOST_CHECK(bf.GetPos() <= 30);
+
+ // We can explicitly close the file, or the destructor will do it.
+ bf.fclose();
+
+ fs::remove("streams_test_tmp");
+}
+
+BOOST_AUTO_TEST_CASE(streams_buffered_file_rand)
+{
+ // Make this test deterministic.
+ SeedInsecureRand(true);
+
+ for (int rep = 0; rep < 50; ++rep) {
+ FILE* file = fsbridge::fopen("streams_test_tmp", "w+b");
+ size_t fileSize = InsecureRandRange(256);
+ for (uint8_t i = 0; i < fileSize; ++i) {
+ fwrite(&i, 1, 1, file);
+ }
+ rewind(file);
+
+ size_t bufSize = InsecureRandRange(300) + 1;
+ size_t rewindSize = InsecureRandRange(bufSize);
+ CBufferedFile bf(file, bufSize, rewindSize, 222, 333);
+ size_t currentPos = 0;
+ size_t maxPos = 0;
+ for (int step = 0; step < 100; ++step) {
+ if (currentPos >= fileSize)
+ break;
+
+ // We haven't read to the end of the file yet.
+ BOOST_CHECK(!bf.eof());
+ BOOST_CHECK_EQUAL(bf.GetPos(), currentPos);
+
+ // Pretend the file consists of a series of objects of varying
+ // sizes; the boundaries of the objects can interact arbitrarily
+ // with the CBufferFile's internal buffer. These first three
+ // cases simulate objects of various sizes (1, 2, 5 bytes).
+ switch (InsecureRandRange(5)) {
+ case 0: {
+ uint8_t a[1];
+ if (currentPos + 1 > fileSize)
+ continue;
+ bf.SetLimit(currentPos + 1);
+ bf >> a;
+ for (uint8_t i = 0; i < 1; ++i) {
+ BOOST_CHECK_EQUAL(a[i], currentPos);
+ currentPos++;
+ }
+ break;
+ }
+ case 1: {
+ uint8_t a[2];
+ if (currentPos + 2 > fileSize)
+ continue;
+ bf.SetLimit(currentPos + 2);
+ bf >> a;
+ for (uint8_t i = 0; i < 2; ++i) {
+ BOOST_CHECK_EQUAL(a[i], currentPos);
+ currentPos++;
+ }
+ break;
+ }
+ case 2: {
+ uint8_t a[5];
+ if (currentPos + 5 > fileSize)
+ continue;
+ bf.SetLimit(currentPos + 5);
+ bf >> a;
+ for (uint8_t i = 0; i < 5; ++i) {
+ BOOST_CHECK_EQUAL(a[i], currentPos);
+ currentPos++;
+ }
+ break;
+ }
+ case 3: {
+ // Find a byte value (that is at or ahead of the current position).
+ size_t find = currentPos + InsecureRandRange(8);
+ if (find >= fileSize)
+ find = fileSize - 1;
+ bf.FindByte(static_cast<char>(find));
+ // The value at each offset is the offset.
+ BOOST_CHECK_EQUAL(bf.GetPos(), find);
+ currentPos = find;
+
+ bf.SetLimit(currentPos + 1);
+ uint8_t i;
+ bf >> i;
+ BOOST_CHECK_EQUAL(i, currentPos);
+ currentPos++;
+ break;
+ }
+ case 4: {
+ size_t requestPos = InsecureRandRange(maxPos + 4);
+ bool okay = bf.SetPos(requestPos);
+ // The new position may differ from the requested position
+ // because we may not be able to rewind beyond the rewind
+ // window, and we may not be able to move forward beyond the
+ // farthest position we've reached so far.
+ currentPos = bf.GetPos();
+ BOOST_CHECK_EQUAL(okay, currentPos == requestPos);
+ // Check that we can position within the rewind window.
+ if (requestPos <= maxPos &&
+ maxPos > rewindSize &&
+ requestPos >= maxPos - rewindSize) {
+ // We requested a position within the rewind window.
+ BOOST_CHECK(okay);
+ }
+ break;
+ }
+ }
+ if (maxPos < currentPos)
+ maxPos = currentPos;
+ }
+ }
+ fs::remove("streams_test_tmp");
+}
+
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/validation.cpp b/src/validation.cpp
index 4caee52424..1faaa411c4 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -1821,7 +1821,8 @@ public:
bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const override
{
- return ((pindex->nVersion & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS) &&
+ return pindex->nHeight >= params.MinBIP9WarningHeight &&
+ ((pindex->nVersion & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS) &&
((pindex->nVersion >> bit) & 1) != 0 &&
((ComputeBlockVersion(pindex->pprev, params) >> bit) & 1) == 0;
}
@@ -3280,9 +3281,7 @@ bool IsWitnessEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& pa
return (height >= params.SegwitHeight);
}
-// Compute at which vout of the block's coinbase transaction the witness
-// commitment occurs, or -1 if not found.
-static int GetWitnessCommitmentIndex(const CBlock& block)
+int GetWitnessCommitmentIndex(const CBlock& block)
{
int commitpos = -1;
if (!block.vtx.empty()) {
diff --git a/src/validation.h b/src/validation.h
index 615b83f028..96d249b6d3 100644
--- a/src/validation.h
+++ b/src/validation.h
@@ -384,6 +384,9 @@ bool IsWitnessEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& pa
/** When there are blocks in the active chain with missing data, rewind the chainstate and remove them from the block index */
bool RewindBlockIndex(const CChainParams& params) LOCKS_EXCLUDED(cs_main);
+/** Compute at which vout of the block's coinbase transaction the witness commitment occurs, or -1 if not found */
+int GetWitnessCommitmentIndex(const CBlock& block);
+
/** Update uncommitted block structures (currently: only the witness reserved value). This is safe for submitted blocks. */
void UpdateUncommittedBlockStructures(CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams);
diff --git a/test/README.md b/test/README.md
index 8f08b7afe4..26fd525064 100644
--- a/test/README.md
+++ b/test/README.md
@@ -136,8 +136,10 @@ killall bitcoind
##### Test logging
-The tests contain logging at different levels (debug, info, warning, etc). By
-default:
+The tests contain logging at five different levels (DEBUG, INFO, WARNING, ERROR
+and CRITICAL). From within your functional tests you can log to these different
+levels using the logger included in the test_framework, e.g.
+`self.log.debug(object)`. By default:
- when run through the test_runner harness, *all* logs are written to
`test_framework.log` and no logs are output to the console.
@@ -182,18 +184,32 @@ call methods that interact with the bitcoind nodes-under-test.
If further introspection of the bitcoind instances themselves becomes
necessary, this can be accomplished by first setting a pdb breakpoint
at an appropriate location, running the test to that point, then using
-`gdb` to attach to the process and debug.
+`gdb` (or `lldb` on macOS) to attach to the process and debug.
-For instance, to attach to `self.node[1]` during a run:
+For instance, to attach to `self.node[1]` during a run you can get
+the pid of the node within `pdb`.
+
+```
+(pdb) self.node[1].process.pid
+```
+
+Alternatively, you can find the pid by inspecting the temp folder for the specific test
+you are running. The path to that folder is printed at the beginning of every
+test run:
```bash
2017-06-27 14:13:56.686000 TestFramework (INFO): Initializing test directory /tmp/user/1000/testo9vsdjo3
```
-use the directory path to get the pid from the pid file:
+Use the path to find the pid file in the temp folder:
```bash
cat /tmp/user/1000/testo9vsdjo3/node1/regtest/bitcoind.pid
+```
+
+Then you can use the pid to start `gdb`:
+
+```bash
gdb /home/example/bitcoind <pid>
```
diff --git a/test/functional/README.md b/test/functional/README.md
index 5e3009e6af..197c2afbe4 100644
--- a/test/functional/README.md
+++ b/test/functional/README.md
@@ -116,7 +116,7 @@ Basic code to support P2P connectivity to a bitcoind.
Utilities for manipulating transaction scripts (originally from python-bitcoinlib)
#### [test_framework/key.py](test_framework/key.py)
-Wrapper around OpenSSL EC_Key (originally from python-bitcoinlib)
+Test-only secp256k1 elliptic curve implementation
#### [test_framework/bignum.py](test_framework/bignum.py)
Helpers for script.py
diff --git a/test/functional/feature_segwit.py b/test/functional/feature_segwit.py
index d2826dd1b7..c69c7f90e8 100755
--- a/test/functional/feature_segwit.py
+++ b/test/functional/feature_segwit.py
@@ -257,7 +257,7 @@ class SegWitTest(BitcoinTestFramework):
tx.vin.append(CTxIn(COutPoint(int(txid2, 16), 0), b""))
tx.vout.append(CTxOut(int(49.95 * COIN), CScript([OP_TRUE, OP_DROP] * 15 + [OP_TRUE]))) # Huge fee
tx.calc_sha256()
- txid3 = self.nodes[0].sendrawtransaction(ToHex(tx), 0)
+ txid3 = self.nodes[0].sendrawtransaction(hexstring=ToHex(tx), maxfeerate=0)
assert tx.wit.is_null()
assert txid3 in self.nodes[0].getrawmempool()
@@ -566,7 +566,7 @@ class SegWitTest(BitcoinTestFramework):
tx.vout.append(CTxOut(10000000, i))
tx.rehash()
signresults = self.nodes[0].signrawtransactionwithwallet(tx.serialize_without_witness().hex())['hex']
- txid = self.nodes[0].sendrawtransaction(signresults, 0)
+ txid = self.nodes[0].sendrawtransaction(hexstring=signresults, maxfeerate=0)
txs_mined[txid] = self.nodes[0].generate(1)[0]
self.sync_blocks()
watchcount = 0
@@ -618,7 +618,7 @@ class SegWitTest(BitcoinTestFramework):
tx.vout.append(CTxOut(0, CScript()))
tx.rehash()
signresults = self.nodes[0].signrawtransactionwithwallet(tx.serialize_without_witness().hex())['hex']
- self.nodes[0].sendrawtransaction(signresults, 0)
+ self.nodes[0].sendrawtransaction(hexstring=signresults, maxfeerate=0)
self.nodes[0].generate(1)
self.sync_blocks()
diff --git a/test/functional/rpc_blockchain.py b/test/functional/rpc_blockchain.py
index 266a0d6cd2..278ce6d911 100755
--- a/test/functional/rpc_blockchain.py
+++ b/test/functional/rpc_blockchain.py
@@ -134,7 +134,7 @@ class BlockchainTest(BitcoinTestFramework):
'bip9': {
'status': 'started',
'bit': 28,
- 'startTime': 0,
+ 'start_time': 0,
'timeout': 0x7fffffffffffffff, # testdummy does not have a timeout so is set to the max int64 value
'since': 144,
'statistics': {
diff --git a/test/functional/rpc_rawtransaction.py b/test/functional/rpc_rawtransaction.py
index eb98334988..ca0d47a5f8 100755
--- a/test/functional/rpc_rawtransaction.py
+++ b/test/functional/rpc_rawtransaction.py
@@ -438,48 +438,50 @@ class RawTransactionsTest(BitcoinTestFramework):
self.log.info('sendrawtransaction/testmempoolaccept with maxfeerate')
- # Test a transaction with small fee
+ # Test a transaction with a small fee.
txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1.0)
rawTx = self.nodes[0].getrawtransaction(txId, True)
vout = next(o for o in rawTx['vout'] if o['value'] == Decimal('1.00000000'))
self.sync_all()
inputs = [{ "txid" : txId, "vout" : vout['n'] }]
- outputs = { self.nodes[0].getnewaddress() : Decimal("0.999990000") } # 10000 sat fee
+ # Fee 10,000 satoshis, (1 - (10000 sat * 0.00000001 BTC/sat)) = 0.9999
+ outputs = { self.nodes[0].getnewaddress() : Decimal("0.99990000") }
rawTx = self.nodes[2].createrawtransaction(inputs, outputs)
rawTxSigned = self.nodes[2].signrawtransactionwithwallet(rawTx)
assert_equal(rawTxSigned['complete'], True)
- # 10000 sat fee, ~100 b transaction, fee rate should land around 100 sat/b = 0.00100000 BTC/kB
+ # Fee 10,000 satoshis, ~100 b transaction, fee rate should land around 100 sat/byte = 0.00100000 BTC/kB
# Thus, testmempoolaccept should reject
testres = self.nodes[2].testmempoolaccept([rawTxSigned['hex']], 0.00001000)[0]
assert_equal(testres['allowed'], False)
assert_equal(testres['reject-reason'], '256: absurdly-high-fee')
# and sendrawtransaction should throw
assert_raises_rpc_error(-26, "absurdly-high-fee", self.nodes[2].sendrawtransaction, rawTxSigned['hex'], 0.00001000)
- # And below calls should both succeed
+ # and the following calls should both succeed
testres = self.nodes[2].testmempoolaccept(rawtxs=[rawTxSigned['hex']])[0]
assert_equal(testres['allowed'], True)
self.nodes[2].sendrawtransaction(hexstring=rawTxSigned['hex'])
- # Test a transaction with large fee
+ # Test a transaction with a large fee.
txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1.0)
rawTx = self.nodes[0].getrawtransaction(txId, True)
vout = next(o for o in rawTx['vout'] if o['value'] == Decimal('1.00000000'))
self.sync_all()
inputs = [{ "txid" : txId, "vout" : vout['n'] }]
- outputs = { self.nodes[0].getnewaddress() : Decimal("0.98000000") } # 2000000 sat fee
+ # Fee 2,000,000 satoshis, (1 - (2000000 sat * 0.00000001 BTC/sat)) = 0.98
+ outputs = { self.nodes[0].getnewaddress() : Decimal("0.98000000") }
rawTx = self.nodes[2].createrawtransaction(inputs, outputs)
rawTxSigned = self.nodes[2].signrawtransactionwithwallet(rawTx)
assert_equal(rawTxSigned['complete'], True)
- # 2000000 sat fee, ~100 b transaction, fee rate should land around 20000 sat/b = 0.20000000 BTC/kB
+ # Fee 2,000,000 satoshis, ~100 b transaction, fee rate should land around 20,000 sat/byte = 0.20000000 BTC/kB
# Thus, testmempoolaccept should reject
testres = self.nodes[2].testmempoolaccept([rawTxSigned['hex']])[0]
assert_equal(testres['allowed'], False)
assert_equal(testres['reject-reason'], '256: absurdly-high-fee')
# and sendrawtransaction should throw
assert_raises_rpc_error(-26, "absurdly-high-fee", self.nodes[2].sendrawtransaction, rawTxSigned['hex'])
- # And below calls should both succeed
+ # and the following calls should both succeed
testres = self.nodes[2].testmempoolaccept(rawtxs=[rawTxSigned['hex']], maxfeerate='0.20000000')[0]
assert_equal(testres['allowed'], True)
self.nodes[2].sendrawtransaction(hexstring=rawTxSigned['hex'], maxfeerate='0.20000000')
diff --git a/test/functional/test_framework/util.py b/test/functional/test_framework/util.py
index 1c254b6755..598e87558b 100644
--- a/test/functional/test_framework/util.py
+++ b/test/functional/test_framework/util.py
@@ -7,13 +7,13 @@
from base64 import b64encode
from binascii import unhexlify
from decimal import Decimal, ROUND_DOWN
+from subprocess import CalledProcessError
import inspect
import json
import logging
import os
import random
import re
-from subprocess import CalledProcessError
import time
from . import coverage
@@ -235,10 +235,11 @@ def wait_until(predicate, *, attempts=float('inf'), timeout=float('inf'), lock=N
# The maximum number of nodes a single test can spawn
MAX_NODES = 12
# Don't assign rpc or p2p ports lower than this
-PORT_MIN = 11000
+PORT_MIN = int(os.getenv('TEST_RUNNER_PORT_MIN', default=11000))
# The number of ports to "reserve" for p2p and rpc, each
PORT_RANGE = 5000
+
class PortSeed:
# Must be initialized with a unique integer for each process
n = None
diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py
index 5b1c672a48..96ea5c9c35 100755
--- a/test/functional/wallet_basic.py
+++ b/test/functional/wallet_basic.py
@@ -169,8 +169,8 @@ class WalletTest(BitcoinTestFramework):
txns_to_send.append(self.nodes[0].signrawtransactionwithwallet(raw_tx))
# Have node 1 (miner) send the transactions
- self.nodes[1].sendrawtransaction(txns_to_send[0]["hex"], 0)
- self.nodes[1].sendrawtransaction(txns_to_send[1]["hex"], 0)
+ self.nodes[1].sendrawtransaction(hexstring=txns_to_send[0]["hex"], maxfeerate=0)
+ self.nodes[1].sendrawtransaction(hexstring=txns_to_send[1]["hex"], maxfeerate=0)
# Have node1 mine a block to confirm transactions:
self.nodes[1].generate(1)
@@ -433,7 +433,7 @@ class WalletTest(BitcoinTestFramework):
# Split into two chains
rawtx = self.nodes[0].createrawtransaction([{"txid": singletxid, "vout": 0}], {chain_addrs[0]: node0_balance / 2 - Decimal('0.01'), chain_addrs[1]: node0_balance / 2 - Decimal('0.01')})
signedtx = self.nodes[0].signrawtransactionwithwallet(rawtx)
- singletxid = self.nodes[0].sendrawtransaction(signedtx["hex"], 0)
+ singletxid = self.nodes[0].sendrawtransaction(hexstring=signedtx["hex"], maxfeerate=0)
self.nodes[0].generate(1)
# Make a long chain of unconfirmed payments without hitting mempool limit
diff --git a/test/lint/lint-python-dead-code-whitelist b/test/lint/lint-python-dead-code-whitelist
deleted file mode 100644
index 33bb7b44fa..0000000000
--- a/test/lint/lint-python-dead-code-whitelist
+++ /dev/null
@@ -1,46 +0,0 @@
-BadInputOutpointIndex # unused class (test/functional/data/invalid_txs.py)
-_.carbon_path # unused attribute (contrib/macdeploy/custom_dsstore.py)
-connection_lost # unused function (test/functional/test_framework/mininode.py)
-connection_made # unused function (test/functional/test_framework/mininode.py)
-_.converter # unused attribute (test/functional/test_framework/test_framework.py)
-_.daemon # unused attribute (test/functional/test_framework/socks5.py)
-data_received # unused function (test/functional/test_framework/mininode.py)
-DuplicateInput # unused class (test/functional/data/invalid_txs.py)
-DisabledOpcodeTemplates # unused class (test/functional/data/invalid_txs.py)
-_.filename # unused attribute (contrib/macdeploy/custom_dsstore.py)
-InvalidOPIFConstruction # unused class (test/functional/data/invalid_txs.py)
-_.is_compressed # unused property (test/functional/test_framework/key.py)
-legacy # unused variable (test/functional/test_framework/address.py)
-msg_generic # unused class (test/functional/test_framework/messages.py)
-NonexistentInput # unused class (test/functional/data/invalid_txs.py)
-on_addr # unused function (test/functional/test_framework/mininode.py)
-on_blocktxn # unused function (test/functional/test_framework/mininode.py)
-on_block # unused function (test/functional/test_framework/mininode.py)
-on_cmpctblock # unused function (test/functional/test_framework/mininode.py)
-on_feefilter # unused function (test/functional/test_framework/mininode.py)
-on_getaddr # unused function (test/functional/test_framework/mininode.py)
-on_getblocks # unused function (test/functional/test_framework/mininode.py)
-on_getblocktxn # unused function (test/functional/test_framework/mininode.py)
-on_getdata # unused function (test/functional/test_framework/mininode.py)
-on_getheaders # unused function (test/functional/test_framework/mininode.py)
-on_headers # unused function (test/functional/test_framework/mininode.py)
-on_inv # unused function (test/functional/test_framework/mininode.py)
-on_mempool # unused function (test/functional/test_framework/mininode.py)
-on_notfound # unused function (test/functional/test_framework/mininode.py)
-on_ping # unused function (test/functional/test_framework/mininode.py)
-on_pong # unused function (test/functional/test_framework/mininode.py)
-on_reject # unused function (test/functional/test_framework/mininode.py)
-on_sendcmpct # unused function (test/functional/test_framework/mininode.py)
-on_sendheaders # unused function (test/functional/test_framework/mininode.py)
-on_tx # unused function (test/functional/test_framework/mininode.py)
-on_verack # unused function (test/functional/test_framework/mininode.py)
-on_version # unused function (test/functional/test_framework/mininode.py)
-_.optionxform # unused attribute (test/util/bitcoin-util-test.py)
-OutputMissing # unused class (test/functional/data/invalid_txs.py)
-_.posix_path # unused attribute (contrib/macdeploy/custom_dsstore.py)
-profile_with_perf # unused function (test/functional/test_framework/test_node.py)
-SizeTooSmall # unused class (test/functional/data/invalid_txs.py)
-SpendNegative # unused class (test/functional/data/invalid_txs.py)
-SpendTooMuch # unused class (test/functional/data/invalid_txs.py)
-TooManySigops # unused class (test/functional/data/invalid_txs.py)
-verify_ecdsa # unused function (test/functional/test_framework/key.py)
diff --git a/test/lint/lint-python-dead-code.sh b/test/lint/lint-python-dead-code.sh
deleted file mode 100755
index af37d393e8..0000000000
--- a/test/lint/lint-python-dead-code.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-#
-# Find dead Python code.
-
-export LC_ALL=C
-
-if ! command -v vulture > /dev/null; then
- echo "Skipping Python dead code linting since vulture is not installed. Install by running \"pip3 install vulture\""
- exit 0
-fi
-
-VULTURE_SUPPRESSIONS=$(dirname "${BASH_SOURCE[0]}")/lint-python-dead-code-whitelist
-if ! vulture \
- --min-confidence 60 \
- $(git rev-parse --show-toplevel) \
- "${VULTURE_SUPPRESSIONS}"; then
- echo "False positives? Suppressions can be added to ${VULTURE_SUPPRESSIONS}"
- exit 1
-fi