From 2b4e896f60f848bc9041469dd75385b88bd1594f Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 14 Jun 2016 09:07:40 +0200 Subject: [PATCH 01/47] Merge #8197: [trivial] Ignore split-debug.sh 01a9904 [trivial] Ignore split-debug.sh (fanquake) --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 80fa9c28fd6a..fd2d88159663 100644 --- a/.gitignore +++ b/.gitignore @@ -124,6 +124,7 @@ share/BitcoindComparisonTool.jar /doc/doxygen/ libdashconsensus.pc +contrib/devtools/split-debug.sh src/qt/dash-qt.bash qa/pull-tester/tests-config.sh From 61a667fc492874c28faf5b577a62e1dba47b5938 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 14 Jun 2016 09:13:07 +0200 Subject: [PATCH 02/47] Merge #8194: [gitian] set correct PATH for wrappers fa61756 [gitian] set correct PATH for wrappers (MarcoFalke) --- contrib/gitian-descriptors/gitian-linux.yml | 6 ++++-- contrib/gitian-descriptors/gitian-osx.yml | 6 ++++-- contrib/gitian-descriptors/gitian-win.yml | 6 ++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index ce4baee31ead..ff11505426de 100755 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -84,11 +84,11 @@ script: | done } - export PATH=${WRAP_DIR}:${PATH} - # Faketime for depends so intermediate results are comparable + export PATH_orig=${PATH} create_global_faketime_wrappers "2000-01-01 12:00:00" create_per-host_faketime_wrappers "2000-01-01 12:00:00" + export PATH=${WRAP_DIR}:${PATH} cd dash BASEPREFIX=`pwd`/depends @@ -98,8 +98,10 @@ script: | done # Faketime for binaries + export PATH=${PATH_orig} create_global_faketime_wrappers "${REFERENCE_DATETIME}" create_per-host_faketime_wrappers "${REFERENCE_DATETIME}" + export PATH=${WRAP_DIR}:${PATH} # Create the release tarball using (arbitrarily) the first host ./autogen.sh diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index 29b8772c519b..64007a7b6c39 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -77,11 +77,11 @@ script: | done } - export PATH=${WRAP_DIR}:${PATH} - # Faketime for depends so intermediate results are comparable + export PATH_orig=${PATH} create_global_faketime_wrappers "2000-01-01 12:00:00" create_per-host_faketime_wrappers "2000-01-01 12:00:00" + export PATH=${WRAP_DIR}:${PATH} cd dash BASEPREFIX=`pwd`/depends @@ -95,8 +95,10 @@ script: | done # Faketime for binaries + export PATH=${PATH_orig} create_global_faketime_wrappers "${REFERENCE_DATETIME}" create_per-host_faketime_wrappers "${REFERENCE_DATETIME}" + export PATH=${WRAP_DIR}:${PATH} # Create the release tarball using (arbitrarily) the first host ./autogen.sh diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index 299de65a8978..d91fbf9acb6e 100755 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -94,12 +94,12 @@ script: | done } - export PATH=${WRAP_DIR}:${PATH} - # Faketime for depends so intermediate results are comparable + export PATH_orig=${PATH} create_global_faketime_wrappers "2000-01-01 12:00:00" create_per-host_faketime_wrappers "2000-01-01 12:00:00" create_per-host_linker_wrapper "2000-01-01 12:00:00" + export PATH=${WRAP_DIR}:${PATH} cd dash BASEPREFIX=`pwd`/depends @@ -109,9 +109,11 @@ script: | done # Faketime for binaries + export PATH=${PATH_orig} create_global_faketime_wrappers "${REFERENCE_DATETIME}" create_per-host_faketime_wrappers "${REFERENCE_DATETIME}" create_per-host_linker_wrapper "${REFERENCE_DATETIME}" + export PATH=${WRAP_DIR}:${PATH} # Create the release tarball using (arbitrarily) the first host ./autogen.sh From 62852538e1944c2510944c64e7a87e324560b26b Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 14 Jun 2016 11:48:20 +0200 Subject: [PATCH 03/47] Merge #8198: [trivial] Sync ax_pthread with upstream draft4 0e209f9 [trivial] Sync ax_pthread with upstream draft (fanquake) --- build-aux/m4/ax_pthread.m4 | 550 ++++++++++++++++++------------------- 1 file changed, 275 insertions(+), 275 deletions(-) diff --git a/build-aux/m4/ax_pthread.m4 b/build-aux/m4/ax_pthread.m4 index d218d1af7381..4c4051ea376f 100644 --- a/build-aux/m4/ax_pthread.m4 +++ b/build-aux/m4/ax_pthread.m4 @@ -82,7 +82,7 @@ # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. -#serial 22 +#serial 23 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) AC_DEFUN([AX_PTHREAD], [ @@ -100,22 +100,22 @@ ax_pthread_ok=no # etcetera environment variables, and if threads linking works using # them: if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then - ax_pthread_save_CC="$CC" - ax_pthread_save_CFLAGS="$CFLAGS" - ax_pthread_save_LIBS="$LIBS" - AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - LIBS="$PTHREAD_LIBS $LIBS" - AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) - AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes]) - AC_MSG_RESULT([$ax_pthread_ok]) - if test "x$ax_pthread_ok" = "xno"; then - PTHREAD_LIBS="" - PTHREAD_CFLAGS="" - fi - CC="$ax_pthread_save_CC" - CFLAGS="$ax_pthread_save_CFLAGS" - LIBS="$ax_pthread_save_LIBS" + ax_pthread_save_CC="$CC" + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) + AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes]) + AC_MSG_RESULT([$ax_pthread_ok]) + if test "x$ax_pthread_ok" = "xno"; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + CC="$ax_pthread_save_CC" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" fi # We must check for the threads library under a number of different @@ -152,50 +152,50 @@ ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread -- case $host_os in - freebsd*) + freebsd*) - # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) - # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) + # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) + # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) - ax_pthread_flags="-kthread lthread $ax_pthread_flags" - ;; + ax_pthread_flags="-kthread lthread $ax_pthread_flags" + ;; - hpux*) + hpux*) - # From the cc(1) man page: "[-mt] Sets various -D flags to enable - # multi-threading and also sets -lpthread." + # From the cc(1) man page: "[-mt] Sets various -D flags to enable + # multi-threading and also sets -lpthread." - ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" - ;; + ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" + ;; - openedition*) + openedition*) - # IBM z/OS requires a feature-test macro to be defined in order to - # enable POSIX threads at all, so give the user a hint if this is - # not set. (We don't define these ourselves, as they can affect - # other portions of the system API in unpredictable ways.) + # IBM z/OS requires a feature-test macro to be defined in order to + # enable POSIX threads at all, so give the user a hint if this is + # not set. (We don't define these ourselves, as they can affect + # other portions of the system API in unpredictable ways.) - AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING], - [ -# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) - AX_PTHREAD_ZOS_MISSING -# endif - ], - [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])]) - ;; + AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING], + [ +# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) + AX_PTHREAD_ZOS_MISSING +# endif + ], + [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])]) + ;; - solaris*) + solaris*) - # On Solaris (at least, for some versions), libc contains stubbed - # (non-functional) versions of the pthreads routines, so link-based - # tests will erroneously succeed. (N.B.: The stubs are missing - # pthread_cleanup_push, or rather a function called by this macro, - # so we could check for that, but who knows whether they'll stub - # that too in a future libc.) So we'll check first for the - # standard Solaris way of linking pthreads (-mt -lpthread). + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (N.B.: The stubs are missing + # pthread_cleanup_push, or rather a function called by this macro, + # so we could check for that, but who knows whether they'll stub + # that too in a future libc.) So we'll check first for the + # standard Solaris way of linking pthreads (-mt -lpthread). - ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags" - ;; + ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags" + ;; esac # GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) @@ -208,17 +208,17 @@ AS_IF([test "x$GCC" = "xyes"], # correctly enabled case $host_os in - darwin* | hpux* | linux* | osf* | solaris*) - ax_pthread_check_macro="_REENTRANT" - ;; + darwin* | hpux* | linux* | osf* | solaris*) + ax_pthread_check_macro="_REENTRANT" + ;; - aix* | freebsd*) - ax_pthread_check_macro="_THREAD_SAFE" - ;; + aix*) + ax_pthread_check_macro="_THREAD_SAFE" + ;; - *) - ax_pthread_check_macro="--" - ;; + *) + ax_pthread_check_macro="--" + ;; esac AS_IF([test "x$ax_pthread_check_macro" = "x--"], [ax_pthread_check_cond=0], @@ -231,13 +231,13 @@ AC_CACHE_CHECK([whether $CC is Clang], [ax_cv_PTHREAD_CLANG=no # Note that Autoconf sets GCC=yes for Clang as well as GCC if test "x$GCC" = "xyes"; then - AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], - [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ -# if defined(__clang__) && defined(__llvm__) - AX_PTHREAD_CC_IS_CLANG -# endif - ], - [ax_cv_PTHREAD_CLANG=yes]) + AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], + [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ +# if defined(__clang__) && defined(__llvm__) + AX_PTHREAD_CC_IS_CLANG +# endif + ], + [ax_cv_PTHREAD_CLANG=yes]) fi ]) ax_pthread_clang="$ax_cv_PTHREAD_CLANG" @@ -249,222 +249,222 @@ ax_pthread_clang_warning=no if test "x$ax_pthread_clang" = "xyes"; then - # Clang takes -pthread; it has never supported any other flag - - # (Note 1: This will need to be revisited if a system that Clang - # supports has POSIX threads in a separate library. This tends not - # to be the way of modern systems, but it's conceivable.) - - # (Note 2: On some systems, notably Darwin, -pthread is not needed - # to get POSIX threads support; the API is always present and - # active. We could reasonably leave PTHREAD_CFLAGS empty. But - # -pthread does define _REENTRANT, and while the Darwin headers - # ignore this macro, third-party headers might not.) - - PTHREAD_CFLAGS="-pthread" - PTHREAD_LIBS= - - ax_pthread_ok=yes - - # However, older versions of Clang make a point of warning the user - # that, in an invocation where only linking and no compilation is - # taking place, the -pthread option has no effect ("argument unused - # during compilation"). They expect -pthread to be passed in only - # when source code is being compiled. - # - # Problem is, this is at odds with the way Automake and most other - # C build frameworks function, which is that the same flags used in - # compilation (CFLAGS) are also used in linking. Many systems - # supported by AX_PTHREAD require exactly this for POSIX threads - # support, and in fact it is often not straightforward to specify a - # flag that is used only in the compilation phase and not in - # linking. Such a scenario is extremely rare in practice. - # - # Even though use of the -pthread flag in linking would only print - # a warning, this can be a nuisance for well-run software projects - # that build with -Werror. So if the active version of Clang has - # this misfeature, we search for an option to squash it. - - AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], - [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], - [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown - # Create an alternate version of $ac_link that compiles and - # links in two steps (.c -> .o, .o -> exe) instead of one - # (.c -> exe), because the warning occurs only in the second - # step - ax_pthread_save_ac_link="$ac_link" - ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' - ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"` - ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" - ax_pthread_save_CFLAGS="$CFLAGS" - for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do - AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) - CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" - ac_link="$ax_pthread_save_ac_link" - AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], - [ac_link="$ax_pthread_2step_ac_link" - AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], - [break]) - ]) - done - ac_link="$ax_pthread_save_ac_link" - CFLAGS="$ax_pthread_save_CFLAGS" - AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) - ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" - ]) - - case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in - no | unknown) ;; - *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; - esac + # Clang takes -pthread; it has never supported any other flag + + # (Note 1: This will need to be revisited if a system that Clang + # supports has POSIX threads in a separate library. This tends not + # to be the way of modern systems, but it's conceivable.) + + # (Note 2: On some systems, notably Darwin, -pthread is not needed + # to get POSIX threads support; the API is always present and + # active. We could reasonably leave PTHREAD_CFLAGS empty. But + # -pthread does define _REENTRANT, and while the Darwin headers + # ignore this macro, third-party headers might not.) + + PTHREAD_CFLAGS="-pthread" + PTHREAD_LIBS= + + ax_pthread_ok=yes + + # However, older versions of Clang make a point of warning the user + # that, in an invocation where only linking and no compilation is + # taking place, the -pthread option has no effect ("argument unused + # during compilation"). They expect -pthread to be passed in only + # when source code is being compiled. + # + # Problem is, this is at odds with the way Automake and most other + # C build frameworks function, which is that the same flags used in + # compilation (CFLAGS) are also used in linking. Many systems + # supported by AX_PTHREAD require exactly this for POSIX threads + # support, and in fact it is often not straightforward to specify a + # flag that is used only in the compilation phase and not in + # linking. Such a scenario is extremely rare in practice. + # + # Even though use of the -pthread flag in linking would only print + # a warning, this can be a nuisance for well-run software projects + # that build with -Werror. So if the active version of Clang has + # this misfeature, we search for an option to squash it. + + AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown + # Create an alternate version of $ac_link that compiles and + # links in two steps (.c -> .o, .o -> exe) instead of one + # (.c -> exe), because the warning occurs only in the second + # step + ax_pthread_save_ac_link="$ac_link" + ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' + ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"` + ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" + ax_pthread_save_CFLAGS="$CFLAGS" + for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do + AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) + CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" + ac_link="$ax_pthread_save_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [ac_link="$ax_pthread_2step_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [break]) + ]) + done + ac_link="$ax_pthread_save_ac_link" + CFLAGS="$ax_pthread_save_CFLAGS" + AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) + ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" + ]) + + case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in + no | unknown) ;; + *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; + esac fi # $ax_pthread_clang = yes if test "x$ax_pthread_ok" = "xno"; then for ax_pthread_try_flag in $ax_pthread_flags; do - case $ax_pthread_try_flag in - none) - AC_MSG_CHECKING([whether pthreads work without any flags]) - ;; - - -mt,pthread) - AC_MSG_CHECKING([whether pthreads work with -mt -lpthread]) - PTHREAD_CFLAGS="-mt" - PTHREAD_LIBS="-lpthread" - ;; - - -*) - AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) - PTHREAD_CFLAGS="$ax_pthread_try_flag" - ;; - - pthread-config) - AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) - AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) - PTHREAD_CFLAGS="`pthread-config --cflags`" - PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" - ;; - - *) - AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) - PTHREAD_LIBS="-l$ax_pthread_try_flag" - ;; - esac - - ax_pthread_save_CFLAGS="$CFLAGS" - ax_pthread_save_LIBS="$LIBS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - LIBS="$PTHREAD_LIBS $LIBS" - - # Check for various functions. We must include pthread.h, - # since some functions may be macros. (On the Sequent, we - # need a special flag -Kthread to make this header compile.) - # We check for pthread_join because it is in -lpthread on IRIX - # while pthread_create is in libc. We check for pthread_attr_init - # due to DEC craziness with -lpthreads. We check for - # pthread_cleanup_push because it is one of the few pthread - # functions on Solaris that doesn't have a non-functional libc stub. - # We try pthread_create on general principles. - - AC_LINK_IFELSE([AC_LANG_PROGRAM([#include -# if $ax_pthread_check_cond -# error "$ax_pthread_check_macro must be defined" -# endif - static void routine(void *a) { a = 0; } - static void *start_routine(void *a) { return a; }], - [pthread_t th; pthread_attr_t attr; - pthread_create(&th, 0, start_routine, 0); - pthread_join(th, 0); - pthread_attr_init(&attr); - pthread_cleanup_push(routine, 0); - pthread_cleanup_pop(0) /* ; */])], - [ax_pthread_ok=yes], - []) - - CFLAGS="$ax_pthread_save_CFLAGS" - LIBS="$ax_pthread_save_LIBS" - - AC_MSG_RESULT([$ax_pthread_ok]) - AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) - - PTHREAD_LIBS="" - PTHREAD_CFLAGS="" + case $ax_pthread_try_flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + -mt,pthread) + AC_MSG_CHECKING([whether pthreads work with -mt -lpthread]) + PTHREAD_CFLAGS="-mt" + PTHREAD_LIBS="-lpthread" + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) + PTHREAD_CFLAGS="$ax_pthread_try_flag" + ;; + + pthread-config) + AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) + AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) + PTHREAD_LIBS="-l$ax_pthread_try_flag" + ;; + esac + + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include +# if $ax_pthread_check_cond +# error "$ax_pthread_check_macro must be defined" +# endif + static void routine(void *a) { a = 0; } + static void *start_routine(void *a) { return a; }], + [pthread_t th; pthread_attr_t attr; + pthread_create(&th, 0, start_routine, 0); + pthread_join(th, 0); + pthread_attr_init(&attr); + pthread_cleanup_push(routine, 0); + pthread_cleanup_pop(0) /* ; */])], + [ax_pthread_ok=yes], + []) + + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" + + AC_MSG_RESULT([$ax_pthread_ok]) + AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" done fi # Various other checks: if test "x$ax_pthread_ok" = "xyes"; then - ax_pthread_save_CFLAGS="$CFLAGS" - ax_pthread_save_LIBS="$LIBS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - LIBS="$PTHREAD_LIBS $LIBS" - - # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. - AC_CACHE_CHECK([for joinable pthread attribute], - [ax_cv_PTHREAD_JOINABLE_ATTR], - [ax_cv_PTHREAD_JOINABLE_ATTR=unknown - for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do - AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], - [int attr = $ax_pthread_attr; return attr /* ; */])], - [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break], - []) - done - ]) - AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ - test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ - test "x$ax_pthread_joinable_attr_defined" != "xyes"], - [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], - [$ax_cv_PTHREAD_JOINABLE_ATTR], - [Define to necessary symbol if this constant - uses a non-standard name on your system.]) - ax_pthread_joinable_attr_defined=yes - ]) - - AC_CACHE_CHECK([whether more special flags are required for pthreads], - [ax_cv_PTHREAD_SPECIAL_FLAGS], - [ax_cv_PTHREAD_SPECIAL_FLAGS=no - case $host_os in - solaris*) - ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" - ;; - esac - ]) - AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ - test "x$ax_pthread_special_flags_added" != "xyes"], - [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" - ax_pthread_special_flags_added=yes]) - - AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], - [ax_cv_PTHREAD_PRIO_INHERIT], - [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], - [[int i = PTHREAD_PRIO_INHERIT;]])], - [ax_cv_PTHREAD_PRIO_INHERIT=yes], - [ax_cv_PTHREAD_PRIO_INHERIT=no]) - ]) - AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ - test "x$ax_pthread_prio_inherit_defined" != "xyes"], - [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.]) - ax_pthread_prio_inherit_defined=yes - ]) - - CFLAGS="$ax_pthread_save_CFLAGS" - LIBS="$ax_pthread_save_LIBS" - - # More AIX lossage: compile with *_r variant - if test "x$GCC" != "xyes"; then - case $host_os in - aix*) - AS_CASE(["x/$CC"], - [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], - [#handle absolute path differently from PATH based program lookup - AS_CASE(["x$CC"], - [x/*], - [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], - [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) - ;; - esac - fi + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + AC_CACHE_CHECK([for joinable pthread attribute], + [ax_cv_PTHREAD_JOINABLE_ATTR], + [ax_cv_PTHREAD_JOINABLE_ATTR=unknown + for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], + [int attr = $ax_pthread_attr; return attr /* ; */])], + [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break], + []) + done + ]) + AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ + test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ + test "x$ax_pthread_joinable_attr_defined" != "xyes"], + [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], + [$ax_cv_PTHREAD_JOINABLE_ATTR], + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + ax_pthread_joinable_attr_defined=yes + ]) + + AC_CACHE_CHECK([whether more special flags are required for pthreads], + [ax_cv_PTHREAD_SPECIAL_FLAGS], + [ax_cv_PTHREAD_SPECIAL_FLAGS=no + case $host_os in + solaris*) + ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" + ;; + esac + ]) + AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ + test "x$ax_pthread_special_flags_added" != "xyes"], + [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" + ax_pthread_special_flags_added=yes]) + + AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], + [ax_cv_PTHREAD_PRIO_INHERIT], + [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[int i = PTHREAD_PRIO_INHERIT;]])], + [ax_cv_PTHREAD_PRIO_INHERIT=yes], + [ax_cv_PTHREAD_PRIO_INHERIT=no]) + ]) + AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ + test "x$ax_pthread_prio_inherit_defined" != "xyes"], + [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.]) + ax_pthread_prio_inherit_defined=yes + ]) + + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" + + # More AIX lossage: compile with *_r variant + if test "x$GCC" != "xyes"; then + case $host_os in + aix*) + AS_CASE(["x/$CC"], + [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], + [#handle absolute path differently from PATH based program lookup + AS_CASE(["x$CC"], + [x/*], + [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], + [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) + ;; + esac + fi fi test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" @@ -475,11 +475,11 @@ AC_SUBST([PTHREAD_CC]) # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test "x$ax_pthread_ok" = "xyes"; then - ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) - : + ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) + : else - ax_pthread_ok=no - $2 + ax_pthread_ok=no + $2 fi AC_LANG_POP ])dnl AX_PTHREAD From 96180a189687dd1bc23e79fd962444568749a0b9 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 14 Jun 2016 13:17:39 +0200 Subject: [PATCH 04/47] Merge #7636: Add bitcoin address label to request payment QR code 1c2a1ba Add address label to request payment QR Code (QT) (Francesco 'makevoid' Canessa) --- src/qt/forms/receiverequestdialog.ui | 2 +- src/qt/guiconstants.h | 2 +- src/qt/receiverequestdialog.cpp | 22 +++++++++++++++++----- src/qt/receiverequestdialog.h | 1 + 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/qt/forms/receiverequestdialog.ui b/src/qt/forms/receiverequestdialog.ui index 1e484dd9a0f5..4163f4189c5e 100644 --- a/src/qt/forms/receiverequestdialog.ui +++ b/src/qt/forms/receiverequestdialog.ui @@ -22,7 +22,7 @@ 300 - 300 + 320 diff --git a/src/qt/guiconstants.h b/src/qt/guiconstants.h index b20de4c58f25..d1d6ae3c4221 100644 --- a/src/qt/guiconstants.h +++ b/src/qt/guiconstants.h @@ -44,7 +44,7 @@ static const int TOOLTIP_WRAP_THRESHOLD = 80; static const int MAX_URI_LENGTH = 255; /* QRCodeDialog -- size of exported QR Code image */ -#define EXPORT_IMAGE_SIZE 256 +#define QR_IMAGE_SIZE 300 /* Number of frames in spinner animation */ #define SPINNER_FRAMES 36 diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp index 5163cbaf1156..be4ae56c4025 100644 --- a/src/qt/receiverequestdialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -45,7 +45,7 @@ QImage QRImageWidget::exportImage() { if(!pixmap()) return QImage(); - return pixmap()->toImage().scaled(EXPORT_IMAGE_SIZE, EXPORT_IMAGE_SIZE); + return pixmap()->toImage(); } void QRImageWidget::mousePressEvent(QMouseEvent *event) @@ -167,20 +167,32 @@ void ReceiveRequestDialog::update() ui->lblQRCode->setText(tr("Error encoding URI into QR Code.")); return; } - QImage myImage = QImage(code->width + 8, code->width + 8, QImage::Format_RGB32); - myImage.fill(0xffffff); + QImage qrImage = QImage(code->width + 8, code->width + 8, QImage::Format_RGB32); + qrImage.fill(0xffffff); unsigned char *p = code->data; for (int y = 0; y < code->width; y++) { for (int x = 0; x < code->width; x++) { - myImage.setPixel(x + 4, y + 4, ((*p & 1) ? 0x0 : 0xffffff)); + qrImage.setPixel(x + 4, y + 4, ((*p & 1) ? 0x0 : 0xffffff)); p++; } } QRcode_free(code); - ui->lblQRCode->setPixmap(QPixmap::fromImage(myImage).scaled(300, 300)); + QImage qrAddrImage = QImage(QR_IMAGE_SIZE, QR_IMAGE_SIZE+20, QImage::Format_RGB32); + qrAddrImage.fill(0xffffff); + QPainter painter(&qrAddrImage); + painter.drawImage(0, 0, qrImage.scaled(QR_IMAGE_SIZE, QR_IMAGE_SIZE)); + QFont font = GUIUtil::fixedPitchFont(); + font.setPixelSize(12); + painter.setFont(font); + QRect paddedRect = qrAddrImage.rect(); + paddedRect.setHeight(QR_IMAGE_SIZE+12); + painter.drawText(paddedRect, Qt::AlignBottom|Qt::AlignCenter, info.address); + painter.end(); + + ui->lblQRCode->setPixmap(QPixmap::fromImage(qrAddrImage)); ui->btnSaveAs->setEnabled(true); } } diff --git a/src/qt/receiverequestdialog.h b/src/qt/receiverequestdialog.h index 4cab4caff1ac..676745a858f6 100644 --- a/src/qt/receiverequestdialog.h +++ b/src/qt/receiverequestdialog.h @@ -10,6 +10,7 @@ #include #include #include +#include class OptionsModel; From 9875ab53534e8548e1b8551ac0e2269cdebc4186 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 16 Jun 2016 10:53:23 +0200 Subject: [PATCH 05/47] Merge #8207: [trivial] Add a link to the Bitcoin-Core repository and website to the About Dialog fa58e5e [doc] Add website links to about dialog (MarcoFalke) --- src/init.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index a442b241fe79..45c471f28c73 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -590,11 +590,20 @@ std::string HelpMessage(HelpMessageMode mode) std::string LicenseInfo() { + const std::string URL_SOURCE_CODE = ""; + const std::string URL_WEBSITE = ""; // todo: remove urls from translations on next change return CopyrightHolders(_("Copyright (C)"), 2014, COPYRIGHT_YEAR) + "\n" + "\n" + - _("This is experimental software.") + "\n" + + strprintf(_("Please contribute if you find %s useful. " + "Visit %s for further information about the software."), + PACKAGE_NAME, URL_WEBSITE) + + "\n" + + strprintf(_("The source code is available from %s."), + URL_SOURCE_CODE) + "\n" + + "\n" + + _("This is experimental software.") + "\n" + _("Distributed under the MIT software license, see the accompanying file COPYING or .") + "\n" + "\n" + _("This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.") + From 402eb557325805887365a427de096cdae0ca93da Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 16 Jun 2016 10:57:55 +0200 Subject: [PATCH 06/47] Merge #8208: Do not set extra flags for unfiltered DNS seed results bc0a895 Do not set extra flags for unfiltered DNS seed results (Pieter Wuille) --- src/chainparams.cpp | 8 -------- src/chainparams.h | 4 +--- src/net.cpp | 14 +++++++++++++- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index c289f4f26c4f..68c6499ce235 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -19,14 +19,6 @@ #include "chainparamsseeds.h" -std::string CDNSSeedData::getHost(uint64_t requiredServiceBits) const { - //use default host for non-filter-capable seeds or if we use the default service bits (NODE_NETWORK) - if (!supportsServiceBitsFiltering || requiredServiceBits == NODE_NETWORK) - return host; - - return strprintf("x%x.%s", requiredServiceBits, host); -} - static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward) { CMutableTransaction txNew; diff --git a/src/chainparams.h b/src/chainparams.h index ed1d1abca9c1..fdad53d9d78a 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -13,11 +13,9 @@ #include -class CDNSSeedData { -public: +struct CDNSSeedData { std::string name, host; bool supportsServiceBitsFiltering; - std::string getHost(uint64_t requiredServiceBits) const; CDNSSeedData(const std::string &strName, const std::string &strHost, bool supportsServiceBitsFilteringIn = false) : name(strName), host(strHost), supportsServiceBitsFiltering(supportsServiceBitsFilteringIn) {} }; diff --git a/src/net.cpp b/src/net.cpp index f009ada74809..51310ce7ae19 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1502,6 +1502,18 @@ void MapPort(bool) +static std::string GetDNSHost(const CDNSSeedData& data, ServiceFlags* requiredServiceBits) +{ + //use default host for non-filter-capable seeds or if we use the default service bits (NODE_NETWORK) + if (!data.supportsServiceBitsFiltering || *requiredServiceBits == NODE_NETWORK) { + *requiredServiceBits = NODE_NETWORK; + return data.host; + } + + return strprintf("x%x.%s", *requiredServiceBits, data.host); +} + + void CConnman::ThreadDNSAddressSeed() { // goal: only query DNS seeds if address need is acute @@ -1529,7 +1541,7 @@ void CConnman::ThreadDNSAddressSeed() std::vector vIPs; std::vector vAdd; ServiceFlags requiredServiceBits = nRelevantServices; - if (LookupHost(seed.getHost(requiredServiceBits).c_str(), vIPs, 0, true)) + if (LookupHost(GetDNSHost(seed, &requiredServiceBits).c_str(), vIPs, 0, true)) { BOOST_FOREACH(const CNetAddr& ip, vIPs) { From c783b39ce7c47db0a2bb95226c07ebe344309ed1 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 16 Jun 2016 11:05:32 +0200 Subject: [PATCH 07/47] Merge #8171: [RPC] Fix createrawtx sequence number unsigned int parsing 6fa950a [RPC] Fix createrawtx sequence number unsigned int parsing (Jonas Schnelli) --- qa/rpc-tests/rawtransactions.py | 14 ++++++++++++++ src/rpc/rawtransaction.cpp | 9 +++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/rawtransactions.py b/qa/rpc-tests/rawtransactions.py index cec626b0db52..ab5cb845706f 100755 --- a/qa/rpc-tests/rawtransactions.py +++ b/qa/rpc-tests/rawtransactions.py @@ -143,6 +143,20 @@ def run_test(self): rawtx = self.nodes[0].createrawtransaction(inputs, outputs) decrawtx= self.nodes[0].decoderawtransaction(rawtx) assert_equal(decrawtx['vin'][0]['sequence'], 1000) + + inputs = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1, 'sequence' : -1}] + outputs = { self.nodes[0].getnewaddress() : 1 } + assert_raises(JSONRPCException, self.nodes[0].createrawtransaction, inputs, outputs) + + inputs = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1, 'sequence' : 4294967296}] + outputs = { self.nodes[0].getnewaddress() : 1 } + assert_raises(JSONRPCException, self.nodes[0].createrawtransaction, inputs, outputs) + + inputs = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1, 'sequence' : 4294967294}] + outputs = { self.nodes[0].getnewaddress() : 1 } + rawtx = self.nodes[0].createrawtransaction(inputs, outputs) + decrawtx= self.nodes[0].decoderawtransaction(rawtx) + assert_equal(decrawtx['vin'][0]['sequence'], 4294967294) if __name__ == '__main__': RawTransactionsTest().main() diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 14ad47d91ea3..904713f00932 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -428,8 +428,13 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp) // set the sequence number if passed in the parameters object const UniValue& sequenceObj = find_value(o, "sequence"); - if (sequenceObj.isNum()) - nSequence = sequenceObj.get_int(); + if (sequenceObj.isNum()) { + int64_t seqNr64 = sequenceObj.get_int64(); + if (seqNr64 < 0 || seqNr64 > std::numeric_limits::max()) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, sequence number is out of range"); + else + nSequence = (uint32_t)seqNr64; + } CTxIn in(COutPoint(txid, nOutput), CScript(), nSequence); From 79ad5f768227e0525f918fcdeb94e57fed79d2a0 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Sat, 16 Sep 2017 13:11:56 +0200 Subject: [PATCH 08/47] Bump univalue version This was probably missed while backporting Bitcoin PR #7892 --- src/univalue/configure.ac | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/univalue/configure.ac b/src/univalue/configure.ac index 0515b632bdf9..93d3ba945d14 100644 --- a/src/univalue/configure.ac +++ b/src/univalue/configure.ac @@ -1,7 +1,7 @@ m4_define([libunivalue_major_version], [1]) m4_define([libunivalue_minor_version], [1]) -m4_define([libunivalue_micro_version], [1]) -m4_define([libunivalue_interface_age], [1]) +m4_define([libunivalue_micro_version], [2]) +m4_define([libunivalue_interface_age], [2]) # If you need a modifier for the version number. # Normally empty, but can be used to make "fixup" releases. m4_define([libunivalue_extraversion], []) @@ -14,7 +14,7 @@ m4_define([libunivalue_age], [m4_eval(libunivalue_binary_age - libunivalue_inter m4_define([libunivalue_version], [libunivalue_major_version().libunivalue_minor_version().libunivalue_micro_version()libunivalue_extraversion()]) -AC_INIT([univalue], [1.0.1], +AC_INIT([univalue], [1.0.2], [http://github.com/jgarzik/univalue/]) dnl make the compilation flags quiet unless V=1 is used From f362c610e45f3965596c27d102708c35fa5ae92c Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 16 Jun 2016 18:42:45 +0200 Subject: [PATCH 09/47] Merge #7600: Mining: Select transactions using feerate-with-ancestors 29fac19 Add unit tests for ancestor feerate mining (Suhas Daftuar) c82a4e9 Use ancestor-feerate based transaction selection for mining (Suhas Daftuar) --- src/miner.cpp | 206 ++++++++++++++++++++++++++++++++++++++- src/miner.h | 118 ++++++++++++++++++++++ src/test/miner_tests.cpp | 109 +++++++++++++++++++++ 3 files changed, 432 insertions(+), 1 deletion(-) diff --git a/src/miner.cpp b/src/miner.cpp index ba50a96acc20..1b0e2a12aaf9 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -28,6 +28,7 @@ #include "masternode-sync.h" #include "validationinterface.h" +#include #include #include #include @@ -137,7 +138,7 @@ CBlockTemplate* BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn) : pblock->GetBlockTime(); addPriorityTxs(); - addScoreTxs(); + addPackageTxs(); nLastBlockTx = nBlockTx; nLastBlockSize = nBlockSize; @@ -192,7 +193,38 @@ bool BlockAssembler::isStillDependent(CTxMemPool::txiter iter) return false; } +void BlockAssembler::onlyUnconfirmed(CTxMemPool::setEntries& testSet) +{ + for (CTxMemPool::setEntries::iterator iit = testSet.begin(); iit != testSet.end(); ) { + // Only test txs not already in the block + if (inBlock.count(*iit)) { + testSet.erase(iit++); + } + else { + iit++; + } + } +} + +bool BlockAssembler::TestPackage(uint64_t packageSize, unsigned int packageSigOps) +{ + if (nBlockSize + packageSize >= nBlockMaxSize) + return false; + if (nBlockSigOps + packageSigOps >= MaxBlockSigOps(fDIP0001ActiveAtTip)) + return false; + return true; +} +// Block size and sigops have already been tested. Check that all transactions +// are final. +bool BlockAssembler::TestPackageFinality(const CTxMemPool::setEntries& package) +{ + BOOST_FOREACH (const CTxMemPool::txiter it, package) { + if (!IsFinalTx(it->GetTx(), nHeight, nLockTimeCutoff)) + return false; + } + return true; +} bool BlockAssembler::TestForBlock(CTxMemPool::txiter iter) { @@ -313,6 +345,178 @@ void BlockAssembler::addScoreTxs() } } +void BlockAssembler::UpdatePackagesForAdded(const CTxMemPool::setEntries& alreadyAdded, + indexed_modified_transaction_set &mapModifiedTx) +{ + BOOST_FOREACH(const CTxMemPool::txiter it, alreadyAdded) { + CTxMemPool::setEntries descendants; + mempool.CalculateDescendants(it, descendants); + // Insert all descendants (not yet in block) into the modified set + BOOST_FOREACH(CTxMemPool::txiter desc, descendants) { + if (alreadyAdded.count(desc)) + continue; + modtxiter mit = mapModifiedTx.find(desc); + if (mit == mapModifiedTx.end()) { + CTxMemPoolModifiedEntry modEntry(desc); + modEntry.nSizeWithAncestors -= it->GetTxSize(); + modEntry.nModFeesWithAncestors -= it->GetModifiedFee(); + modEntry.nSigOpCountWithAncestors -= it->GetSigOpCount(); + mapModifiedTx.insert(modEntry); + } else { + mapModifiedTx.modify(mit, update_for_parent_inclusion(it)); + } + } + } +} + +// Skip entries in mapTx that are already in a block or are present +// in mapModifiedTx (which implies that the mapTx ancestor state is +// stale due to ancestor inclusion in the block) +// Also skip transactions that we've already failed to add. This can happen if +// we consider a transaction in mapModifiedTx and it fails: we can then +// potentially consider it again while walking mapTx. It's currently +// guaranteed to fail again, but as a belt-and-suspenders check we put it in +// failedTx and avoid re-evaluation, since the re-evaluation would be using +// cached size/sigops/fee values that are not actually correct. +bool BlockAssembler::SkipMapTxEntry(CTxMemPool::txiter it, indexed_modified_transaction_set &mapModifiedTx, CTxMemPool::setEntries &failedTx) +{ + assert (it != mempool.mapTx.end()); + if (mapModifiedTx.count(it) || inBlock.count(it) || failedTx.count(it)) + return true; + return false; +} + +void BlockAssembler::SortForBlock(const CTxMemPool::setEntries& package, CTxMemPool::txiter entry, std::vector& sortedEntries) +{ + // Sort package by ancestor count + // If a transaction A depends on transaction B, then A's ancestor count + // must be greater than B's. So this is sufficient to validly order the + // transactions for block inclusion. + sortedEntries.clear(); + sortedEntries.insert(sortedEntries.begin(), package.begin(), package.end()); + std::sort(sortedEntries.begin(), sortedEntries.end(), CompareTxIterByAncestorCount()); +} + +// This transaction selection algorithm orders the mempool based +// on feerate of a transaction including all unconfirmed ancestors. +// Since we don't remove transactions from the mempool as we select them +// for block inclusion, we need an alternate method of updating the feerate +// of a transaction with its not-yet-selected ancestors as we go. +// This is accomplished by walking the in-mempool descendants of selected +// transactions and storing a temporary modified state in mapModifiedTxs. +// Each time through the loop, we compare the best transaction in +// mapModifiedTxs with the next transaction in the mempool to decide what +// transaction package to work on next. +void BlockAssembler::addPackageTxs() +{ + // mapModifiedTx will store sorted packages after they are modified + // because some of their txs are already in the block + indexed_modified_transaction_set mapModifiedTx; + // Keep track of entries that failed inclusion, to avoid duplicate work + CTxMemPool::setEntries failedTx; + + // Start by adding all descendants of previously added txs to mapModifiedTx + // and modifying them for their already included ancestors + UpdatePackagesForAdded(inBlock, mapModifiedTx); + + CTxMemPool::indexed_transaction_set::index::type::iterator mi = mempool.mapTx.get().begin(); + CTxMemPool::txiter iter; + while (mi != mempool.mapTx.get().end() || !mapModifiedTx.empty()) + { + // First try to find a new transaction in mapTx to evaluate. + if (mi != mempool.mapTx.get().end() && + SkipMapTxEntry(mempool.mapTx.project<0>(mi), mapModifiedTx, failedTx)) { + ++mi; + continue; + } + + // Now that mi is not stale, determine which transaction to evaluate: + // the next entry from mapTx, or the best from mapModifiedTx? + bool fUsingModified = false; + + modtxscoreiter modit = mapModifiedTx.get().begin(); + if (mi == mempool.mapTx.get().end()) { + // We're out of entries in mapTx; use the entry from mapModifiedTx + iter = modit->iter; + fUsingModified = true; + } else { + // Try to compare the mapTx entry to the mapModifiedTx entry + iter = mempool.mapTx.project<0>(mi); + if (modit != mapModifiedTx.get().end() && + CompareModifiedEntry()(*modit, CTxMemPoolModifiedEntry(iter))) { + // The best entry in mapModifiedTx has higher score + // than the one from mapTx. + // Switch which transaction (package) to consider + iter = modit->iter; + fUsingModified = true; + } else { + // Either no entry in mapModifiedTx, or it's worse than mapTx. + // Increment mi for the next loop iteration. + ++mi; + } + } + + // We skip mapTx entries that are inBlock, and mapModifiedTx shouldn't + // contain anything that is inBlock. + assert(!inBlock.count(iter)); + + uint64_t packageSize = iter->GetSizeWithAncestors(); + CAmount packageFees = iter->GetModFeesWithAncestors(); + unsigned int packageSigOps = iter->GetSigOpCountWithAncestors(); + if (fUsingModified) { + packageSize = modit->nSizeWithAncestors; + packageFees = modit->nModFeesWithAncestors; + packageSigOps = modit->nSigOpCountWithAncestors; + } + + if (packageFees < ::minRelayTxFee.GetFee(packageSize) && nBlockSize >= nBlockMinSize) { + // Everything else we might consider has a lower fee rate + return; + } + + if (!TestPackage(packageSize, packageSigOps)) { + if (fUsingModified) { + // Since we always look at the best entry in mapModifiedTx, + // we must erase failed entries so that we can consider the + // next best entry on the next loop iteration + mapModifiedTx.get().erase(modit); + failedTx.insert(iter); + } + continue; + } + + CTxMemPool::setEntries ancestors; + uint64_t nNoLimit = std::numeric_limits::max(); + std::string dummy; + mempool.CalculateMemPoolAncestors(*iter, ancestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy, false); + + onlyUnconfirmed(ancestors); + ancestors.insert(iter); + + // Test if all tx's are Final + if (!TestPackageFinality(ancestors)) { + if (fUsingModified) { + mapModifiedTx.get().erase(modit); + failedTx.insert(iter); + } + continue; + } + + // Package can be added. Sort the entries in a valid order. + vector sortedEntries; + SortForBlock(ancestors, iter, sortedEntries); + + for (size_t i=0; i #include +#include "boost/multi_index_container.hpp" +#include "boost/multi_index/ordered_index.hpp" class CBlockIndex; class CChainParams; @@ -30,6 +32,104 @@ struct CBlockTemplate std::vector vTxSigOps; }; +// Container for tracking updates to ancestor feerate as we include (parent) +// transactions in a block +struct CTxMemPoolModifiedEntry { + CTxMemPoolModifiedEntry(CTxMemPool::txiter entry) + { + iter = entry; + nSizeWithAncestors = entry->GetSizeWithAncestors(); + nModFeesWithAncestors = entry->GetModFeesWithAncestors(); + nSigOpCountWithAncestors = entry->GetSigOpCountWithAncestors(); + } + + CTxMemPool::txiter iter; + uint64_t nSizeWithAncestors; + CAmount nModFeesWithAncestors; + unsigned int nSigOpCountWithAncestors; +}; + +/** Comparator for CTxMemPool::txiter objects. + * It simply compares the internal memory address of the CTxMemPoolEntry object + * pointed to. This means it has no meaning, and is only useful for using them + * as key in other indexes. + */ +struct CompareCTxMemPoolIter { + bool operator()(const CTxMemPool::txiter& a, const CTxMemPool::txiter& b) const + { + return &(*a) < &(*b); + } +}; + +struct modifiedentry_iter { + typedef CTxMemPool::txiter result_type; + result_type operator() (const CTxMemPoolModifiedEntry &entry) const + { + return entry.iter; + } +}; + +// This matches the calculation in CompareTxMemPoolEntryByAncestorFee, +// except operating on CTxMemPoolModifiedEntry. +// TODO: refactor to avoid duplication of this logic. +struct CompareModifiedEntry { + bool operator()(const CTxMemPoolModifiedEntry &a, const CTxMemPoolModifiedEntry &b) + { + double f1 = (double)a.nModFeesWithAncestors * b.nSizeWithAncestors; + double f2 = (double)b.nModFeesWithAncestors * a.nSizeWithAncestors; + if (f1 == f2) { + return CTxMemPool::CompareIteratorByHash()(a.iter, b.iter); + } + return f1 > f2; + } +}; + +// A comparator that sorts transactions based on number of ancestors. +// This is sufficient to sort an ancestor package in an order that is valid +// to appear in a block. +struct CompareTxIterByAncestorCount { + bool operator()(const CTxMemPool::txiter &a, const CTxMemPool::txiter &b) + { + if (a->GetCountWithAncestors() != b->GetCountWithAncestors()) + return a->GetCountWithAncestors() < b->GetCountWithAncestors(); + return CTxMemPool::CompareIteratorByHash()(a, b); + } +}; + +typedef boost::multi_index_container< + CTxMemPoolModifiedEntry, + boost::multi_index::indexed_by< + boost::multi_index::ordered_unique< + modifiedentry_iter, + CompareCTxMemPoolIter + >, + // sorted by modified ancestor fee rate + boost::multi_index::ordered_non_unique< + // Reuse same tag from CTxMemPool's similar index + boost::multi_index::tag, + boost::multi_index::identity, + CompareModifiedEntry + > + > +> indexed_modified_transaction_set; + +typedef indexed_modified_transaction_set::nth_index<0>::type::iterator modtxiter; +typedef indexed_modified_transaction_set::index::type::iterator modtxscoreiter; + +struct update_for_parent_inclusion +{ + update_for_parent_inclusion(CTxMemPool::txiter it) : iter(it) {} + + void operator() (CTxMemPoolModifiedEntry &e) + { + e.nModFeesWithAncestors -= iter->GetFee(); + e.nSizeWithAncestors -= iter->GetTxSize(); + e.nSigOpCountWithAncestors -= iter->GetSigOpCount(); + } + + CTxMemPool::txiter iter; +}; + /** Generate a new block, without valid proof-of-work */ class BlockAssembler { @@ -75,12 +175,30 @@ class BlockAssembler void addScoreTxs(); /** Add transactions based on tx "priority" */ void addPriorityTxs(); + /** Add transactions based on feerate including unconfirmed ancestors */ + void addPackageTxs(); // helper function for addScoreTxs and addPriorityTxs /** Test if tx will still "fit" in the block */ bool TestForBlock(CTxMemPool::txiter iter); /** Test if tx still has unconfirmed parents not yet in block */ bool isStillDependent(CTxMemPool::txiter iter); + + // helper functions for addPackageTxs() + /** Remove confirmed (inBlock) entries from given set */ + void onlyUnconfirmed(CTxMemPool::setEntries& testSet); + /** Test if a new package would "fit" in the block */ + bool TestPackage(uint64_t packageSize, unsigned int packageSigOps); + /** Test if a set of transactions are all final */ + bool TestPackageFinality(const CTxMemPool::setEntries& package); + /** Return true if given transaction from mapTx has already been evaluated, + * or if the transaction's cached data in mapTx is incorrect. */ + bool SkipMapTxEntry(CTxMemPool::txiter it, indexed_modified_transaction_set &mapModifiedTx, CTxMemPool::setEntries &failedTx); + /** Sort the package in an order that is valid to appear in a block */ + void SortForBlock(const CTxMemPool::setEntries& package, CTxMemPool::txiter entry, std::vector& sortedEntries); + /** Add descendants of given transactions to mapModifiedTx with ancestor + * state updated assuming given transactions are inBlock. */ + void UpdatePackagesForAdded(const CTxMemPool::setEntries& alreadyAdded, indexed_modified_transaction_set &mapModifiedTx); }; /** Modify the extranonce in a block */ diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 7da7a11ea793..5cb7575921a8 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -72,6 +72,113 @@ bool TestSequenceLocks(const CTransaction &tx, int flags) return CheckSequenceLocks(tx, flags); } +// Test suite for ancestor feerate transaction selection. +// Implemented as an additional function, rather than a separate test case, +// to allow reusing the blockchain created in CreateNewBlock_validity. +// Note that this test assumes blockprioritysize is 0. +void TestPackageSelection(const CChainParams& chainparams, CScript scriptPubKey, std::vector& txFirst) +{ + // Test the ancestor feerate transaction selection. + TestMemPoolEntryHelper entry; + + // Test that a medium fee transaction will be selected after a higher fee + // rate package with a low fee rate parent. + CMutableTransaction tx; + tx.vin.resize(1); + tx.vin[0].scriptSig = CScript() << OP_1; + tx.vin[0].prevout.hash = txFirst[0]->GetHash(); + tx.vin[0].prevout.n = 0; + tx.vout.resize(1); + tx.vout[0].nValue = 5000000000LL - 1000; + // This tx has a low fee: 1000 satoshis + uint256 hashParentTx = tx.GetHash(); // save this txid for later use + mempool.addUnchecked(hashParentTx, entry.Fee(1000).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); + + // This tx has a medium fee: 10000 satoshis + tx.vin[0].prevout.hash = txFirst[1]->GetHash(); + tx.vout[0].nValue = 5000000000LL - 10000; + uint256 hashMediumFeeTx = tx.GetHash(); + mempool.addUnchecked(hashMediumFeeTx, entry.Fee(10000).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); + + // This tx has a high fee, but depends on the first transaction + tx.vin[0].prevout.hash = hashParentTx; + tx.vout[0].nValue = 5000000000LL - 1000 - 50000; // 50k satoshi fee + uint256 hashHighFeeTx = tx.GetHash(); + mempool.addUnchecked(hashHighFeeTx, entry.Fee(50000).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); + + CBlockTemplate *pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); + BOOST_CHECK(pblocktemplate->block.vtx[1].GetHash() == hashParentTx); + BOOST_CHECK(pblocktemplate->block.vtx[2].GetHash() == hashHighFeeTx); + BOOST_CHECK(pblocktemplate->block.vtx[3].GetHash() == hashMediumFeeTx); + + // Test that a package below the min relay fee doesn't get included + tx.vin[0].prevout.hash = hashHighFeeTx; + tx.vout[0].nValue = 5000000000LL - 1000 - 50000; // 0 fee + uint256 hashFreeTx = tx.GetHash(); + mempool.addUnchecked(hashFreeTx, entry.Fee(0).FromTx(tx)); + size_t freeTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); + + // Calculate a fee on child transaction that will put the package just + // below the min relay fee (assuming 1 child tx of the same size). + CAmount feeToUse = minRelayTxFee.GetFee(2*freeTxSize) - 1; + + tx.vin[0].prevout.hash = hashFreeTx; + tx.vout[0].nValue = 5000000000LL - 1000 - 50000 - feeToUse; + uint256 hashLowFeeTx = tx.GetHash(); + mempool.addUnchecked(hashLowFeeTx, entry.Fee(feeToUse).FromTx(tx)); + pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); + // Verify that the free tx and the low fee tx didn't get selected + for (size_t i=0; iblock.vtx.size(); ++i) { + BOOST_CHECK(pblocktemplate->block.vtx[i].GetHash() != hashFreeTx); + BOOST_CHECK(pblocktemplate->block.vtx[i].GetHash() != hashLowFeeTx); + } + + // Test that packages above the min relay fee do get included, even if one + // of the transactions is below the min relay fee + // Remove the low fee transaction and replace with a higher fee transaction + std::list dummy; + mempool.removeRecursive(tx, dummy); + tx.vout[0].nValue -= 2; // Now we should be just over the min relay fee + hashLowFeeTx = tx.GetHash(); + mempool.addUnchecked(hashLowFeeTx, entry.Fee(feeToUse+2).FromTx(tx)); + pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); + BOOST_CHECK(pblocktemplate->block.vtx[4].GetHash() == hashFreeTx); + BOOST_CHECK(pblocktemplate->block.vtx[5].GetHash() == hashLowFeeTx); + + // Test that transaction selection properly updates ancestor fee + // calculations as ancestor transactions get included in a block. + // Add a 0-fee transaction that has 2 outputs. + tx.vin[0].prevout.hash = txFirst[2]->GetHash(); + tx.vout.resize(2); + tx.vout[0].nValue = 5000000000LL - 100000000; + tx.vout[1].nValue = 100000000; // 1BTC output + uint256 hashFreeTx2 = tx.GetHash(); + mempool.addUnchecked(hashFreeTx2, entry.Fee(0).SpendsCoinbase(true).FromTx(tx)); + + // This tx can't be mined by itself + tx.vin[0].prevout.hash = hashFreeTx2; + tx.vout.resize(1); + feeToUse = minRelayTxFee.GetFee(freeTxSize); + tx.vout[0].nValue = 5000000000LL - 100000000 - feeToUse; + uint256 hashLowFeeTx2 = tx.GetHash(); + mempool.addUnchecked(hashLowFeeTx2, entry.Fee(feeToUse).SpendsCoinbase(false).FromTx(tx)); + pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); + + // Verify that this tx isn't selected. + for (size_t i=0; iblock.vtx.size(); ++i) { + BOOST_CHECK(pblocktemplate->block.vtx[i].GetHash() != hashFreeTx2); + BOOST_CHECK(pblocktemplate->block.vtx[i].GetHash() != hashLowFeeTx2); + } + + // This tx will be mineable, and should cause hashLowFeeTx2 to be selected + // as well. + tx.vin[0].prevout.n = 1; + tx.vout[0].nValue = 100000000 - 10000; // 10k satoshi fee + mempool.addUnchecked(tx.GetHash(), entry.Fee(10000).FromTx(tx)); + pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); + BOOST_CHECK(pblocktemplate->block.vtx[8].GetHash() == hashLowFeeTx2); +} + // NOTE: These tests rely on CreateNewBlock doing its own self-validation! BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) { @@ -387,6 +494,8 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) SetMockTime(0); mempool.clear(); + TestPackageSelection(chainparams, scriptPubKey, txFirst); + BOOST_FOREACH(CTransaction *_tx, txFirst) delete _tx; From 6227cfdad532c5d2c8895a78fe7821ae645d5d5c Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Fri, 17 Jun 2016 15:41:32 +0200 Subject: [PATCH 10/47] Merge #8214: [qa] mininode: fail on send_message instead of silent return facb6c0 [qa] mininode: fail on send_message instead of silent return (MarcoFalke) --- qa/rpc-tests/test_framework/mininode.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index 822c10ac1a06..c1735dc76696 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -1319,7 +1319,7 @@ def got_data(self): def send_message(self, message, pushbuf=False): if self.state != "connected" and not pushbuf: - return + raise IOError('Not connected, no pushbuf') self.show_debug_msg("Send %s" % repr(message)) command = message.command data = message.serialize() From 46473757ee5baf4ee712aa11ad4a515e66e45d10 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sat, 18 Jun 2016 16:49:11 +0200 Subject: [PATCH 11/47] Merge #8215: [wallet] tests: Don't use floating point faa91b1 [wallet] tests: Don't use floating point (MarcoFalke) --- src/wallet/test/wallet_tests.cpp | 46 +++++++++++++++++--------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index 387b22358934..0a4f06ba8817 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -27,7 +27,7 @@ typedef set > CoinSet; BOOST_FIXTURE_TEST_SUITE(wallet_tests, WalletTestingSetup) -static CWallet wallet; +static const CWallet wallet; static vector vCoins; static void add_coin(const CAmount& nValue, int nAge = 6*24, bool fIsFromMe = false, int nInput=0) @@ -188,11 +188,11 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // empty the wallet and start again, now with fractions of a cent, to test small change avoidance empty_wallet(); - add_coin(0.1*MIN_CHANGE); - add_coin(0.2*MIN_CHANGE); - add_coin(0.3*MIN_CHANGE); - add_coin(0.4*MIN_CHANGE); - add_coin(0.5*MIN_CHANGE); + add_coin(MIN_CHANGE * 1 / 10); + add_coin(MIN_CHANGE * 2 / 10); + add_coin(MIN_CHANGE * 3 / 10); + add_coin(MIN_CHANGE * 4 / 10); + add_coin(MIN_CHANGE * 5 / 10); // try making 1 * MIN_CHANGE from the 1.5 * MIN_CHANGE // we'll get change smaller than MIN_CHANGE whatever happens, so can expect MIN_CHANGE exactly @@ -207,8 +207,8 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) BOOST_CHECK_EQUAL(nValueRet, 1 * MIN_CHANGE); // we should get the exact amount // if we add more small coins: - add_coin(0.6*MIN_CHANGE); - add_coin(0.7*MIN_CHANGE); + add_coin(MIN_CHANGE * 6 / 10); + add_coin(MIN_CHANGE * 7 / 10); // and try again to make 1.0 * MIN_CHANGE BOOST_CHECK( wallet.SelectCoinsMinConf(1 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); @@ -229,9 +229,9 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // sometimes it will fail, and so we use the next biggest coin: empty_wallet(); - add_coin(0.5 * MIN_CHANGE); - add_coin(0.6 * MIN_CHANGE); - add_coin(0.7 * MIN_CHANGE); + add_coin(MIN_CHANGE * 5 / 10); + add_coin(MIN_CHANGE * 6 / 10); + add_coin(MIN_CHANGE * 7 / 10); add_coin(1111 * MIN_CHANGE); BOOST_CHECK( wallet.SelectCoinsMinConf(1 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 1111 * MIN_CHANGE); // we get the bigger coin @@ -239,9 +239,9 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // but sometimes it's possible, and we use an exact subset (0.4 + 0.6 = 1.0) empty_wallet(); - add_coin(0.4 * MIN_CHANGE); - add_coin(0.6 * MIN_CHANGE); - add_coin(0.8 * MIN_CHANGE); + add_coin(MIN_CHANGE * 4 / 10); + add_coin(MIN_CHANGE * 6 / 10); + add_coin(MIN_CHANGE * 8 / 10); add_coin(1111 * MIN_CHANGE); BOOST_CHECK( wallet.SelectCoinsMinConf(MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, MIN_CHANGE); // we should get the exact amount @@ -249,17 +249,17 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // test avoiding small change empty_wallet(); - add_coin(0.05 * MIN_CHANGE); - add_coin(1 * MIN_CHANGE); - add_coin(100 * MIN_CHANGE); + add_coin(MIN_CHANGE * 5 / 100); + add_coin(MIN_CHANGE * 1); + add_coin(MIN_CHANGE * 100); // trying to make 100.01 from these three coins - BOOST_CHECK( wallet.SelectCoinsMinConf(100.01 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); - BOOST_CHECK_EQUAL(nValueRet, 101.05 * MIN_CHANGE); // we should get all coins + BOOST_CHECK(wallet.SelectCoinsMinConf(MIN_CHANGE * 10001 / 100, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, MIN_CHANGE * 10105 / 100); // we should get all coins BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); // but if we try to make 99.9, we should take the bigger of the two small coins to avoid small change - BOOST_CHECK( wallet.SelectCoinsMinConf(99.9 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(MIN_CHANGE * 9990 / 100, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 101 * MIN_CHANGE); BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); @@ -310,7 +310,11 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // add 75 cents in small change. not enough to make 90 cents, // then try making 90 cents. there are multiple competing "smallest bigger" coins, // one of which should be picked at random - add_coin( 5*CENT); add_coin(10*CENT); add_coin(15*CENT); add_coin(20*CENT); add_coin(25*CENT); + add_coin(5 * CENT); + add_coin(10 * CENT); + add_coin(15 * CENT); + add_coin(20 * CENT); + add_coin(25 * CENT); fails = 0; for (int i = 0; i < RANDOM_REPEATS; i++) From b6d8206c20f1ffaa6391e4d403557f659b775e76 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 20 Jun 2016 10:29:13 +0200 Subject: [PATCH 12/47] Merge #8224: readme: Omit phrasing; 'new' 7734479 readme: Omit phrasing; 'new' (Will Binns) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f8c7114ef784..9f9b40845f37 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ https://www.dash.org What is Dash? ---------------- -Dash is an experimental new digital currency that enables anonymous, instant +Dash is an experimental digital currency that enables anonymous, instant payments to anyone, anywhere in the world. Dash uses peer-to-peer technology to operate with no central authority: managing transactions and issuing money are carried out collectively by the network. Dash Core is the name of the open From 05684db6e3e33149642e004d4f6095043d1ff734 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 20 Jun 2016 10:48:07 +0200 Subject: [PATCH 13/47] Merge #8203: Clarify documentation for running a tor node 9e3ec74 Clarify documentation for running a tor node (Nathaniel Mahieu) --- doc/tor.md | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/doc/tor.md b/doc/tor.md index 1b8855502d1c..05e3f9e02387 100644 --- a/doc/tor.md +++ b/doc/tor.md @@ -122,12 +122,22 @@ Starting with Tor version 0.2.7.1 it is possible, through Tor's control socket API, to create and destroy 'ephemeral' hidden services programmatically. Dash Core has been updated to make use of this. -This means that if Tor is running (and proper authorization is available), -Dash Core automatically creates a hidden service to listen on, without -manual configuration. This will positively affect the number of available -.onion nodes. +This means that if Tor is running (and proper authentication has been configured), +Dash Core automatically creates a hidden service to listen on. This will positively +affect the number of available .onion nodes. This new feature is enabled by default if Dash Core is listening, and a connection to Tor can be made. It can be configured with the `-listenonion`, `-torcontrol` and `-torpassword` settings. To show verbose debugging information, pass `-debug=tor`. + +Connecting to Tor's control socket API requires one of two authentication methods to be +configured. For cookie authentication the user running dashd must have write access +to the `CookieAuthFile` specified in Tor configuration. In some cases this is +preconfigured and the creation of a hidden service is automatic. If permission problems +are seen with `-debug=tor` they can be resolved by adding both the user running tor and +the user running dashd to the same group and setting permissions appropriately. On +Debian-based systems the user running dashd can be added to the debian-tor group, +which has the appropriate permissions. An alternative authentication method is the use +of the `-torpassword` flag and a `hash-password` which can be enabled and specified in +Tor configuration. \ No newline at end of file From 68757db683f882dbefae06ac87ef52a632ff3940 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 20 Jun 2016 13:31:17 +0200 Subject: [PATCH 14/47] Merge #8210: [Qt] Bump to Qt5.6.1 2759597 Only pass -lQt5PlatformSupport if >=Qt5.6 (Jonas Schnelli) 59d063d Use runtime linking of QT libdbus, use custom/temp. SDK URL (Jonas Schnelli) 6194d9a Fix bitcoin_qt.m4 and fix-xcb-include-order.patch (Jonas Schnelli) f6eb4e2 [depends] OpenSSL 1.0.1k - update config_opts (fanquake) f25209a depends: bump OSX toolchain (Cory Fields) --- .travis.yml | 4 +- build-aux/m4/bitcoin_qt.m4 | 4 + contrib/gitian-descriptors/gitian-osx.yml | 4 +- depends/hosts/darwin.mk | 4 +- depends/packages/native_cctools.mk | 20 +++-- depends/packages/openssl.mk | 39 +++++++- depends/packages/qt.mk | 88 ++++++++++--------- .../patches/qt/fix-xcb-include-order.patch | 28 +++--- depends/patches/qt/fix_qt_pkgconfig.patch | 11 +++ src/qt/dash.cpp | 3 + 10 files changed, 134 insertions(+), 71 deletions(-) create mode 100644 depends/patches/qt/fix_qt_pkgconfig.patch diff --git a/.travis.yml b/.travis.yml index ec8b746721b7..45eb965726fe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,7 +31,7 @@ env: - CCACHE_TEMPDIR=/tmp/.ccache-temp - CCACHE_COMPRESS=1 - BASE_OUTDIR=$TRAVIS_BUILD_DIR/out - - SDK_URL=https://bitcoincore.org/depends-sources/sdks + - SDK_URL=https://bitcoin.jonasschnelli.ch/sdks - PYTHON_DEBUG=1 - WINEDEBUG=fixme-all @@ -49,7 +49,7 @@ env: # No wallet - HOST=x86_64-unknown-linux-gnu PPA="ppa:bitcoin/bitcoin" PACKAGES="python3" DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" # Cross-Mac - - HOST=x86_64-apple-darwin11 PPA="ppa:bitcoin/bitcoin" PACKAGES="cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python3-dev" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" OSX_SDK=10.9 GOAL="deploy" + - HOST=x86_64-apple-darwin11 PPA="ppa:bitcoin/bitcoin" PACKAGES="cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python3-dev" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" OSX_SDK=10.11 GOAL="deploy" before_install: - git clone https://github.com/dashpay/dash_hash diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index b09a5fb7112d..13f4c7469733 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -357,6 +357,10 @@ AC_DEFUN([_BITCOIN_QT_FIND_STATIC_PLUGINS],[ elif test x$TARGET_OS = xdarwin; then PKG_CHECK_MODULES([QTPRINT], [Qt5PrintSupport], [QT_LIBS="$QTPRINT_LIBS $QT_LIBS"]) fi + else + if ${PKG_CONFIG} --exists "Qt5Core >= 5.6" 2>/dev/null; then + QT_LIBS="-lQt5PlatformSupport $QT_LIBS" + fi fi ]) else diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index 64007a7b6c39..9abc4776fbbd 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -31,7 +31,7 @@ remotes: - "url": "https://github.com/dashpay/dash.git" "dir": "dash" files: -- "MacOSX10.9.sdk.tar.gz" +- "MacOSX10.11.sdk.tar.gz" script: | WRAP_DIR=$HOME/wrapped HOSTS="x86_64-apple-darwin11" @@ -87,7 +87,7 @@ script: | BASEPREFIX=`pwd`/depends mkdir -p ${BASEPREFIX}/SDKs - tar -C ${BASEPREFIX}/SDKs -xf ${BUILD_DIR}/MacOSX10.9.sdk.tar.gz + tar -C ${BASEPREFIX}/SDKs -xf ${BUILD_DIR}/MacOSX10.11.sdk.tar.gz # Build dependencies for each host for i in $HOSTS; do diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk index dbe6d00795e0..985649619ffe 100644 --- a/depends/hosts/darwin.mk +++ b/depends/hosts/darwin.mk @@ -1,7 +1,7 @@ OSX_MIN_VERSION=10.7 -OSX_SDK_VERSION=10.9 +OSX_SDK_VERSION=10.11 OSX_SDK=$(SDK_PATH)/MacOSX$(OSX_SDK_VERSION).sdk -LD64_VERSION=241.9 +LD64_VERSION=253.9 darwin_CC=clang -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) darwin_CXX=clang++ -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) -stdlib=libc++ diff --git a/depends/packages/native_cctools.mk b/depends/packages/native_cctools.mk index b5603a8d48c6..797480c25eb2 100644 --- a/depends/packages/native_cctools.mk +++ b/depends/packages/native_cctools.mk @@ -1,14 +1,14 @@ package=native_cctools -$(package)_version=ee31ae567931c426136c94aad457c7b51d844beb +$(package)_version=807d6fd1be5d2224872e381870c0a75387fe05e6 $(package)_download_path=https://github.com/theuni/cctools-port/archive $(package)_file_name=$($(package)_version).tar.gz -$(package)_sha256_hash=ef107e6ab1b3994cb22e14f4f5c59ea0c0b5a988e6b21d42ed9616b018bbcbf9 +$(package)_sha256_hash=a09c9ba4684670a0375e42d9d67e7f12c1f62581a27f28f7c825d6d7032ccc6a $(package)_build_subdir=cctools -$(package)_clang_version=3.3 +$(package)_clang_version=3.7.1 $(package)_clang_download_path=http://llvm.org/releases/$($(package)_clang_version) -$(package)_clang_download_file=clang+llvm-$($(package)_clang_version)-amd64-Ubuntu-12.04.2.tar.gz -$(package)_clang_file_name=clang-llvm-$($(package)_clang_version)-amd64-Ubuntu-12.04.2.tar.gz -$(package)_clang_sha256_hash=60d8f69f032d62ef61bf527857ebb933741ec3352d4d328c5516aa520662dab7 +$(package)_clang_download_file=clang+llvm-$($(package)_clang_version)-x86_64-linux-gnu-ubuntu-14.04.tar.xz +$(package)_clang_file_name=clang-llvm-$($(package)_clang_version)-x86_64-linux-gnu-ubuntu-14.04.tar.xz +$(package)_clang_sha256_hash=99b28a6b48e793705228a390471991386daa33a9717cd9ca007fcdde69608fd9 $(package)_extra_sources=$($(package)_clang_file_name) define $(package)_fetch_cmds @@ -23,6 +23,7 @@ define $(package)_extract_cmds $(build_SHA256SUM) -c $($(package)_extract_dir)/.$($(package)_file_name).hash && \ mkdir -p toolchain/bin toolchain/lib/clang/3.5/include && \ tar --strip-components=1 -C toolchain -xf $($(package)_source_dir)/$($(package)_clang_file_name) && \ + rm -f toolchain/lib/libc++abi.so* && \ echo "#!/bin/sh" > toolchain/bin/$(host)-dsymutil && \ echo "exit 0" >> toolchain/bin/$(host)-dsymutil && \ chmod +x toolchain/bin/$(host)-dsymutil && \ @@ -30,7 +31,7 @@ define $(package)_extract_cmds endef define $(package)_set_vars -$(package)_config_opts=--target=$(host) --disable-libuuid +$(package)_config_opts=--target=$(host) --disable-lto-support $(package)_ldflags+=-Wl,-rpath=\\$$$$$$$$\$$$$$$$$ORIGIN/../lib $(package)_cc=$($(package)_extract_dir)/toolchain/bin/clang $(package)_cxx=$($(package)_extract_dir)/toolchain/bin/clang++ @@ -53,10 +54,11 @@ define $(package)_stage_cmds cd $($(package)_extract_dir)/toolchain && \ mkdir -p $($(package)_staging_prefix_dir)/lib/clang/$($(package)_clang_version)/include && \ mkdir -p $($(package)_staging_prefix_dir)/bin $($(package)_staging_prefix_dir)/include && \ - cp -P bin/clang bin/clang++ $($(package)_staging_prefix_dir)/bin/ &&\ + cp bin/clang $($(package)_staging_prefix_dir)/bin/ &&\ + cp -P bin/clang++ $($(package)_staging_prefix_dir)/bin/ &&\ cp lib/libLTO.so $($(package)_staging_prefix_dir)/lib/ && \ cp -rf lib/clang/$($(package)_clang_version)/include/* $($(package)_staging_prefix_dir)/lib/clang/$($(package)_clang_version)/include/ && \ - cp bin/$(host)-dsymutil $($(package)_staging_prefix_dir)/bin && \ + cp bin/llvm-dsymutil $($(package)_staging_prefix_dir)/bin/$(host)-dsymutil && \ if `test -d include/c++/`; then cp -rf include/c++/ $($(package)_staging_prefix_dir)/include/; fi && \ if `test -d lib/c++/`; then cp -rf lib/c++/ $($(package)_staging_prefix_dir)/lib/; fi endef diff --git a/depends/packages/openssl.mk b/depends/packages/openssl.mk index fe6eb97dead0..5ee9f17a6323 100644 --- a/depends/packages/openssl.mk +++ b/depends/packages/openssl.mk @@ -6,9 +6,42 @@ $(package)_sha256_hash=8f9faeaebad088e772f4ef5e38252d472be4d878c6b3a2718c10a4fce define $(package)_set_vars $(package)_config_env=AR="$($(package)_ar)" RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)" -$(package)_config_opts=--prefix=$(host_prefix) --openssldir=$(host_prefix)/etc/openssl no-zlib no-shared no-dso -$(package)_config_opts+=no-krb5 no-capieng no-dtls1 no-gost no-gmp no-heartbeats no-jpake no-md2 -$(package)_config_opts+=no-rc5 no-rdrand no-rfc3779 no-rsax no-sctp no-sha0 no-static_engine no-ssl2 no-ssl3 +$(package)_config_opts=--prefix=$(host_prefix) --openssldir=$(host_prefix)/etc/openssl +$(package)_config_opts+=no-camellia +$(package)_config_opts+=no-capieng +$(package)_config_opts+=no-cast +$(package)_config_opts+=no-comp +$(package)_config_opts+=no-dso +$(package)_config_opts+=no-dtls1 +$(package)_config_opts+=no-ec_nistp_64_gcc_128 +$(package)_config_opts+=no-gost +$(package)_config_opts+=no-gmp +$(package)_config_opts+=no-heartbeats +$(package)_config_opts+=no-idea +$(package)_config_opts+=no-jpake +$(package)_config_opts+=no-krb5 +$(package)_config_opts+=no-libunbound +$(package)_config_opts+=no-md2 +$(package)_config_opts+=no-mdc2 +$(package)_config_opts+=no-rc4 +$(package)_config_opts+=no-rc5 +$(package)_config_opts+=no-rdrand +$(package)_config_opts+=no-rfc3779 +$(package)_config_opts+=no-rsax +$(package)_config_opts+=no-sctp +$(package)_config_opts+=no-seed +$(package)_config_opts+=no-sha0 +$(package)_config_opts+=no-shared +$(package)_config_opts+=no-ssl-trace +$(package)_config_opts+=no-ssl2 +$(package)_config_opts+=no-ssl3 +$(package)_config_opts+=no-static_engine +$(package)_config_opts+=no-store +$(package)_config_opts+=no-unit-test +$(package)_config_opts+=no-weak-ssl-ciphers +$(package)_config_opts+=no-whirlpool +$(package)_config_opts+=no-zlib +$(package)_config_opts+=no-zlib-dynamic $(package)_config_opts+=$($(package)_cflags) $($(package)_cppflags) $(package)_config_opts_linux=-fPIC -Wa,--noexecstack $(package)_config_opts_x86_64_linux=linux-x86_64 diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index b7a2413750d0..d41d0b9ea5b1 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -1,20 +1,21 @@ PACKAGE=qt -$(package)_version=5.5.0 -$(package)_download_path=http://download.qt.io/archive/qt/5.5/$($(package)_version)/submodules +$(package)_version=5.6.1 +$(package)_download_path=http://download.qt.io/official_releases/qt/5.6/$($(package)_version)/submodules $(package)_suffix=opensource-src-$($(package)_version).tar.gz $(package)_file_name=qtbase-$($(package)_suffix) -$(package)_sha256_hash=7e82b1318f88e56a2a9376e069aa608d4fd96b48cb0e1b880ae658b0a1af0561 +$(package)_sha256_hash=0ac67cf8d66d52b995f96c31c4b48117a1afb3db99eaa93e20ccd8f7f55f7fde $(package)_dependencies=openssl -$(package)_linux_dependencies=freetype fontconfig dbus libxcb libX11 xproto libXext +$(package)_linux_dependencies=freetype fontconfig libxcb libX11 xproto libXext $(package)_build_subdir=qtbase $(package)_qt_libs=corelib network widgets gui plugins testlib -$(package)_patches=mac-qmake.conf fix-xcb-include-order.patch mingw-uuidof.patch pidlist_absolute.patch +$(package)_patches=mac-qmake.conf mingw-uuidof.patch pidlist_absolute.patch fix-xcb-include-order.patch fix_qt_pkgconfig.patch $(package)_qttranslations_file_name=qttranslations-$($(package)_suffix) -$(package)_qttranslations_sha256_hash=c4bd6db6e426965c6f8824c54e81f68bbd61e2bae1bcadc328c6e81c45902a0d +$(package)_qttranslations_sha256_hash=dcc1534d247babca1840cb6d0a000671801a341ea352d0535474f86adadaf028 + $(package)_qttools_file_name=qttools-$($(package)_suffix) -$(package)_qttools_sha256_hash=d9e06bd19ecc86afba5e95d45a906d1bc1ad579aa70001e36143c1aaf695bdd6 +$(package)_qttools_sha256_hash=e0f845de28c31230dfa428f0190ccb3b91d1fc02481b1f064698ae4ef8376aa1 $(package)_extra_sources = $($(package)_qttranslations_file_name) $(package)_extra_sources += $($(package)_qttools_file_name) @@ -22,21 +23,34 @@ $(package)_extra_sources += $($(package)_qttools_file_name) define $(package)_set_vars $(package)_config_opts_release = -release $(package)_config_opts_debug = -debug -$(package)_config_opts += -opensource -confirm-license +$(package)_config_opts += -bindir $(build_prefix)/bin +$(package)_config_opts += -c++11 +$(package)_config_opts += -confirm-license +$(package)_config_opts += -dbus-runtime +$(package)_config_opts += -hostprefix $(build_prefix) +$(package)_config_opts += -no-alsa $(package)_config_opts += -no-audio-backend +$(package)_config_opts += -no-cups +$(package)_config_opts += -no-egl +$(package)_config_opts += -no-eglfs +$(package)_config_opts += -no-feature-style-windowsmobile +$(package)_config_opts += -no-feature-style-windowsce +$(package)_config_opts += -no-freetype +$(package)_config_opts += -no-gif $(package)_config_opts += -no-glib +$(package)_config_opts += -no-gstreamer $(package)_config_opts += -no-icu -$(package)_config_opts += -no-cups $(package)_config_opts += -no-iconv -$(package)_config_opts += -no-gif -$(package)_config_opts += -no-freetype +$(package)_config_opts += -no-kms +$(package)_config_opts += -no-linuxfb +$(package)_config_opts += -no-libudev +$(package)_config_opts += -no-mitshm +$(package)_config_opts += -no-mtdev $(package)_config_opts += -no-nis -$(package)_config_opts += -pch +$(package)_config_opts += -no-pulseaudio +$(package)_config_opts += -no-openvg +$(package)_config_opts += -no-reduce-relocations $(package)_config_opts += -no-qml-debug -$(package)_config_opts += -nomake examples -$(package)_config_opts += -nomake tests -$(package)_config_opts += -no-feature-style-windowsmobile -$(package)_config_opts += -no-feature-style-windowsce $(package)_config_opts += -no-sql-db2 $(package)_config_opts += -no-sql-ibase $(package)_config_opts += -no-sql-oci @@ -46,36 +60,25 @@ $(package)_config_opts += -no-sql-odbc $(package)_config_opts += -no-sql-psql $(package)_config_opts += -no-sql-sqlite $(package)_config_opts += -no-sql-sqlite2 -$(package)_config_opts += -prefix $(host_prefix) -$(package)_config_opts += -hostprefix $(build_prefix) -$(package)_config_opts += -bindir $(build_prefix)/bin -$(package)_config_opts += -c++11 +$(package)_config_opts += -no-use-gold-linker +$(package)_config_opts += -no-xinput2 +$(package)_config_opts += -no-xrender +$(package)_config_opts += -nomake examples +$(package)_config_opts += -nomake tests +$(package)_config_opts += -opensource $(package)_config_opts += -openssl-linked -$(package)_config_opts += -v -$(package)_config_opts += -static -$(package)_config_opts += -silent +$(package)_config_opts += -optimized-qmake +$(package)_config_opts += -pch $(package)_config_opts += -pkg-config +$(package)_config_opts += -prefix $(host_prefix) $(package)_config_opts += -qt-libpng $(package)_config_opts += -qt-libjpeg -$(package)_config_opts += -qt-zlib $(package)_config_opts += -qt-pcre -$(package)_config_opts += -no-pulseaudio -$(package)_config_opts += -no-openvg -$(package)_config_opts += -no-xrender -$(package)_config_opts += -no-alsa -$(package)_config_opts += -no-mtdev -$(package)_config_opts += -no-gstreamer -$(package)_config_opts += -no-mitshm -$(package)_config_opts += -no-kms -$(package)_config_opts += -no-reduce-relocations -$(package)_config_opts += -no-egl -$(package)_config_opts += -no-eglfs -$(package)_config_opts += -no-linuxfb -$(package)_config_opts += -no-xinput2 -$(package)_config_opts += -no-libudev -$(package)_config_opts += -no-use-gold-linker +$(package)_config_opts += -qt-zlib $(package)_config_opts += -reduce-exports -$(package)_config_opts += -optimized-qmake +$(package)_config_opts += -static +$(package)_config_opts += -silent +$(package)_config_opts += -v ifneq ($(build_os),darwin) $(package)_config_opts_darwin = -xplatform macx-clang-linux @@ -119,19 +122,22 @@ define $(package)_extract_cmds tar --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttools_file_name) -C qttools endef + define $(package)_preprocess_cmds sed -i.old "s|updateqm.commands = \$$$$\$$$$LRELEASE|updateqm.commands = $($(package)_extract_dir)/qttools/bin/lrelease|" qttranslations/translations/translations.pro && \ sed -i.old "s/src_plugins.depends = src_sql src_xml src_network/src_plugins.depends = src_xml src_network/" qtbase/src/src.pro && \ sed -i.old "s|X11/extensions/XIproto.h|X11/X.h|" qtbase/src/plugins/platforms/xcb/qxcbxsettings.cpp && \ sed -i.old 's/if \[ "$$$$XPLATFORM_MAC" = "yes" \]; then xspecvals=$$$$(macSDKify/if \[ "$$$$BUILD_ON_MAC" = "yes" \]; then xspecvals=$$$$(macSDKify/' qtbase/configure && \ + sed -i.old 's/CGEventCreateMouseEvent(0, kCGEventMouseMoved, pos, 0)/CGEventCreateMouseEvent(0, kCGEventMouseMoved, pos, kCGMouseButtonLeft)/' qtbase/src/plugins/platforms/cocoa/qcocoacursor.mm && \ mkdir -p qtbase/mkspecs/macx-clang-linux &&\ cp -f qtbase/mkspecs/macx-clang/Info.plist.lib qtbase/mkspecs/macx-clang-linux/ &&\ cp -f qtbase/mkspecs/macx-clang/Info.plist.app qtbase/mkspecs/macx-clang-linux/ &&\ cp -f qtbase/mkspecs/macx-clang/qplatformdefs.h qtbase/mkspecs/macx-clang-linux/ &&\ cp -f $($(package)_patch_dir)/mac-qmake.conf qtbase/mkspecs/macx-clang-linux/qmake.conf && \ - patch -p1 < $($(package)_patch_dir)/fix-xcb-include-order.patch && \ patch -p1 < $($(package)_patch_dir)/mingw-uuidof.patch && \ patch -p1 < $($(package)_patch_dir)/pidlist_absolute.patch && \ + patch -p1 < $($(package)_patch_dir)/fix-xcb-include-order.patch && \ + patch -p1 < $($(package)_patch_dir)/fix_qt_pkgconfig.patch && \ echo "QMAKE_CFLAGS += $($(package)_cflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ echo "QMAKE_CXXFLAGS += $($(package)_cxxflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ echo "QMAKE_LFLAGS += $($(package)_ldflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ diff --git a/depends/patches/qt/fix-xcb-include-order.patch b/depends/patches/qt/fix-xcb-include-order.patch index ae469ea94bff..c7dbebedce83 100644 --- a/depends/patches/qt/fix-xcb-include-order.patch +++ b/depends/patches/qt/fix-xcb-include-order.patch @@ -1,15 +1,15 @@ --- old/qtbase/src/plugins/platforms/xcb/xcb_qpa_lib.pro 2015-03-17 02:06:42.705930685 +0000 +++ new/qtbase/src/plugins/platforms/xcb/xcb_qpa_lib.pro 2015-03-17 02:08:41.281926351 +0000 -@@ -94,8 +94,6 @@ - +@@ -74,8 +74,6 @@ + DEFINES += $$QMAKE_DEFINES_XCB LIBS += $$QMAKE_LIBS_XCB -QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XCB -QMAKE_CFLAGS += $$QMAKE_CFLAGS_XCB - + CONFIG += qpa/genericunixfontdatabase - -@@ -104,7 +102,8 @@ + +@@ -87,7 +85,8 @@ contains(QT_CONFIG, xcb-qt) { DEFINES += XCB_USE_RENDER XCB_DIR = ../../../3rdparty/xcb @@ -18,28 +18,32 @@ + QMAKE_CXXFLAGS += -I$$XCB_DIR/include -I$$XCB_DIR/sysinclude $$QMAKE_CFLAGS_XCB LIBS += -lxcb -L$$OUT_PWD/xcb-static -lxcb-static } else { - LIBS += -lxcb -lxcb-image -lxcb-icccm -lxcb-sync -lxcb-xfixes -lxcb-shm -lxcb-randr -lxcb-shape -lxcb-keysyms + LIBS += -lxcb -lxcb-image -lxcb-icccm -lxcb-sync -lxcb-xfixes -lxcb-shm -lxcb-randr -lxcb-shape -lxcb-keysyms -lxcb-xinerama --- old/qtbase/src/plugins/platforms/xcb/xcb-static/xcb-static.pro 2015-03-17 02:07:04.641929383 +0000 +++ new/qtbase/src/plugins/platforms/xcb/xcb-static/xcb-static.pro 2015-03-17 02:10:15.485922059 +0000 -@@ -8,7 +8,8 @@ - +@@ -9,7 +9,8 @@ + XCB_DIR = ../../../../3rdparty/xcb - + -INCLUDEPATH += $$XCB_DIR/include $$XCB_DIR/include/xcb $$XCB_DIR/sysinclude +QMAKE_CFLAGS += -I$$XCB_DIR/include -I$$XCB_DIR/include/xcb -I$$XCB_DIR/sysinclude +QMAKE_CXXFLAGS += -I$$XCB_DIR/include -I$$XCB_DIR/include/xcb -I$$XCB_DIR/sysinclude - + QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XCB QMAKE_CFLAGS += $$QMAKE_CFLAGS_XCB --- old/qtbase/src/plugins/platforms/xcb/xcb-plugin.pro 2015-07-24 16:02:59.530038830 -0400 +++ new/qtbase/src/plugins/platforms/xcb/xcb-plugin.pro 2015-07-24 16:01:22.106037459 -0400 -@@ -11,3 +11,9 @@ +@@ -6,6 +6,13 @@ qxcbmain.cpp OTHER_FILES += xcb.json README - + +contains(QT_CONFIG, xcb-qt) { + DEFINES += XCB_USE_RENDER + XCB_DIR = ../../../3rdparty/xcb + QMAKE_CFLAGS += -I$$XCB_DIR/include -I$$XCB_DIR/sysinclude $$QMAKE_CFLAGS_XCB + QMAKE_CXXFLAGS += -I$$XCB_DIR/include -I$$XCB_DIR/sysinclude $$QMAKE_CFLAGS_XCB +} ++ + PLUGIN_TYPE = platforms + PLUGIN_CLASS_NAME = QXcbIntegrationPlugin + !equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - diff --git a/depends/patches/qt/fix_qt_pkgconfig.patch b/depends/patches/qt/fix_qt_pkgconfig.patch new file mode 100644 index 000000000000..3772db4f8b80 --- /dev/null +++ b/depends/patches/qt/fix_qt_pkgconfig.patch @@ -0,0 +1,11 @@ +--- old/qtbase/mkspecs/features/qt_module.prf 2016-03-17 02:06:42.705930685 +0000 ++++ new/qtbase/mkspecs/features/qt_module.prf 2016-03-17 02:06:42.705930685 +0000 +@@ -244,7 +244,7 @@ + load(qt_targets) + + # this builds on top of qt_common +-!internal_module:!lib_bundle:if(unix|mingw) { ++unix|mingw { + CONFIG += create_pc + QMAKE_PKGCONFIG_DESTDIR = pkgconfig + host_build: \ diff --git a/src/qt/dash.cpp b/src/qt/dash.cpp index df351750de39..bd37cf4468d8 100644 --- a/src/qt/dash.cpp +++ b/src/qt/dash.cpp @@ -577,6 +577,9 @@ int main(int argc, char *argv[]) // Generate high-dpi pixmaps QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); #endif +#if QT_VERSION >= 0x050600 + QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); +#endif #ifdef Q_OS_MAC QApplication::setAttribute(Qt::AA_DontShowIconsInMenus); #endif From 782745b05b62fb18fb727a6f45b39ef0c6dc64d3 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 20 Jun 2016 13:34:22 +0200 Subject: [PATCH 15/47] Merge #8066: [qa] test_framework: Use different rpc_auth_pair for each node fad1845 [qa] test_framework: Use different rpc_auth_pair for each node (MarcoFalke) --- qa/rpc-tests/test_framework/util.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 89396863c0cc..d268063ad81e 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -170,17 +170,22 @@ def initialize_datadir(dirname, n): datadir = os.path.join(dirname, "node"+str(n)) if not os.path.isdir(datadir): os.makedirs(datadir) + rpc_u, rpc_p = rpc_auth_pair(n) with open(os.path.join(datadir, "dash.conf"), 'w') as f: f.write("regtest=1\n") - f.write("rpcuser=rt\n") - f.write("rpcpassword=rt\n") + f.write("rpcuser=" + rpc_u + "\n") + f.write("rpcpassword=" + rpc_p + "\n") f.write("port="+str(p2p_port(n))+"\n") f.write("rpcport="+str(rpc_port(n))+"\n") f.write("listenonion=0\n") return datadir +def rpc_auth_pair(n): + return 'rpcuser💻' + str(n), 'rpcpass🔑' + str(n) + def rpc_url(i, rpchost=None): - return "http://rt:rt@%s:%d" % (rpchost or '127.0.0.1', rpc_port(i)) + rpc_u, rpc_p = rpc_auth_pair(i) + return "http://%s:%s@%s:%d" % (rpc_u, rpc_p, rpchost or '127.0.0.1', rpc_port(i)) def wait_for_bitcoind_start(process, url, i): ''' From d2c3b7efef9a8cbc43c4ceef8a6760f2064534ab Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 20 Jun 2016 14:09:36 +0200 Subject: [PATCH 16/47] Merge #7687: Stop treating importaddress'ed scripts as change 595b22e Stop treating importaddress'ed scripts as change (Pieter Wuille) --- src/wallet/rpcdump.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 7544bb18821b..7401d8745491 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -168,6 +168,11 @@ void ImportScript(const CScript& script, const string& strLabel, bool isRedeemSc if (!pwalletMain->HaveCScript(script) && !pwalletMain->AddCScript(script)) throw JSONRPCError(RPC_WALLET_ERROR, "Error adding p2sh redeemScript to wallet"); ImportAddress(CBitcoinAddress(CScriptID(script)), strLabel); + } else { + CTxDestination destination; + if (ExtractDestination(script, destination)) { + pwalletMain->SetAddressBook(destination, strLabel, "receive"); + } } } @@ -196,6 +201,8 @@ UniValue importaddress(const UniValue& params, bool fHelp) "4. p2sh (boolean, optional, default=false) Add the P2SH version of the script as well\n" "\nNote: This call can take minutes to complete if rescan is true.\n" "If you have the full public key, you should call importpubkey instead of this.\n" + "\nNote: If you import a non-standard raw script in hex form, outputs sending to it will be treated\n" + "as change, and not show up in many RPCs.\n" "\nExamples:\n" "\nImport a script with rescan\n" + HelpExampleCli("importaddress", "\"myscript\"") + From 573d9314e8b19e9ddd06006d101c689d83999197 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 20 Jun 2016 14:33:26 +0200 Subject: [PATCH 17/47] Merge #7713: Fixes for verify-commits script 1e9aab0 Remove sipa's old revoked key from verify-commits (Peter Todd) 966151e Add README for verify-commits (Peter Todd) 11164ec Remove keys that are no longer used for merging (Peter Todd) 22421fa Remove pointless warning (Peter Todd) 9523e8a Make verify-commits path-independent (Matt Corallo) f7d4a25 Make verify-commits POSIX-compliant (Matt Corallo) --- contrib/verify-commits/README.md | 26 +++++++++++++++++++++ contrib/verify-commits/allow-revsig-commits | 2 -- contrib/verify-commits/gpg.sh | 10 ++++---- contrib/verify-commits/trusted-git-root | 2 +- contrib/verify-commits/trusted-keys | 4 ---- contrib/verify-commits/verify-commits.sh | 19 ++++++--------- 6 files changed, 39 insertions(+), 24 deletions(-) create mode 100644 contrib/verify-commits/README.md diff --git a/contrib/verify-commits/README.md b/contrib/verify-commits/README.md new file mode 100644 index 000000000000..e9e3f65da292 --- /dev/null +++ b/contrib/verify-commits/README.md @@ -0,0 +1,26 @@ +Tooling for verification of PGP signed commits +---------------------------------------------- + +This is an incomplete work in progress, but currently includes a pre-push hook +script (`pre-push-hook.sh`) for maintainers to ensure that their own commits +are PGP signed (nearly always merge commits), as well as a script to verify +commits against a trusted keys list. + + +Using verify-commits.sh safely +------------------------------ + +Remember that you can't use an untrusted script to verify itself. This means +that checking out code, then running `verify-commits.sh` against `HEAD` is +_not_ safe, because the version of `verify-commits.sh` that you just ran could +be backdoored. Instead, you need to use a trusted version of verify-commits +prior to checkout to make sure you're checking out only code signed by trusted +keys: + + git fetch origin && \ + ./contrib/verify-commits/verify-commits.sh origin/master && \ + git checkout origin/master + +Note that the above isn't a good UI/UX yet, and needs significant improvements +to make it more convenient and reduce the chance of errors; pull-reqs +improving this process would be much appreciated. diff --git a/contrib/verify-commits/allow-revsig-commits b/contrib/verify-commits/allow-revsig-commits index 31aeb8f3d38b..e69de29bb2d1 100644 --- a/contrib/verify-commits/allow-revsig-commits +++ b/contrib/verify-commits/allow-revsig-commits @@ -1,2 +0,0 @@ -586a29253dabec3ca0f1ccba9091daabd16b8411 -eddaba7b5692288087a926da5733e86b47274e4e diff --git a/contrib/verify-commits/gpg.sh b/contrib/verify-commits/gpg.sh index 0218b82e11dd..375d71172570 100755 --- a/contrib/verify-commits/gpg.sh +++ b/contrib/verify-commits/gpg.sh @@ -1,8 +1,9 @@ #!/bin/sh -INPUT=$(/dev/null); do case "$LINE" in "[GNUPG:] VALIDSIG "*) @@ -13,10 +14,9 @@ for LINE in $(echo "$INPUT" | gpg --trust-model always "$@" 2>/dev/null); do "[GNUPG:] REVKEYSIG "*) [ "$BITCOIN_VERIFY_COMMITS_ALLOW_REVSIG" != 1 ] && exit 1 while read KEY; do - case "$LINE" in "[GNUPG:] REVKEYSIG ${KEY:24:40} "*) + case "$LINE" in "[GNUPG:] REVKEYSIG ${KEY#????????????????????????} "*) REVSIG=true - GOODREVSIG="[GNUPG:] GOODSIG ${KEY:24:40} " - ;; + GOODREVSIG="[GNUPG:] GOODSIG ${KEY#????????????????????????} " esac done < ./contrib/verify-commits/trusted-keys ;; diff --git a/contrib/verify-commits/trusted-git-root b/contrib/verify-commits/trusted-git-root index 838b8d1ea84b..c60f8ab695e9 100644 --- a/contrib/verify-commits/trusted-git-root +++ b/contrib/verify-commits/trusted-git-root @@ -1 +1 @@ -165e323d851cc87213c7673c6f278e87a6f2e752 +82bcf405f6db1d55b684a1f63a4aabad376cdad7 diff --git a/contrib/verify-commits/trusted-keys b/contrib/verify-commits/trusted-keys index a0d0f82db3f4..5b64a44abfdf 100644 --- a/contrib/verify-commits/trusted-keys +++ b/contrib/verify-commits/trusted-keys @@ -1,7 +1,3 @@ 71A3B16735405025D447E8F274810B012346C9A6 -1F4410F6A89268CE3197A84C57896D2FF8F0B657 -01CDF4627A3B88AAE4A571C87588242FBE38D3A8 -AF8BE07C7049F3A26B239D5325B3083201782B2F -81291FA67D2C379A006A053FEAB5AF94D9E9ABE7 3F1888C6DCA92A6499C4911FDBA1A67379A1A931 32EE5C4C3FA15CCADB46ABE529D4BCB6416F53EC diff --git a/contrib/verify-commits/verify-commits.sh b/contrib/verify-commits/verify-commits.sh index 9ba781008a65..5219331e2e5b 100755 --- a/contrib/verify-commits/verify-commits.sh +++ b/contrib/verify-commits/verify-commits.sh @@ -1,25 +1,19 @@ #!/bin/sh +# Not technically POSIX-compliant due to use of "local", but almost every +# shell anyone uses today supports it, so its probably fine DIR=$(dirname "$0") - -echo "Please verify all commits in the following list are not evil:" -git log "$DIR" +[ "/${DIR#/}" != "$DIR" ] && DIR=$(dirname "$(pwd)/$0") VERIFIED_ROOT=$(cat "${DIR}/trusted-git-root") - -IS_REVSIG_ALLOWED () { - while read LINE; do - [ "$LINE" = "$1" ] && return 0 - done < "${DIR}/allow-revsig-commits" - return 1 -} +REVSIG_ALLOWED=$(cat "${DIR}/allow-revsig-commits") HAVE_FAILED=false IS_SIGNED () { if [ $1 = $VERIFIED_ROOT ]; then return 0; fi - if IS_REVSIG_ALLOWED "$1"; then + if [ "${REVSIG_ALLOWED#*$1}" != "$REVSIG_ALLOWED" ]; then export BITCOIN_VERIFY_COMMITS_ALLOW_REVSIG=1 else export BITCOIN_VERIFY_COMMITS_ALLOW_REVSIG=0 @@ -27,7 +21,8 @@ IS_SIGNED () { if ! git -c "gpg.program=${DIR}/gpg.sh" verify-commit $1 > /dev/null 2>&1; then return 1; fi - local PARENTS=$(git show -s --format=format:%P $1) + local PARENTS + PARENTS=$(git show -s --format=format:%P $1) for PARENT in $PARENTS; do if IS_SIGNED $PARENT > /dev/null; then return 0; From 808936cc302f72046308eceecfecd50f7a8674c0 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 20 Jun 2016 14:45:34 +0200 Subject: [PATCH 18/47] Merge #8179: Evict orphans which are included or precluded by accepted blocks. 54326a6 Increase maximum orphan size to 100,000 bytes. (Gregory Maxwell) 8c99d1b Treat orphans as implicit inv for parents, discard when parents rejected. (Gregory Maxwell) 11cc143 Adds an expiration time for orphan tx. (Gregory Maxwell) db0ffe8 This eliminates the primary leak that causes the orphan map to always grow to its maximum size. (Gregory Maxwell) 1b0bcc5 Track orphan by prev COutPoint rather than prev hash (Pieter Wuille) --- src/net_processing.cpp | 113 ++++++++++++++++++++++++++++++----------- src/net_processing.h | 7 +++ src/test/DoS_tests.cpp | 2 +- src/validation.cpp | 21 ++++++++ src/validation.h | 2 - 5 files changed, 111 insertions(+), 34 deletions(-) diff --git a/src/net_processing.cpp b/src/net_processing.cpp index ff2bfe60d7f7..4254b793c5f7 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -52,12 +52,22 @@ int64_t nTimeBestReceived = 0; // Used only to inform the wallet of when we last extern FeeFilterRounder filterRounder; +struct IteratorComparator +{ + template + bool operator()(const I& a, const I& b) + { + return &(*a) < &(*b); + } +}; + struct COrphanTx { CTransaction tx; NodeId fromPeer; + int64_t nTimeExpire; }; map mapOrphanTransactions GUARDED_BY(cs_main); -map > mapOrphanTransactionsByPrev GUARDED_BY(cs_main);; +map::iterator, IteratorComparator>> mapOrphanTransactionsByPrev GUARDED_BY(cs_main); void EraseOrphansFor(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main); // Internal stuff @@ -521,40 +531,42 @@ bool AddOrphanTx(const CTransaction& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(c // large transaction with a missing parent then we assume // it will rebroadcast it later, after the parent transaction(s) // have been mined or received. - // 10,000 orphans, each of which is at most 5,000 bytes big is - // at most 500 megabytes of orphans: + // 100 orphans, each of which is at most 99,999 bytes big is + // at most 10 megabytes of orphans and somewhat more byprev index (in the worst case): unsigned int sz = tx.GetSerializeSize(SER_NETWORK, CTransaction::CURRENT_VERSION); - if (sz > 5000) + if (sz > MAX_STANDARD_TX_SIZE) { LogPrint("mempool", "ignoring large orphan tx (size: %u, hash: %s)\n", sz, hash.ToString()); return false; } - mapOrphanTransactions[hash].tx = tx; - mapOrphanTransactions[hash].fromPeer = peer; - BOOST_FOREACH(const CTxIn& txin, tx.vin) - mapOrphanTransactionsByPrev[txin.prevout.hash].insert(hash); + auto ret = mapOrphanTransactions.emplace(hash, COrphanTx{tx, peer, GetTime() + ORPHAN_TX_EXPIRE_TIME}); + assert(ret.second); + BOOST_FOREACH(const CTxIn& txin, tx.vin) { + mapOrphanTransactionsByPrev[txin.prevout].insert(ret.first); + } - LogPrint("mempool", "stored orphan tx %s (mapsz %u prevsz %u)\n", hash.ToString(), + LogPrint("mempool", "stored orphan tx %s (mapsz %u outsz %u)\n", hash.ToString(), mapOrphanTransactions.size(), mapOrphanTransactionsByPrev.size()); return true; } -void static EraseOrphanTx(uint256 hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main) +int static EraseOrphanTx(uint256 hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { map::iterator it = mapOrphanTransactions.find(hash); if (it == mapOrphanTransactions.end()) - return; + return 0; BOOST_FOREACH(const CTxIn& txin, it->second.tx.vin) { - map >::iterator itPrev = mapOrphanTransactionsByPrev.find(txin.prevout.hash); + auto itPrev = mapOrphanTransactionsByPrev.find(txin.prevout); if (itPrev == mapOrphanTransactionsByPrev.end()) continue; - itPrev->second.erase(hash); + itPrev->second.erase(it); if (itPrev->second.empty()) mapOrphanTransactionsByPrev.erase(itPrev); } mapOrphanTransactions.erase(it); + return 1; } void EraseOrphansFor(NodeId peer) @@ -566,8 +578,7 @@ void EraseOrphansFor(NodeId peer) map::iterator maybeErase = iter++; // increment to avoid iterator becoming invalid if (maybeErase->second.fromPeer == peer) { - EraseOrphanTx(maybeErase->second.tx.GetHash()); - ++nErased; + nErased += EraseOrphanTx(maybeErase->second.tx.GetHash()); } } if (nErased > 0) LogPrint("mempool", "Erased %d orphan tx from peer %d\n", nErased, peer); @@ -577,6 +588,26 @@ void EraseOrphansFor(NodeId peer) unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { unsigned int nEvicted = 0; + static int64_t nNextSweep; + int64_t nNow = GetTime(); + if (nNextSweep <= nNow) { + // Sweep out expired orphan pool entries: + int nErased = 0; + int64_t nMinExpTime = nNow + ORPHAN_TX_EXPIRE_TIME - ORPHAN_TX_EXPIRE_INTERVAL; + map::iterator iter = mapOrphanTransactions.begin(); + while (iter != mapOrphanTransactions.end()) + { + map::iterator maybeErase = iter++; + if (maybeErase->second.nTimeExpire <= nNow) { + nErased += EraseOrphanTx(maybeErase->second.tx.GetHash()); + } else { + nMinExpTime = std::min(maybeErase->second.nTimeExpire, nMinExpTime); + } + } + // Sweep again 5 minutes after the next entry that expires in order to batch the linear scan. + nNextSweep = nMinExpTime + ORPHAN_TX_EXPIRE_INTERVAL; + if (nErased > 0) LogPrint("mempool", "Erased %d orphan tx due to expiration\n", nErased); + } while (mapOrphanTransactions.size() > nMaxOrphans) { // Evict a random orphan: @@ -1532,7 +1563,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, return true; } - vector vWorkQueue; + deque vWorkQueue; vector vEraseQueue; CTransaction tx; CTxLockRequest txLockRequest; @@ -1614,7 +1645,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, mempool.check(pcoinsTip); connman.RelayTransaction(tx); - vWorkQueue.push_back(inv.hash); + for (unsigned int i = 0; i < tx.vout.size(); i++) { + vWorkQueue.emplace_back(inv.hash, i); + } pfrom->nLastTXTime = GetTime(); @@ -1625,18 +1658,18 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // Recursively process any orphan transactions that depended on this one set setMisbehaving; - for (unsigned int i = 0; i < vWorkQueue.size(); i++) - { - map >::iterator itByPrev = mapOrphanTransactionsByPrev.find(vWorkQueue[i]); + while (!vWorkQueue.empty()) { + auto itByPrev = mapOrphanTransactionsByPrev.find(vWorkQueue.front()); + vWorkQueue.pop_front(); if (itByPrev == mapOrphanTransactionsByPrev.end()) continue; - for (set::iterator mi = itByPrev->second.begin(); + for (auto mi = itByPrev->second.begin(); mi != itByPrev->second.end(); ++mi) { - const uint256& orphanHash = *mi; - const CTransaction& orphanTx = mapOrphanTransactions[orphanHash].tx; - NodeId fromPeer = mapOrphanTransactions[orphanHash].fromPeer; + const CTransaction& orphanTx = (*mi)->second.tx; + const uint256& orphanHash = orphanTx.GetHash(); + NodeId fromPeer = (*mi)->second.fromPeer; bool fMissingInputs2 = false; // Use a dummy CValidationState so someone can't setup nodes to counter-DoS based on orphan // resolution (that is, feeding people an invalid transaction based on LegitTxX in order to get @@ -1650,7 +1683,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, { LogPrint("mempool", " accepted orphan tx %s\n", orphanHash.ToString()); connman.RelayTransaction(orphanTx); - vWorkQueue.push_back(orphanHash); + for (unsigned int i = 0; i < orphanTx.vout.size(); i++) { + vWorkQueue.emplace_back(orphanHash, i); + } vEraseQueue.push_back(orphanHash); } else if (!fMissingInputs2) @@ -1679,13 +1714,29 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } else if (fMissingInputs) { - AddOrphanTx(tx, pfrom->GetId()); + bool fRejectedParents = false; // It may be the case that the orphans parents have all been rejected + BOOST_FOREACH(const CTxIn& txin, tx.vin) { + if (recentRejects->contains(txin.prevout.hash)) { + fRejectedParents = true; + break; + } + } + if (!fRejectedParents) { + BOOST_FOREACH(const CTxIn& txin, tx.vin) { + CInv inv(MSG_TX, txin.prevout.hash); + pfrom->AddInventoryKnown(inv); + if (!AlreadyHave(inv)) pfrom->AskFor(inv); + } + AddOrphanTx(tx, pfrom->GetId()); - // DoS prevention: do not allow mapOrphanTransactions to grow unbounded - unsigned int nMaxOrphanTx = (unsigned int)std::max((int64_t)0, GetArg("-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS)); - unsigned int nEvicted = LimitOrphanTxSize(nMaxOrphanTx); - if (nEvicted > 0) - LogPrint("mempool", "mapOrphan overflow, removed %u tx\n", nEvicted); + // DoS prevention: do not allow mapOrphanTransactions to grow unbounded + unsigned int nMaxOrphanTx = (unsigned int)std::max((int64_t)0, GetArg("-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS)); + unsigned int nEvicted = LimitOrphanTxSize(nMaxOrphanTx); + if (nEvicted > 0) + LogPrint("mempool", "mapOrphan overflow, removed %u tx\n", nEvicted); + } else { + LogPrint("mempool", "not keeping orphan with rejected parents %s\n",tx.GetHash().ToString()); + } } else { assert(recentRejects); recentRejects->insert(tx.GetHash()); diff --git a/src/net_processing.h b/src/net_processing.h index 13fceb55c3f7..9ff1ab8da8f2 100644 --- a/src/net_processing.h +++ b/src/net_processing.h @@ -9,6 +9,13 @@ #include "net.h" #include "validationinterface.h" +/** Default for -maxorphantx, maximum number of orphan transactions kept in memory */ +static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100; +/** Expiration time for orphan transactions in seconds */ +static const int64_t ORPHAN_TX_EXPIRE_TIME = 20 * 60; +/** Minimum time between orphan transactions expire time checks in seconds */ +static const int64_t ORPHAN_TX_EXPIRE_INTERVAL = 5 * 60; + /** Headers download timeout expressed in microseconds * Timeout = base + per_header * (expected number of headers) */ static constexpr int64_t HEADERS_DOWNLOAD_TIMEOUT_BASE = 15 * 60 * 1000000; // 15 minutes diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp index 180ad667a7ef..fb3ff06f478a 100644 --- a/src/test/DoS_tests.cpp +++ b/src/test/DoS_tests.cpp @@ -182,7 +182,7 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans) tx.vout.resize(1); tx.vout[0].nValue = 1*CENT; tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID()); - tx.vin.resize(500); + tx.vin.resize(2777); for (unsigned int j = 0; j < tx.vin.size(); j++) { tx.vin[j].prevout.n = j; diff --git a/src/validation.cpp b/src/validation.cpp index 825a54c7b7ce..15c2f8419d6b 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2078,6 +2078,7 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd CCheckQueueControl control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL); + std::vector vOrphanErase; std::vector prevheights; CAmount nFees = 0; int nInputs = 0; @@ -2117,6 +2118,17 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd prevheights[j] = view.AccessCoin(tx.vin[j].prevout).nHeight; } + // Which orphan pool entries must we evict? + for (size_t j = 0; j < tx.vin.size(); j++) { + auto itByPrev = mapOrphanTransactionsByPrev.find(tx.vin[j].prevout); + if (itByPrev == mapOrphanTransactionsByPrev.end()) continue; + for (auto mi = itByPrev->second.begin(); mi != itByPrev->second.end(); ++mi) { + const CTransaction& orphanTx = (*mi)->second.tx; + const uint256& orphanHash = orphanTx.GetHash(); + vOrphanErase.push_back(orphanHash); + } + } + if (!SequenceLocks(tx, nLockTimeFlags, &prevheights, *pindex)) { return state.DoS(100, error("%s: contains a non-BIP68-final transaction", __func__), REJECT_INVALID, "bad-txns-nonfinal"); @@ -2302,6 +2314,15 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd GetMainSignals().UpdatedTransaction(hashPrevBestCoinBase); hashPrevBestCoinBase = block.vtx[0].GetHash(); + // Erase orphan transactions include or precluded by this block + if (vOrphanErase.size()) { + int nErased = 0; + BOOST_FOREACH(uint256 &orphanHash, vOrphanErase) { + nErased += EraseOrphanTx(orphanHash); + } + LogPrint("mempool", "Erased %d orphan tx included or conflicted by block\n", nErased); + } + int64_t nTime6 = GetTimeMicros(); nTimeCallbacks += nTime6 - nTime5; LogPrint("bench", " - Callbacks: %.2fms [%.2fs]\n", 0.001 * (nTime6 - nTime5), nTimeCallbacks * 0.000001); diff --git a/src/validation.h b/src/validation.h index 7c58651438b7..683121a2a651 100644 --- a/src/validation.h +++ b/src/validation.h @@ -62,8 +62,6 @@ static const CAmount DEFAULT_TRANSACTION_MAXFEE = 0.2 * COIN; // "smallest denom static const CAmount HIGH_TX_FEE_PER_KB = 0.01 * COIN; //! -maxtxfee will warn if called with a higher fee than this amount (in duffs) static const CAmount HIGH_MAX_TX_FEE = 100 * HIGH_TX_FEE_PER_KB; -/** Default for -maxorphantx, maximum number of orphan transactions kept in memory */ -static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100; /** Default for -limitancestorcount, max number of in-mempool ancestors */ static const unsigned int DEFAULT_ANCESTOR_LIMIT = 25; /** Default for -limitancestorsize, maximum kilobytes of tx + all in-mempool ancestors */ From 36aa554584dcf3c2178f49bfe70faaa24d1e4e9e Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Sat, 16 Sep 2017 22:40:07 +0200 Subject: [PATCH 19/47] Temporarily fix build error cased by out-of-order backporting Can be removed when we catch up with backporting. You'll notice it's time for this when you get conflicts while merging the affected backported PR. --- src/net_processing.cpp | 17 ++++++++++++++++- src/validation.cpp | 27 ++++++++++++++++++--------- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 4254b793c5f7..f6f8176be31c 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -520,6 +520,21 @@ void UnregisterNodeSignals(CNodeSignals& nodeSignals) // mapOrphanTransactions // +// TODO This is a temporary solution while backporting Bitcoin 0.13 changes into Dash +// See caller of this method +void LoopMapOrphanTransactionsByPrev(const CTransaction &tx, std::vector &vOrphanErase) +{ + for (size_t j = 0; j < tx.vin.size(); j++) { + auto itByPrev = mapOrphanTransactionsByPrev.find(tx.vin[j].prevout); + if (itByPrev == mapOrphanTransactionsByPrev.end()) continue; + for (auto mi = itByPrev->second.begin(); mi != itByPrev->second.end(); ++mi) { + const CTransaction& orphanTx = (*mi)->second.tx; + const uint256& orphanHash = orphanTx.GetHash(); + vOrphanErase.push_back(orphanHash); + } + } +} + bool AddOrphanTx(const CTransaction& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { uint256 hash = tx.GetHash(); @@ -551,7 +566,7 @@ bool AddOrphanTx(const CTransaction& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(c return true; } -int static EraseOrphanTx(uint256 hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main) +int EraseOrphanTx(uint256 hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { map::iterator it = mapOrphanTransactions.find(hash); if (it == mapOrphanTransactions.end()) diff --git a/src/validation.cpp b/src/validation.cpp index 15c2f8419d6b..37295058ca2e 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -102,6 +102,10 @@ CTxMemPool mempool(::minRelayTxFee); FeeFilterRounder filterRounder(::minRelayTxFee); map mapRejectedBlocks GUARDED_BY(cs_main); +// TODO temporary hack for backporting +void LoopMapOrphanTransactionsByPrev(const CTransaction &tx, std::vector &vOrphanErase); +int EraseOrphanTx(uint256 hash); + /** * Returns true if there are nRequired or more blocks of minVersion or above * in the last Consensus::Params::nMajorityWindow blocks, starting at pstart and going backwards. @@ -2119,15 +2123,20 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd } // Which orphan pool entries must we evict? - for (size_t j = 0; j < tx.vin.size(); j++) { - auto itByPrev = mapOrphanTransactionsByPrev.find(tx.vin[j].prevout); - if (itByPrev == mapOrphanTransactionsByPrev.end()) continue; - for (auto mi = itByPrev->second.begin(); mi != itByPrev->second.end(); ++mi) { - const CTransaction& orphanTx = (*mi)->second.tx; - const uint256& orphanHash = orphanTx.GetHash(); - vOrphanErase.push_back(orphanHash); - } - } + //for (size_t j = 0; j < tx.vin.size(); j++) { + // auto itByPrev = mapOrphanTransactionsByPrev.find(tx.vin[j].prevout); + // if (itByPrev == mapOrphanTransactionsByPrev.end()) continue; + // for (auto mi = itByPrev->second.begin(); mi != itByPrev->second.end(); ++mi) { + // const CTransaction& orphanTx = (*mi)->second.tx; + // const uint256& orphanHash = orphanTx.GetHash(); + // vOrphanErase.push_back(orphanHash); + // } + //} + // TODO This is a temporary solution while backporting Bitcoin 0.13 changes into Dash + // It is needed because the splitting of main.cpp into validation.cpp/net_processing.cpp was done out of order + // When we catch up with backporting, the above loop will be at the correct place in net_processing.cpp + // and this hack can be removed + LoopMapOrphanTransactionsByPrev(tx, vOrphanErase); if (!SequenceLocks(tx, nLockTimeFlags, &prevheights, *pindex)) { return state.DoS(100, error("%s: contains a non-BIP68-final transaction", __func__), From c2dabf8bd84965ea62ed8eb5e1059caccbd49f6d Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 20 Jun 2016 15:21:21 +0200 Subject: [PATCH 20/47] Merge #8220: Stop trimming when mapTx is empty ad0752e Stop trimming when mapTx is empty (Pieter Wuille) --- src/txmempool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 36b13918be82..06623908bbcd 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -1219,7 +1219,7 @@ void CTxMemPool::TrimToSize(size_t sizelimit, std::vector* pvNoSpends unsigned nTxnRemoved = 0; CFeeRate maxFeeRateRemoved(0); - while (DynamicMemoryUsage() > sizelimit) { + while (!mapTx.empty() && DynamicMemoryUsage() > sizelimit) { indexed_transaction_set::index::type::iterator it = mapTx.get().begin(); // We set the new mempool min fee to the feerate of the removed set, plus the From e2bcf8ae0cd2d11bc69cbc1bc37590b1c24f1326 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 21 Jun 2016 10:24:09 +0200 Subject: [PATCH 21/47] Merge #8216: [qa] assert 'changePosition out of bounds' fa58f94 [qa] pull-tester: Start longest test first (MarcoFalke) fa3b379 [qa] pull-tester: Fix assertion and check for run_parallel (MarcoFalke) fa32465 [qa] fundrawtransaction: Create get_unspent() (MarcoFalke) fa8ce3b [qa] assert 'changePosition out of bounds' (MarcoFalke) --- qa/pull-tester/rpc-tests.py | 7 ++- qa/rpc-tests/fundrawtransaction.py | 99 ++++++++---------------------- 2 files changed, 29 insertions(+), 77 deletions(-) diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index ab8cea220d53..92ded914725b 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -110,6 +110,8 @@ #Tests testScripts = [ + # longest test should go first, to favor running tests in parallel + 'p2p-fullblocktest.py', # NOTE: needs dash_hash to pass 'walletbackup.py', 'bip68-112-113-p2p.py', 'wallet.py', @@ -139,7 +141,6 @@ 'timestampindex.py', 'spentindex.py', 'decodescript.py', - 'p2p-fullblocktest.py', # NOTE: needs dash_hash to pass 'blockchain.py', 'disablewallet.py', 'sendheaders.py', # NOTE: needs dash_hash to pass @@ -206,7 +207,7 @@ def runtests(): if coverage: flags.append(coverage.flag) - if len(test_list) > 1: + if len(test_list) > 1 and run_parallel > 1: # Populate cache subprocess.check_output([RPC_TESTS_DIR + 'create_cache.py'] + flags) @@ -270,7 +271,7 @@ def get_next(self): log_stdout, log_stderr)) if not self.jobs: - raise IndexError('%s from empty list' % __name__) + raise IndexError('pop from empty list') while True: # Return first proc that finishes time.sleep(.5) diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py index 4ceb5b0867d3..ae3e1fa99470 100755 --- a/qa/rpc-tests/fundrawtransaction.py +++ b/qa/rpc-tests/fundrawtransaction.py @@ -6,7 +6,14 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -# Create one-input, one-output, no-fee transaction: + +def get_unspent(listunspent, amount): + for utx in listunspent: + if utx['amount'] == amount: + return utx + raise AssertionError('Could not find unspent with amount={}'.format(amount)) + + class RawTransactionsTest(BitcoinTestFramework): def __init__(self): @@ -71,7 +78,7 @@ def run_test(self): rawtxfund = self.nodes[2].fundrawtransaction(rawtx) fee = rawtxfund['fee'] dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) - assert(len(dec_tx['vin']) > 0) #test if we have enought inputs + assert(len(dec_tx['vin']) > 0) #test that we have enough inputs ############################## # simple test with two coins # @@ -123,14 +130,7 @@ def run_test(self): ######################################################################### # test a fundrawtransaction with a VIN greater than the required amount # ######################################################################### - utx = False - listunspent = self.nodes[2].listunspent() - for aUtx in listunspent: - if aUtx['amount'] == 50: - utx = aUtx - break - - assert(utx!=False) + utx = get_unspent(self.nodes[2].listunspent(), 50) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}] outputs = { self.nodes[0].getnewaddress() : 10 } @@ -151,14 +151,7 @@ def run_test(self): ##################################################################### # test a fundrawtransaction with which will not get a change output # ##################################################################### - utx = False - listunspent = self.nodes[2].listunspent() - for aUtx in listunspent: - if aUtx['amount'] == 50: - utx = aUtx - break - - assert(utx!=False) + utx = get_unspent(self.nodes[2].listunspent(), 50) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}] outputs = { self.nodes[0].getnewaddress() : Decimal(50) - fee - feeTolerance } @@ -180,14 +173,7 @@ def run_test(self): #################################################### # test a fundrawtransaction with an invalid option # #################################################### - utx = False - listunspent = self.nodes[2].listunspent() - for aUtx in listunspent: - if aUtx['amount'] == 50: - utx = aUtx - break - - assert_equal(utx!=False, True) + utx = get_unspent(self.nodes[2].listunspent(), 50) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']} ] outputs = { self.nodes[0].getnewaddress() : Decimal(40) } @@ -205,14 +191,7 @@ def run_test(self): ############################################################ # test a fundrawtransaction with an invalid change address # ############################################################ - utx = False - listunspent = self.nodes[2].listunspent() - for aUtx in listunspent: - if aUtx['amount'] == 50: - utx = aUtx - break - - assert_equal(utx!=False, True) + utx = get_unspent(self.nodes[2].listunspent(), 50) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']} ] outputs = { self.nodes[0].getnewaddress() : Decimal(40) } @@ -227,18 +206,10 @@ def run_test(self): assert("changeAddress must be a valid dash address" in e.error['message']) - ############################################################ # test a fundrawtransaction with a provided change address # ############################################################ - utx = False - listunspent = self.nodes[2].listunspent() - for aUtx in listunspent: - if aUtx['amount'] == 50: - utx = aUtx - break - - assert_equal(utx!=False, True) + utx = get_unspent(self.nodes[2].listunspent(), 50) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']} ] outputs = { self.nodes[0].getnewaddress() : Decimal(40) } @@ -247,24 +218,22 @@ def run_test(self): assert_equal(utx['txid'], dec_tx['vin'][0]['txid']) change = self.nodes[2].getnewaddress() + try: + rawtxfund = self.nodes[2].fundrawtransaction(rawtx, {'changeAddress': change, 'changePosition': 2}) + except JSONRPCException as e: + assert('changePosition out of bounds' == e.error['message']) + else: + assert(False) rawtxfund = self.nodes[2].fundrawtransaction(rawtx, {'changeAddress': change, 'changePosition': 0}) dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) out = dec_tx['vout'][0]; assert_equal(change, out['scriptPubKey']['addresses'][0]) - ######################################################################### # test a fundrawtransaction with a VIN smaller than the required amount # ######################################################################### - utx = False - listunspent = self.nodes[2].listunspent() - for aUtx in listunspent: - if aUtx['amount'] == 10: - utx = aUtx - break - - assert(utx!=False) + utx = get_unspent(self.nodes[2].listunspent(), 10) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}] outputs = { self.nodes[0].getnewaddress() : 10 } @@ -299,17 +268,8 @@ def run_test(self): ########################################### # test a fundrawtransaction with two VINs # ########################################### - utx = False - utx2 = False - listunspent = self.nodes[2].listunspent() - for aUtx in listunspent: - if aUtx['amount'] == 10: - utx = aUtx - if aUtx['amount'] == 50: - utx2 = aUtx - - - assert(utx!=False) + utx = get_unspent(self.nodes[2].listunspent(), 10) + utx2 = get_unspent(self.nodes[2].listunspent(), 50) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']},{'txid' : utx2['txid'], 'vout' : utx2['vout']} ] outputs = { self.nodes[0].getnewaddress() : 60 } @@ -341,17 +301,8 @@ def run_test(self): ######################################################### # test a fundrawtransaction with two VINs and two vOUTs # ######################################################### - utx = False - utx2 = False - listunspent = self.nodes[2].listunspent() - for aUtx in listunspent: - if aUtx['amount'] == 10: - utx = aUtx - if aUtx['amount'] == 50: - utx2 = aUtx - - - assert(utx!=False) + utx = get_unspent(self.nodes[2].listunspent(), 10) + utx2 = get_unspent(self.nodes[2].listunspent(), 50) inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']},{'txid' : utx2['txid'], 'vout' : utx2['vout']} ] outputs = { self.nodes[0].getnewaddress() : 60, self.nodes[0].getnewaddress() : 10 } From 381629c757677eed46b2328a0518b48bbd0926e2 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 21 Jun 2016 16:32:20 +0200 Subject: [PATCH 22/47] Merge #8229: [Doc] Update OS X build notes for 10.11 SDK e5a680d [Doc] Update OS X build notes for 10.11 SDK (fanquake) --- doc/{README_osx.txt => README_osx.md} | 28 +++++++++++++-------------- doc/build-osx.md | 8 +++++--- doc/release-process.md | 12 +++--------- 3 files changed, 22 insertions(+), 26 deletions(-) rename doc/{README_osx.txt => README_osx.md} (81%) diff --git a/doc/README_osx.txt b/doc/README_osx.md similarity index 81% rename from doc/README_osx.txt rename to doc/README_osx.md index c13efaa145c8..aed3cd97e1ec 100644 --- a/doc/README_osx.txt +++ b/doc/README_osx.md @@ -1,21 +1,19 @@ Deterministic OS X Dmg Notes. Working OS X DMGs are created in Linux by combining a recent clang, -the Apple's binutils (ld, ar, etc), and DMG authoring tools. +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 OS X. A pre-compiled version of 3.2 is used because it was not -available in the Precise repositories at the time this work was started. In the -future, it can be switched to use system packages instead. +when building for OS X. 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: -https://github.com/mingwandroid/toolchain4 +[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. @@ -29,16 +27,19 @@ 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 6.1.1 dmg: -https://developer.apple.com/devcenter/download.action?path=/Developer_Tools/xcode_6.1.1/xcode_6.1.1.dmg +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). 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.9.sdk +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, mount the dmg in OS X, then create it with: - $ tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.9.sdk.tar.gz MacOSX10.9.sdk - +``` + $ tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.11.sdk.tar.gz 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 @@ -48,15 +49,14 @@ 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: -https://raw.githubusercontent.com/theuni/osx-cross-depends/master/patches/cdrtools/genisoimage.diff +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: https://github.com/theuni/libdmg-hfsplus . +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. @@ -77,6 +77,6 @@ build process to remain somewhat deterministic. Here's how it works: 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. + 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/build-osx.md b/doc/build-osx.md index 94d442f174f0..e6b52c6e5573 100644 --- a/doc/build-osx.md +++ b/doc/build-osx.md @@ -5,11 +5,13 @@ The built-in one is located in `/Applications/Utilities/Terminal.app`. Preparation ----------- -Download and install [Xcode](https://developer.apple.com/xcode/download). +Install the OS X command line tools: -Once installed, run `xcode-select --install` to install the OS X command line tools. +`xcode-select --install` -Install [Homebrew](http://brew.sh). +When the popup appears, click `Install`. + +Then install [Homebrew](http://brew.sh). Dependencies ---------------------- diff --git a/doc/release-process.md b/doc/release-process.md index 6d76e1f6b394..fb8f7d1b2f8e 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -1,7 +1,7 @@ Release Process ==================== -* Update translations, see [translation_process.md](https://github.com/dashpay/dash/blob/master/doc/translation_process.md#syncing-with-transifex) +* Update translations (ping wumpus on IRC) see [translation_process.md](https://github.com/dashpay/dash/blob/master/doc/translation_process.md#synchronising-translations). * Update hardcoded [seeds](/contrib/seeds) * * * @@ -53,7 +53,7 @@ Check out the source code in the following directory hierarchy. git pull popd - Ensure gitian-builder is up-to-date to take advantage of new caching features (`e9741525c` or later is recommended). + Ensure gitian-builder is up-to-date: pushd ./gitian-builder git pull @@ -64,13 +64,7 @@ Check out the source code in the following directory hierarchy. wget -P inputs https://bitcoincore.org/cfields/osslsigncode-Backports-to-1.7.1.patch wget -P inputs http://downloads.sourceforge.net/project/osslsigncode/osslsigncode/osslsigncode-1.7.1.tar.gz - Register and download the Apple SDK: see [OS X readme](README_osx.txt) for details. - - https://developer.apple.com/devcenter/download.action?path=/Developer_Tools/xcode_6.1.1/xcode_6.1.1.dmg - - Using a Mac, create a tarball for the 10.9 SDK and copy it to the inputs directory: - - tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.9.sdk.tar.gz MacOSX10.9.sdk + Create the OS X SDK tarball, see the [OS X readme](README_osx.md) for details, and copy it into the inputs directory. ### Optional: Seed the Gitian sources cache and offline git repositories From e51f505449b89637b333cf4ed55b1666fb39469f Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 22 Jun 2016 08:48:23 +0200 Subject: [PATCH 23/47] Merge #8222: Enable mempool consistency checks in unit tests 3775ff9 Enable mempool consistency checks in unit tests (Pieter Wuille) --- src/test/test_dash.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/test_dash.cpp b/src/test/test_dash.cpp index a4484441df2c..6cca19305ef3 100644 --- a/src/test/test_dash.cpp +++ b/src/test/test_dash.cpp @@ -59,6 +59,7 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha pathTemp = GetTempPath() / strprintf("test_dash_%lu_%i", (unsigned long)GetTime(), (int)(GetRand(100000))); boost::filesystem::create_directories(pathTemp); mapArgs["-datadir"] = pathTemp.string(); + mempool.setSanityCheck(1.0); pblocktree = new CBlockTreeDB(1 << 20, true); pcoinsdbview = new CCoinsViewDB(1 << 23, true); pcoinsTip = new CCoinsViewCache(pcoinsdbview); From b7b5d6ea7b252bce651d391bfef6d6aa8f69bb44 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 23 Jun 2016 12:58:08 +0200 Subject: [PATCH 24/47] Merge #8246: trivial: capitalize BIP32 in option help a1c92c2 trivial: capitalize BIP32 in option help (Wladimir J. van der Laan) --- src/wallet/wallet.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 078c0323b996..4e81a47891a5 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4526,9 +4526,9 @@ std::string CWallet::GetWalletHelpString(bool showDebug) strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), DEFAULT_SEND_FREE_TRANSACTIONS)); strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), DEFAULT_SPEND_ZEROCONF_CHANGE)); strUsage += HelpMessageOpt("-txconfirmtarget=", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET)); - strUsage += HelpMessageOpt("-usehd", _("Use hierarchical deterministic key generation (HD) after bip39/bip44. Only has effect during wallet creation/first start") + " " + strprintf(_("(default: %u)"), DEFAULT_USE_HD_WALLET)); + strUsage += HelpMessageOpt("-usehd", _("Use hierarchical deterministic key generation (HD) after BIP39/BIP44. Only has effect during wallet creation/first start") + " " + strprintf(_("(default: %u)"), DEFAULT_USE_HD_WALLET)); strUsage += HelpMessageOpt("-mnemonic", _("User defined mnemonic for HD wallet (bip39). Only has effect during wallet creation/first start (default: randomly generated)")); - strUsage += HelpMessageOpt("-mnemonicpassphrase", _("User defined mnemonic passphrase for HD wallet (bip39). Only has effect during wallet creation/first start (default: empty string)")); + strUsage += HelpMessageOpt("-mnemonicpassphrase", _("User defined mnemonic passphrase for HD wallet (BIP39). Only has effect during wallet creation/first start (default: empty string)")); strUsage += HelpMessageOpt("-hdseed", _("User defined seed for HD wallet (should be in hex). Only has effect during wallet creation/first start (default: randomly generated)")); strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format on startup")); strUsage += HelpMessageOpt("-wallet=", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), DEFAULT_WALLET_DAT)); From 5a844dcc493327adac01da95f60619c8171dd96a Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Fri, 24 Jun 2016 12:38:43 +0200 Subject: [PATCH 25/47] Merge #8254: [doc] Add OSX ZMQ requirement to QA readme d241487 [doc] Add OS X ZMQ requirement to QA readme (fanquake) --- qa/README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/qa/README.md b/qa/README.md index c299561b3838..3f1cb9c8fc40 100644 --- a/qa/README.md +++ b/qa/README.md @@ -16,6 +16,12 @@ The python3-zmq library is required. On Ubuntu or Debian it can be installed via sudo apt-get install python3-zmq ``` +OS X +------ +``` +pip3 install pyzmq +``` + Running tests ============= @@ -36,7 +42,7 @@ Run all possible tests with qa/pull-tester/rpc-tests.py -extended By default, tests will be run in parallel if you want to specify how many -tests should be run in parallel, append `-paralell=n` (default n=4). +tests should be run in parallel, append `-parallel=n` (default n=4). If you want to create a basic coverage report for the rpc test suite, append `--coverage`. From 3f7273d0091b9aa5a33dcd9c1dd9e00a9a8955d6 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 24 Jun 2016 13:47:54 +0200 Subject: [PATCH 26/47] Merge #8256: BUG: bitcoin-qt crash d7828ab check that transactionView->selectionModel()->selectedRows(0) exists (fsb4000) --- src/qt/transactionview.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index 6e39bdb25d19..44a1b74f2676 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -404,6 +404,8 @@ void TransactionView::contextualMenu(const QPoint &point) { QModelIndex index = transactionView->indexAt(point); QModelIndexList selection = transactionView->selectionModel()->selectedRows(0); + if (selection.empty()) + return; // check if transaction can be abandoned, disable context menu action in case it doesn't uint256 hash; From f1f13903381bde9635c27ca3cb2488860eb0bd68 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 24 Jun 2016 18:12:17 +0200 Subject: [PATCH 27/47] Merge #8252: [trivial] Add aarch64 to depends .gitignore f70bcfc [trivial] Add aarch64 to depends .gitignore (fanquake) --- depends/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/depends/.gitignore b/depends/.gitignore index 1f163897b9ef..3cb4b9ac1555 100644 --- a/depends/.gitignore +++ b/depends/.gitignore @@ -7,3 +7,4 @@ x86_64* i686* mips* arm* +aarch64* From 7f5b8f1e1d9cc57238cc208a2b3cebde759d4f5a Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 27 Jun 2016 16:07:14 +0200 Subject: [PATCH 28/47] Merge #8258: RPC: Hide softfork if timeout is 0 409f833 RPC: Hide softfork if timeout is 0 (jl2012) --- src/rpc/blockchain.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index f1675b19b3e2..e2bd0dc63610 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1000,6 +1000,15 @@ static UniValue BIP9SoftForkDesc(const Consensus::Params& consensusParams, Conse return rv; } +void BIP9SoftForkDescPushBack(UniValue& bip9_softforks, const std::string &name, const Consensus::Params& consensusParams, Consensus::DeploymentPos id) +{ + // Deployments with timeout value of 0 are hidden. + // A timeout value of 0 guarantees a softfork will never be activated. + // This is used when softfork codes are merged without specifying the deployment schedule. + if (consensusParams.vDeployments[id].nTimeout > 0) + bip9_softforks.push_back(Pair(name, BIP9SoftForkDesc(consensusParams, id))); +} + UniValue getblockchaininfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) @@ -1033,7 +1042,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) " ],\n" " \"bip9_softforks\": { (object) status of BIP9 softforks in progress\n" " \"xxxx\" : { (string) name of the softfork\n" - " \"status\": \"xxxx\", (string) one of \"defined\", \"started\", \"lockedin\", \"active\", \"failed\"\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 soft fork\n" " \"startTime\": 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" @@ -1065,8 +1074,8 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams)); softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams)); softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams)); - bip9_softforks.push_back(Pair("csv", BIP9SoftForkDesc(consensusParams, Consensus::DEPLOYMENT_CSV))); - bip9_softforks.push_back(Pair("dip0001", BIP9SoftForkDesc(consensusParams, Consensus::DEPLOYMENT_DIP0001))); + BIP9SoftForkDescPushBack(bip9_softforks, "csv", consensusParams, Consensus::DEPLOYMENT_CSV); + BIP9SoftForkDescPushBack(bip9_softforks, "dip0001", consensusParams, Consensus::DEPLOYMENT_DIP0001); obj.push_back(Pair("softforks", softforks)); obj.push_back(Pair("bip9_softforks", bip9_softforks)); From 17aa23c884233c58540a2423230b44f0220aca46 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 28 Jun 2016 16:05:56 +0200 Subject: [PATCH 29/47] Merge #8261: The bit field is shown only when status is "started" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2129fce The bit field is shown only when status is "started" (Pavel Janík) --- src/rpc/blockchain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index e2bd0dc63610..cf7307861281 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1043,7 +1043,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) " \"bip9_softforks\": { (object) status of BIP9 softforks in progress\n" " \"xxxx\" : { (string) name of the softfork\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 soft fork\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" " \"timeout\": xx (numeric) the median time past of a block at which the deployment is considered failed if not yet locked in\n" " }\n" From ba6b3697812e8511a3079d41f183225d05915671 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 29 Jun 2016 10:41:23 +0200 Subject: [PATCH 30/47] Merge #8281: qt: Remove client name from debug window a7897c0 qt: Remove client name from debug window (Wladimir J. van der Laan) --- src/qt/clientmodel.cpp | 5 --- src/qt/clientmodel.h | 1 - src/qt/forms/debugwindow.ui | 79 +++++++++++++------------------------ src/qt/rpcconsole.cpp | 1 - 4 files changed, 28 insertions(+), 58 deletions(-) diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 5d98dc7a9385..48f38f0fd144 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -282,11 +282,6 @@ bool ClientModel::isReleaseVersion() const return CLIENT_VERSION_IS_RELEASE; } -QString ClientModel::clientName() const -{ - return QString::fromStdString(CLIENT_NAME); -} - QString ClientModel::formatClientStartupTime() const { return QDateTime::fromTime_t(nClientStartupTime).toString(); diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index 457bdc8c3726..c29bace26d26 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -82,7 +82,6 @@ class ClientModel : public QObject QString formatFullVersion() const; QString formatSubVersion() const; bool isReleaseVersion() const; - QString clientName() const; QString formatClientStartupTime() const; QString dataDir() const; diff --git a/src/qt/forms/debugwindow.ui b/src/qt/forms/debugwindow.ui index 40a4f85cfffe..cd60a440aae5 100644 --- a/src/qt/forms/debugwindow.ui +++ b/src/qt/forms/debugwindow.ui @@ -41,36 +41,13 @@ - - - Client name - - - - - - - IBeamCursor - - - N/A - - - Qt::PlainText - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - Client version - + IBeamCursor @@ -86,7 +63,7 @@ - + User Agent @@ -96,7 +73,7 @@ - + IBeamCursor @@ -112,7 +89,7 @@ - + Using BerkeleyDB version @@ -122,7 +99,7 @@ - + IBeamCursor @@ -138,14 +115,14 @@ - + Datadir - + IBeamCursor @@ -164,14 +141,14 @@ - + Startup time - + IBeamCursor @@ -187,7 +164,7 @@ - + @@ -200,14 +177,14 @@ - + Name - + IBeamCursor @@ -223,14 +200,14 @@ - + Number of connections - + IBeamCursor @@ -246,21 +223,21 @@ - + Number of Masternodes - + N/A - + @@ -273,14 +250,14 @@ - + Current number of blocks - + IBeamCursor @@ -296,14 +273,14 @@ - + Last block time - + IBeamCursor @@ -319,7 +296,7 @@ - + @@ -332,14 +309,14 @@ - + Current number of transactions - + IBeamCursor @@ -355,14 +332,14 @@ - + Memory usage - + IBeamCursor @@ -378,7 +355,7 @@ - + 3 @@ -418,7 +395,7 @@ - + Qt::Vertical diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index be86e3bd3c71..12039b4e612c 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -481,7 +481,6 @@ void RPCConsole::setClientModel(ClientModel *model) // Provide initial values ui->clientVersion->setText(model->formatFullVersion()); ui->clientUserAgent->setText(model->formatSubVersion()); - ui->clientName->setText(model->clientName()); ui->dataDir->setText(model->dataDir()); ui->startupTime->setText(model->formatClientStartupTime()); ui->networkName->setText(QString::fromStdString(Params().NetworkIDString())); From dcf36df67546602505062235339a455f3b3be026 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 1 Jul 2016 09:52:13 +0200 Subject: [PATCH 31/47] Merge #8285: windows: Add testnet link to installer 975a41d windows: Add testnet icon for testnet link (Wladimir J. van der Laan) 0ce8e99 windows: Add testnet link to installer (Wladimir J. van der Laan) --- share/setup.nsi.in | 2 ++ src/Makefile.qt.include | 1 + src/qt/res/dash-qt-res.rc | 1 + src/qt/res/icons/bitcoin_testnet.ico | Bin 0 -> 57251 bytes 4 files changed, 4 insertions(+) create mode 100644 src/qt/res/icons/bitcoin_testnet.ico diff --git a/share/setup.nsi.in b/share/setup.nsi.in index e8becf25231c..05cec6aca2cc 100644 --- a/share/setup.nsi.in +++ b/share/setup.nsi.in @@ -92,6 +92,7 @@ Section -post SEC0001 !insertmacro MUI_STARTMENU_WRITE_BEGIN Application CreateDirectory $SMPROGRAMS\$StartMenuGroup CreateShortcut "$SMPROGRAMS\$StartMenuGroup\$(^Name).lnk" $INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@ + CreateShortcut "$SMPROGRAMS\$StartMenuGroup\@PACKAGE_NAME@ (testnet, @WINDOWS_BITS@-bit).lnk" "$INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@" "-testnet" "$INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@" 1 CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall $(^Name).lnk" $INSTDIR\uninstall.exe !insertmacro MUI_STARTMENU_WRITE_END WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayName "$(^Name)" @@ -139,6 +140,7 @@ Section -un.post UNSEC0001 DeleteRegKey HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Uninstall $(^Name).lnk" Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\$(^Name).lnk" + Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\@PACKAGE_NAME@ (testnet, @WINDOWS_BITS@-bit).lnk" Delete /REBOOTOK "$SMSTARTUP\Dash.lnk" Delete /REBOOTOK $INSTDIR\uninstall.exe Delete /REBOOTOK $INSTDIR\debug.log diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index dbdf3fcea4b2..be3bef111429 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -169,6 +169,7 @@ BITCOIN_QT_H = \ RES_ICONS = \ qt/res/icons/bitcoin.ico \ + qt/res/icons/bitcoin_testnet.ico \ qt/res/icons/bitcoin.png \ qt/res/icons/chevron.png \ qt/res/icons/warning.png \ diff --git a/src/qt/res/dash-qt-res.rc b/src/qt/res/dash-qt-res.rc index 5922a9bd55e5..70220d93ef55 100644 --- a/src/qt/res/dash-qt-res.rc +++ b/src/qt/res/dash-qt-res.rc @@ -1,4 +1,5 @@ IDI_ICON1 ICON DISCARDABLE "icons/bitcoin.ico" +IDI_ICON2 ICON DISCARDABLE "icons/bitcoin_testnet.ico" #include // needed for VERSIONINFO #include "../../clientversion.h" // holds the needed client version information diff --git a/src/qt/res/icons/bitcoin_testnet.ico b/src/qt/res/icons/bitcoin_testnet.ico new file mode 100644 index 0000000000000000000000000000000000000000..909194ecd2e10985bbca35c3cd26fd1adb4730b8 GIT binary patch literal 57251 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 N250BL5H*Z+s*3%&l;+rD=4 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 Date: Mon, 4 Jul 2016 18:24:32 +0200 Subject: [PATCH 32/47] Merge #8280: Tests: Increase sync_blocks() timeouts in pruning.py 36f1b9d Tests: Increase sync_blocks() timeouts in pruning.py (Suhas Daftuar) --- qa/rpc-tests/pruning.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/pruning.py b/qa/rpc-tests/pruning.py index d225e29b500f..7cbe69c29b2b 100755 --- a/qa/rpc-tests/pruning.py +++ b/qa/rpc-tests/pruning.py @@ -151,14 +151,14 @@ def reorg_test(self): print("Reconnect nodes") connect_nodes(self.nodes[0], 1) connect_nodes(self.nodes[2], 1) - sync_blocks(self.nodes[0:3]) + sync_blocks(self.nodes[0:3], timeout=120) print("Verify height on node 2:",self.nodes[2].getblockcount()) print("Usage possibly still high bc of stale blocks in block files:", calc_usage(self.prunedir)) print("Mine 220 more blocks so we have requisite history (some blocks will be big and cause pruning of previous chain)") self.nodes[0].generate(220) #node 0 has many large tx's in its mempool from the disconnects - sync_blocks(self.nodes[0:3]) + sync_blocks(self.nodes[0:3], timeout=300) usage = calc_usage(self.prunedir) print("Usage should be below target:", usage) From 355f3724d2981c60f334f8d12e1a96138f855217 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 6 Jul 2016 07:21:36 +0200 Subject: [PATCH 33/47] Merge #8298: wallet: Revert input selection post-pruning 20f3cd7 wallet: Revert input selection post-pruning (Wladimir J. van der Laan) --- src/wallet/test/wallet_tests.cpp | 14 -------------- src/wallet/wallet.cpp | 10 ---------- 2 files changed, 24 deletions(-) diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index 0a4f06ba8817..c6c5058984c0 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -349,20 +349,6 @@ BOOST_AUTO_TEST_CASE(ApproximateBestSubset) BOOST_CHECK(wallet.SelectCoinsMinConf(1003 * COIN, 1, 6, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 1003 * COIN); BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); - - empty_wallet(); - - // Test trimming - for (int i = 0; i < 100; i++) - add_coin(10 * COIN); - for (int i = 0; i < 100; i++) - add_coin(1000 * COIN); - - BOOST_CHECK(wallet.SelectCoinsMinConf(100001 * COIN, 1, 6, vCoins, setCoinsRet, nValueRet)); - // We need all 100 larger coins and exactly one small coin. - // Superfluous small coins must be trimmed from the set: - BOOST_CHECK_EQUAL(nValueRet, 100010 * COIN); - BOOST_CHECK_EQUAL(setCoinsRet.size(), 101); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 4e81a47891a5..c25587244516 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2537,16 +2537,6 @@ static void ApproximateBestSubset(vector= nTargetValue ) - { - vfBest[i] = false; - nBest -= vValue[i].first; - } - } } // move denoms down From 25627e31ddc4f7b0eb66a2f345b854506a479260 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 6 Jul 2016 15:45:13 +0200 Subject: [PATCH 34/47] Merge #8288: qt: Network-specific example address 4f44cb6 qt: Network-specific example address (Wladimir J. van der Laan) --- src/qt/guiutil.cpp | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index de8b20f00370..5ceb1505f0d9 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -109,6 +109,23 @@ QFont fixedPitchFont() #endif } +// Just some dummy data to generate an convincing random-looking (but consistent) address +static const uint8_t dummydata[] = {0xeb,0x15,0x23,0x1d,0xfc,0xeb,0x60,0x92,0x58,0x86,0xb6,0x7d,0x06,0x52,0x99,0x92,0x59,0x15,0xae,0xb1,0x72,0xc0,0x66,0x47}; + +// Generate a dummy address with invalid CRC, starting with the network prefix. +static std::string DummyAddress(const CChainParams ¶ms) +{ + std::vector sourcedata = params.Base58Prefix(CChainParams::PUBKEY_ADDRESS); + sourcedata.insert(sourcedata.end(), dummydata, dummydata + sizeof(dummydata)); + for(int i=0; i<256; ++i) { // Try every trailing byte + std::string s = EncodeBase58(begin_ptr(sourcedata), end_ptr(sourcedata)); + if (!CBitcoinAddress(s).IsValid()) + return s; + sourcedata[sourcedata.size()-1] += 1; + } + return ""; +} + void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent) { parent->setFocusProxy(widget); @@ -117,7 +134,8 @@ void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent) #if QT_VERSION >= 0x040700 // We don't want translators to use own addresses in translations // and this is the only place, where this address is supplied. - widget->setPlaceholderText(QObject::tr("Enter a Dash address (e.g. %1)").arg("XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwg")); + widget->setPlaceholderText(QObject::tr("Enter a Dash address (e.g. %1)").arg( + QString::fromStdString(DummyAddress(Params())))); #endif widget->setValidator(new BitcoinAddressEntryValidator(parent)); widget->setCheckValidator(new BitcoinAddressCheckValidator(parent)); From 5ff5474e4783f6e61ffbbfa126cb5aeb7b7916c7 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 7 Jul 2016 20:44:21 +0200 Subject: [PATCH 35/47] Merge #8304: [travis] Update SDK_URL fa6ad56 [travis] Update SDK_URL (MarcoFalke) --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 45eb965726fe..459e31475748 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,7 +31,7 @@ env: - CCACHE_TEMPDIR=/tmp/.ccache-temp - CCACHE_COMPRESS=1 - BASE_OUTDIR=$TRAVIS_BUILD_DIR/out - - SDK_URL=https://bitcoin.jonasschnelli.ch/sdks + - SDK_URL=https://bitcoincore.org/depends-sources/sdks - PYTHON_DEBUG=1 - WINEDEBUG=fixme-all From 7a6febfaae30b2a488f520aae3ea94b7ad7bae4f Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 8 Jul 2016 08:37:00 +0200 Subject: [PATCH 36/47] Merge #8310: build: require boost for bench cf2ef78 build: require boost for bench (Cory Fields) --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index c8cf51610eaf..2e29df79f173 100644 --- a/configure.ac +++ b/configure.ac @@ -593,7 +593,7 @@ BITCOIN_QT_INIT dnl sets $bitcoin_enable_qt, $bitcoin_enable_qt_test, $bitcoin_enable_qt_dbus BITCOIN_QT_CONFIGURE([$use_pkgconfig], [qt5]) -if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests = xnononono; then +if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench = xnonononono; then use_boost=no else use_boost=yes From 237ba56d9ed8a6e5afa29873c22ef087d25b0bfb Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 8 Jul 2016 10:16:13 +0200 Subject: [PATCH 37/47] Merge #8303: [Doc] Update bips.md for CSV softfork. ab0c35a [Doc] Update bips.md for CSV softfork. (fanquake) --- doc/bips.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/bips.md b/doc/bips.md index b4b62e781ec6..eae067ccfcdb 100644 --- a/doc/bips.md +++ b/doc/bips.md @@ -17,11 +17,11 @@ BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.13.0**): * [`BIP 61`](https://github.com/bitcoin/bips/blob/master/bip-0061.mediawiki): The 'reject' protocol message (and the protocol version bump to 70002) was added in **v0.9.0** ([PR #3185](https://github.com/bitcoin/bitcoin/pull/3185)). * [`BIP 65`](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki): The CHECKLOCKTIMEVERIFY softfork was merged in **v0.12.0** ([PR #6351](https://github.com/bitcoin/bitcoin/pull/6351)), and backported to **v0.11.2** and **v0.10.4**. Mempool-only CLTV was added in [PR #6124](https://github.com/bitcoin/bitcoin/pull/6124). * [`BIP 66`](https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki): The strict DER rules and associated version 3 blocks have been implemented since **v0.10.0** ([PR #5713](https://github.com/bitcoin/bitcoin/pull/5713)). -* [`BIP 68`](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki): Sequence locks have been implemented as of **v0.12.1** ([PR #7184](https://github.com/bitcoin/bitcoin/pull/7184)). +* [`BIP 68`](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki): Sequence locks have been implemented as of **v0.12.1** ([PR #7184](https://github.com/bitcoin/bitcoin/pull/7184)), and have been activated since *block 419328*. * [`BIP 70`](https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki) [`71`](https://github.com/bitcoin/bips/blob/master/bip-0071.mediawiki) [`72`](https://github.com/bitcoin/bips/blob/master/bip-0072.mediawiki): Payment Protocol support has been available in Bitcoin Core GUI since **v0.9.0** ([PR #5216](https://github.com/bitcoin/bitcoin/pull/5216)). * [`BIP 111`](https://github.com/bitcoin/bips/blob/master/bip-0111.mediawiki): `NODE_BLOOM` service bit added, and enforced for all peer versions as of **v0.13.0** ([PR #6579](https://github.com/bitcoin/bitcoin/pull/6579) and [PR #6641](https://github.com/bitcoin/bitcoin/pull/6641)). -* [`BIP 112`](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki): The CHECKSEQUENCEVERIFY opcode has been implemented since **v0.12.1** ([PR #7524](https://github.com/bitcoin/bitcoin/pull/7524)). -* [`BIP 113`](https://github.com/bitcoin/bips/blob/master/bip-0113.mediawiki): Median time past lock-time calculations have been implemented since **v0.12.1** ([PR #6566](https://github.com/bitcoin/bitcoin/pull/6566)). +* [`BIP 112`](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki): The CHECKSEQUENCEVERIFY opcode has been implemented since **v0.12.1** ([PR #7524](https://github.com/bitcoin/bitcoin/pull/7524)) and has been activated since *block 419328*. +* [`BIP 113`](https://github.com/bitcoin/bips/blob/master/bip-0113.mediawiki): Median time past lock-time calculations have been implemented since **v0.12.1** ([PR #6566](https://github.com/bitcoin/bitcoin/pull/6566)) and have been activated since *block 419328*. * [`BIP 125`](https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki): Opt-in full replace-by-fee signaling honoured in mempool and mining as of **v0.12.0** ([PR 6871](https://github.com/bitcoin/bitcoin/pull/6871)). * [`BIP 130`](https://github.com/bitcoin/bips/blob/master/bip-0130.mediawiki): direct headers announcement is negotiated with peer versions `>=70012` as of **v0.12.0** ([PR 6494](https://github.com/bitcoin/bitcoin/pull/6494)). * [`BIP 133`](https://github.com/bitcoin/bips/blob/master/bip-0133.mediawiki): feefilter messages are respected and sent for peer versions `>=70013` as of **v0.13.0** ([PR 7542](https://github.com/bitcoin/bitcoin/pull/7542)). From e6b071ab0a983706519f13ef92dcb4c3f0d780c0 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 8 Jul 2016 12:02:34 +0200 Subject: [PATCH 38/47] Merge #8315: gitian: Don't require sudo for Linux. 099d4b0 gitian: use a wrapped gcc/g++ to avoid the need for a system change (Cory Fields) --- contrib/gitian-descriptors/gitian-linux.yml | 40 +++++++++++++++++---- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index ff11505426de..2c26d4fd60d4 100755 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -33,12 +33,6 @@ remotes: files: [] script: | - #unlock sudo - echo "ubuntu" | sudo -S true - - sudo mkdir -p /usr/include/i386-linux-gnu/ - sudo ln -s /usr/include/x86_64-linux-gnu/asm /usr/include/i386-linux-gnu/asm - WRAP_DIR=$HOME/wrapped HOSTS="i686-pc-linux-gnu x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu" CONFIGFLAGS="--enable-glibc-back-compat --enable-reduce-exports --disable-bench --disable-gui-tests" @@ -90,11 +84,45 @@ script: | create_per-host_faketime_wrappers "2000-01-01 12:00:00" export PATH=${WRAP_DIR}:${PATH} + EXTRA_INCLUDES_BASE=$WRAP_DIR/extra_includes + mkdir -p $EXTRA_INCLUDES_BASE + + # x86 needs /usr/include/i386-linux-gnu/asm pointed to /usr/include/x86_64-linux-gnu/asm, + # but we can't write there. Instead, create a link here and force it to be included in the + # search paths by wrapping gcc/g++. + + mkdir -p $EXTRA_INCLUDES_BASE/i686-pc-linux-gnu + rm -f $WRAP_DIR/extra_includes/i686-pc-linux-gnu/asm + ln -s /usr/include/x86_64-linux-gnu/asm $EXTRA_INCLUDES_BASE/i686-pc-linux-gnu/asm + + for prog in gcc g++; do + rm -f ${WRAP_DIR}/${prog} + cat << EOF > ${WRAP_DIR}/${prog} + #!/bin/bash + REAL="`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1`" + for var in "\$@" + do + if [ "\$var" = "-m32" ]; then + export C_INCLUDE_PATH="$EXTRA_INCLUDES_BASE/i686-pc-linux-gnu" + export CPLUS_INCLUDE_PATH="$EXTRA_INCLUDES_BASE/i686-pc-linux-gnu" + break + fi + done + \$REAL \$@ + EOF + chmod +x ${WRAP_DIR}/${prog} + done + cd dash BASEPREFIX=`pwd`/depends # Build dependencies for each host for i in $HOSTS; do + EXTRA_INCLUDES="$EXTRA_INCLUDES_BASE/$i" + if [ -d "$EXTRA_INCLUDES" ]; then + export HOST_ID_SALT="$EXTRA_INCLUDES" + fi make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" + unset HOST_ID_SALT done # Faketime for binaries From 1670472976b99cf0521d683bb7abfb82f99bdcb6 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 8 Jul 2016 15:08:21 +0200 Subject: [PATCH 39/47] Merge #8314: Fix pkg-config issues for 0.13 b556bed build: fix Windows builds without pkg-config (Cory Fields) 0c928cb build: Fix Qt5PlatformSupport check without pkg-config (Cory Fields) --- build-aux/m4/bitcoin_qt.m4 | 20 ++++++++++++++++---- configure.ac | 27 ++++++++++++++++++--------- 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index 13f4c7469733..20f51163a6e6 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -346,8 +346,9 @@ AC_DEFUN([_BITCOIN_QT_FIND_STATIC_PLUGINS],[ QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible" fi fi - m4_ifdef([PKG_CHECK_MODULES],[ if test x$use_pkgconfig = xyes; then + : dnl + m4_ifdef([PKG_CHECK_MODULES],[ PKG_CHECK_MODULES([QTPLATFORM], [Qt5PlatformSupport], [QT_LIBS="$QTPLATFORM_LIBS $QT_LIBS"]) if test x$TARGET_OS = xlinux; then PKG_CHECK_MODULES([X11XCB], [x11-xcb], [QT_LIBS="$X11XCB_LIBS $QT_LIBS"]) @@ -357,12 +358,23 @@ AC_DEFUN([_BITCOIN_QT_FIND_STATIC_PLUGINS],[ elif test x$TARGET_OS = xdarwin; then PKG_CHECK_MODULES([QTPRINT], [Qt5PrintSupport], [QT_LIBS="$QTPRINT_LIBS $QT_LIBS"]) fi + ]) else - if ${PKG_CONFIG} --exists "Qt5Core >= 5.6" 2>/dev/null; then - QT_LIBS="-lQt5PlatformSupport $QT_LIBS" + if test x$TARGET_OS = xwindows; then + AC_CACHE_CHECK(for Qt >= 5.6, bitcoin_cv_need_platformsupport,[AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[#include ]],[[ + #if QT_VERSION < 0x050600 + choke; + #endif + ]])], + [bitcoin_cv_need_platformsupport=yes], + [bitcoin_cv_need_platformsupport=no]) + ]) + if test x$bitcoin_cv_need_platformsupport = xyes; then + BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}PlatformSupport],[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXPlatformSupport not found))) + fi fi fi - ]) else if test x$qt_plugin_path != x; then QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible" diff --git a/configure.ac b/configure.ac index 2e29df79f173..d57d3fc27825 100644 --- a/configure.ac +++ b/configure.ac @@ -88,9 +88,6 @@ AC_PATH_TOOL(OBJCOPY, objcopy) AC_ARG_VAR(PYTHONPATH, Augments the default search path for python module files) -dnl pkg-config check. -PKG_PROG_PKG_CONFIG - # Enable wallet AC_ARG_ENABLE([wallet], [AS_HELP_STRING([--disable-wallet], @@ -385,6 +382,16 @@ case $host in ;; esac +if test x$use_pkgconfig = xyes; then + m4_ifndef([PKG_PROG_PKG_CONFIG], [AC_MSG_ERROR(PKG_PROG_PKG_CONFIG macro not found. Please install pkg-config and re-run autogen.sh.)]) + m4_ifdef([PKG_PROG_PKG_CONFIG], [ + PKG_PROG_PKG_CONFIG + if test x"$PKG_CONFIG" = "x"; then + AC_MSG_ERROR(pkg-config not found.) + fi + ]) +fi + if test x$use_comparison_tool != xno; then AC_SUBST(JAVA_COMPARISON_TOOL, $use_comparison_tool) fi @@ -762,12 +769,7 @@ fi fi if test x$use_pkgconfig = xyes; then - - if test x"$PKG_CONFIG" = "x"; then - AC_MSG_ERROR(pkg-config not found.) - fi - - : #NOP + : dnl m4_ifdef( [PKG_CHECK_MODULES], [ @@ -1068,6 +1070,13 @@ AC_SUBST(TESTDEFS) AC_SUBST(LEVELDB_TARGET_FLAGS) AC_SUBST(MINIUPNPC_CPPFLAGS) AC_SUBST(MINIUPNPC_LIBS) +AC_SUBST(CRYPTO_LIBS) +AC_SUBST(SSL_LIBS) +AC_SUBST(EVENT_LIBS) +AC_SUBST(EVENT_PTHREADS_LIBS) +AC_SUBST(ZMQ_LIBS) +AC_SUBST(PROTOBUF_LIBS) +AC_SUBST(QR_LIBS) AC_CONFIG_FILES([Makefile src/Makefile share/setup.nsi share/qt/Info.plist src/test/buildenv.py]) AC_CONFIG_FILES([qa/pull-tester/run-bitcoind-for-test.sh],[chmod +x qa/pull-tester/run-bitcoind-for-test.sh]) AC_CONFIG_FILES([qa/pull-tester/tests_config.py],[chmod +x qa/pull-tester/tests_config.py]) From 26540aa5d164869fcf32e36852549a2fba5e7dbd Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 11 Jul 2016 11:02:41 +0200 Subject: [PATCH 40/47] Merge #8289: bash-completion: Adapt for 0.12 and 0.13 1ba3db6 bash-completion: Adapt for 0.12 and 0.13 (Christian von Roques) --- contrib/dash-cli.bash-completion | 154 +++++++++++++++++++++++++ contrib/dash-tx.bash-completion | 57 +++++++++ contrib/dashd.bash-completion | 111 ++---------------- contrib/debian/dash-tx.bash-completion | 1 + contrib/debian/dashd.bash-completion | 1 + 5 files changed, 224 insertions(+), 100 deletions(-) create mode 100644 contrib/dash-cli.bash-completion create mode 100644 contrib/dash-tx.bash-completion create mode 100644 contrib/debian/dash-tx.bash-completion diff --git a/contrib/dash-cli.bash-completion b/contrib/dash-cli.bash-completion new file mode 100644 index 000000000000..97a2531bb518 --- /dev/null +++ b/contrib/dash-cli.bash-completion @@ -0,0 +1,154 @@ +# bash programmable completion for dash-cli(1) +# Copyright (c) 2012-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# call $dash-cli for RPC +_dash_rpc() { + # determine already specified args necessary for RPC + local rpcargs=() + for i in ${COMP_LINE}; do + case "$i" in + -conf=*|-datadir=*|-regtest|-rpc*|-testnet) + rpcargs=( "${rpcargs[@]}" "$i" ) + ;; + esac + done + $dash_cli "${rpcargs[@]}" "$@" +} + +# Add wallet accounts to COMPREPLY +_dash_accounts() { + local accounts + accounts=$(_dash_rpc listaccounts | awk -F '"' '{ print $2 }') + COMPREPLY=( "${COMPREPLY[@]}" $( compgen -W "$accounts" -- "$cur" ) ) +} + +_dash_cli() { + local cur prev words=() cword + local dash_cli + + # save and use original argument to invoke dash-cli for -help, help and RPC + # as dash-cli might not be in $PATH + dash_cli="$1" + + COMPREPLY=() + _get_comp_words_by_ref -n = cur prev words cword + + if ((cword > 5)); then + case ${words[cword-5]} in + sendtoaddress) + COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) + return 0 + ;; + esac + fi + + if ((cword > 4)); then + case ${words[cword-4]} in + importaddress|listtransactions|setban) + COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) + return 0 + ;; + signrawtransaction) + COMPREPLY=( $( compgen -W "ALL NONE SINGLE ALL|ANYONECANPAY NONE|ANYONECANPAY SINGLE|ANYONECANPAY" -- "$cur" ) ) + return 0 + ;; + esac + fi + + if ((cword > 3)); then + case ${words[cword-3]} in + addmultisigaddress) + _dash_accounts + return 0 + ;; + getbalance|gettxout|importaddress|importpubkey|importprivkey|listreceivedbyaccount|listreceivedbyaddress|listsinceblock) + COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) + return 0 + ;; + esac + fi + + if ((cword > 2)); then + case ${words[cword-2]} in + addnode) + COMPREPLY=( $( compgen -W "add remove onetry" -- "$cur" ) ) + return 0 + ;; + setban) + COMPREPLY=( $( compgen -W "add remove" -- "$cur" ) ) + return 0 + ;; + fundrawtransaction|getblock|getblockheader|getmempoolancestors|getmempooldescendants|getrawtransaction|gettransaction|listaccounts|listreceivedbyaccount|listreceivedbyaddress|sendrawtransaction) + COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) + return 0 + ;; + move|setaccount) + _dash_accounts + return 0 + ;; + esac + fi + + case "$prev" in + backupwallet|dumpwallet|importwallet) + _filedir + return 0 + ;; + getaddednodeinfo|getrawmempool|lockunspent|setgenerate) + COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) + return 0 + ;; + getaccountaddress|getaddressesbyaccount|getbalance|getnewaddress|getreceivedbyaccount|listtransactions|move|sendfrom|sendmany) + _dash_accounts + return 0 + ;; + esac + + case "$cur" in + -conf=*) + cur="${cur#*=}" + _filedir + return 0 + ;; + -datadir=*) + cur="${cur#*=}" + _filedir -d + return 0 + ;; + -*=*) # prevent nonsense completions + return 0 + ;; + *) + local helpopts commands + + # only parse -help if senseful + if [[ -z "$cur" || "$cur" =~ ^- ]]; then + helpopts=$($dash_cli -help 2>&1 | awk '$1 ~ /^-/ { sub(/=.*/, "="); print $1 }' ) + fi + + # only parse help if senseful + if [[ -z "$cur" || "$cur" =~ ^[a-z] ]]; then + commands=$(_dash_rpc help 2>/dev/null | awk '$1 ~ /^[a-z]/ { print $1; }') + fi + + COMPREPLY=( $( compgen -W "$helpopts $commands" -- "$cur" ) ) + + # Prevent space if an argument is desired + if [[ $COMPREPLY == *= ]]; then + compopt -o nospace + fi + return 0 + ;; + esac +} && +complete -F _dash_cli dash-cli + +# Local variables: +# mode: shell-script +# sh-basic-offset: 4 +# sh-indent-comment: t +# indent-tabs-mode: nil +# End: +# ex: ts=4 sw=4 et filetype=sh diff --git a/contrib/dash-tx.bash-completion b/contrib/dash-tx.bash-completion new file mode 100644 index 000000000000..3cda7036090e --- /dev/null +++ b/contrib/dash-tx.bash-completion @@ -0,0 +1,57 @@ +# bash programmable completion for dash-tx(1) +# Copyright (c) 2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +_dash_tx() { + local cur prev words=() cword + local dash_tx + + # save and use original argument to invoke dash-tx for -help + # it might not be in $PATH + dash_tx="$1" + + COMPREPLY=() + _get_comp_words_by_ref -n =: cur prev words cword + + case "$cur" in + load=*:*) + cur="${cur#load=*:}" + _filedir + return 0 + ;; + *=*) # prevent attempts to complete other arguments + return 0 + ;; + esac + + if [[ "$cword" == 1 || ( "$prev" != "-create" && "$prev" == -* ) ]]; then + # only options (or an uncompletable hex-string) allowed + # parse dash-tx -help for options + local helpopts + helpopts=$($dash_tx -help | sed -e '/^ -/ p' -e d ) + COMPREPLY=( $( compgen -W "$helpopts" -- "$cur" ) ) + else + # only commands are allowed + # parse -help for commands + local helpcmds + helpcmds=$($dash_tx -help | sed -e '1,/Commands:/d' -e 's/=.*/=/' -e '/^ [a-z]/ p' -e d ) + COMPREPLY=( $( compgen -W "$helpcmds" -- "$cur" ) ) + fi + + # Prevent space if an argument is desired + if [[ $COMPREPLY == *= ]]; then + compopt -o nospace + fi + + return 0 +} && +complete -F _dash_tx dash-tx + +# Local variables: +# mode: shell-script +# sh-basic-offset: 4 +# sh-indent-comment: t +# indent-tabs-mode: nil +# End: +# ex: ts=4 sw=4 et filetype=sh diff --git a/contrib/dashd.bash-completion b/contrib/dashd.bash-completion index 18880e8090f9..18e25097faa1 100644 --- a/contrib/dashd.bash-completion +++ b/contrib/dashd.bash-completion @@ -1,102 +1,21 @@ -# bash programmable completion for dashd(1) and dash-cli(1) -# Copyright (c) 2012,2014 Christian von Roques +# bash programmable completion for dashd(1) and dash-qt(1) +# Copyright (c) 2012-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -have dashd && { - -# call $dashd for RPC -_dash_rpc() { - # determine already specified args necessary for RPC - local rpcargs=() - for i in ${COMP_LINE}; do - case "$i" in - -conf=*|-proxy*|-rpc*) - rpcargs=( "${rpcargs[@]}" "$i" ) - ;; - esac - done - $dashd "${rpcargs[@]}" "$@" -} - -# Add dash accounts to COMPREPLY -_dash_accounts() { - local accounts - accounts=$(_dash_rpc listaccounts | awk '/".*"/ { a=$1; gsub(/"/, "", a); print a}') - COMPREPLY=( "${COMPREPLY[@]}" $( compgen -W "$accounts" -- "$cur" ) ) -} - _dashd() { local cur prev words=() cword local dashd - # save and use original argument to invoke dashd - # dashd might not be in $PATH + # save and use original argument to invoke dashd for -help + # it might not be in $PATH dashd="$1" COMPREPLY=() _get_comp_words_by_ref -n = cur prev words cword - if ((cword > 4)); then - case ${words[cword-4]} in - listtransactions) - COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) - return 0 - ;; - signrawtransaction) - COMPREPLY=( $( compgen -W "ALL NONE SINGLE ALL|ANYONECANPAY NONE|ANYONECANPAY SINGLE|ANYONECANPAY" -- "$cur" ) ) - return 0 - ;; - esac - fi - - if ((cword > 3)); then - case ${words[cword-3]} in - addmultisigaddress) - _dash_accounts - return 0 - ;; - getbalance|gettxout|importaddress|importprivkey|listreceivedbyaccount|listreceivedbyaddress|listsinceblock) - COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) - return 0 - ;; - esac - fi - - if ((cword > 2)); then - case ${words[cword-2]} in - addnode) - COMPREPLY=( $( compgen -W "add remove onetry" -- "$cur" ) ) - return 0 - ;; - getblock|getrawtransaction|gettransaction|listaccounts|listreceivedbyaccount|listreceivedbyaddress|sendrawtransaction) - COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) - return 0 - ;; - move|setaccount) - _dash_accounts - return 0 - ;; - esac - fi - - case "$prev" in - backupwallet|dumpwallet|importwallet) - _filedir - return 0 - ;; - getmempool|lockunspent|setgenerate) - COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) - return 0 - ;; - getaccountaddress|getaddressesbyaccount|getbalance|getnewaddress|getreceivedbyaccount|listtransactions|move|sendfrom|sendmany) - _dash_accounts - return 0 - ;; - esac - case "$cur" in - -conf=*|-pid=*|-loadblock=*|-wallet=*) + -conf=*|-pid=*|-loadblock=*|-rootcertificates=*|-rpccookiefile=*|-wallet=*) cur="${cur#*=}" _filedir return 0 @@ -110,20 +29,14 @@ _dashd() { return 0 ;; *) - local helpopts commands - # only parse --help if senseful + # only parse -help if senseful if [[ -z "$cur" || "$cur" =~ ^- ]]; then - helpopts=$($dashd --help 2>&1 | awk '$1 ~ /^-/ { sub(/=.*/, "="); print $1 }' ) + local helpopts + helpopts=$($dashd -help 2>&1 | awk '$1 ~ /^-/ { sub(/=.*/, "="); print $1 }' ) + COMPREPLY=( $( compgen -W "$helpopts" -- "$cur" ) ) fi - # only parse help if senseful - if [[ -z "$cur" || "$cur" =~ ^[a-z] ]]; then - commands=$(_dash_rpc help 2>/dev/null | awk '$1 ~ /^[a-z]/ { print $1; }') - fi - - COMPREPLY=( $( compgen -W "$helpopts $commands" -- "$cur" ) ) - # Prevent space if an argument is desired if [[ $COMPREPLY == *= ]]; then compopt -o nospace @@ -131,10 +44,8 @@ _dashd() { return 0 ;; esac -} - -complete -F _dashd dashd dash-cli -} +} && +complete -F _dashd dashd dash-qt # Local variables: # mode: shell-script diff --git a/contrib/debian/dash-tx.bash-completion b/contrib/debian/dash-tx.bash-completion new file mode 100644 index 000000000000..605234a39be6 --- /dev/null +++ b/contrib/debian/dash-tx.bash-completion @@ -0,0 +1 @@ +contrib/dash-tx.bash-completion dash-tx diff --git a/contrib/debian/dashd.bash-completion b/contrib/debian/dashd.bash-completion index d92f33da7bf3..da0bc29409b9 100644 --- a/contrib/debian/dashd.bash-completion +++ b/contrib/debian/dashd.bash-completion @@ -1 +1,2 @@ contrib/dashd.bash-completion dashd +contrib/dash-cli.bash-completion dash-cli \ No newline at end of file From bc257c1a0894576be046ad8ab1030fb3abb17091 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 18 Jul 2016 07:43:55 +0200 Subject: [PATCH 41/47] Merge #8305: Improve handling of unconnecting headers e91cf4b Add test for handling of unconnecting headers (Suhas Daftuar) 96fa953 Improve handling of unconnecting headers (Suhas Daftuar) --- qa/rpc-tests/sendheaders.py | 105 ++++++++++++++++++++++++++++++++++++ src/net_processing.cpp | 39 +++++++++++++- src/validation.h | 3 ++ 3 files changed, 146 insertions(+), 1 deletion(-) diff --git a/qa/rpc-tests/sendheaders.py b/qa/rpc-tests/sendheaders.py index 6ab17d59b387..c3f3180b6bca 100755 --- a/qa/rpc-tests/sendheaders.py +++ b/qa/rpc-tests/sendheaders.py @@ -63,6 +63,21 @@ Expect: getdata request for 14 more blocks. f. Announce 1 more header that builds on that fork. Expect: no response. + +Part 5: Test handling of headers that don't connect. +a. Repeat 10 times: + 1. Announce a header that doesn't connect. + Expect: getheaders message + 2. Send headers chain. + Expect: getdata for the missing blocks, tip update. +b. Then send 9 more headers that don't connect. + Expect: getheaders message each time. +c. Announce a header that does connect. + Expect: no response. +d. Announce 49 headers that don't connect. + Expect: getheaders message each time. +e. Announce one more that doesn't connect. + Expect: disconnect. ''' class BaseNode(NodeConnCB): @@ -77,6 +92,8 @@ def __init__(self): self.last_getdata = None self.sleep_time = 0.05 self.block_announced = False + self.last_getheaders = None + self.disconnected = False def clear_last_announcement(self): with mininode_lock: @@ -127,6 +144,12 @@ def on_getdata(self, conn, message): def on_pong(self, conn, message): self.last_pong = message + def on_getheaders(self, conn, message): + self.last_getheaders = message + + def on_close(self, conn): + self.disconnected = True + # Test whether the last announcement we received had the # right header or the right inv # inv and headers should be lists of block hashes @@ -178,6 +201,11 @@ def wait_for_block(self, blockhash, timeout=60): self.sync(test_function, timeout) return + def wait_for_getheaders(self, timeout=60): + test_function = lambda: self.last_getheaders != None + self.sync(test_function, timeout) + return + def wait_for_getdata(self, hash_list, timeout=60): if hash_list == []: return @@ -186,6 +214,11 @@ def wait_for_getdata(self, hash_list, timeout=60): self.sync(test_function, timeout) return + def wait_for_disconnect(self, timeout=60): + test_function = lambda: self.disconnected + self.sync(test_function, timeout) + return + def send_header_for_blocks(self, new_blocks): headers_message = msg_headers() headers_message.headers = [ CBlockHeader(b) for b in new_blocks ] @@ -510,6 +543,78 @@ def run_test(self): print("Part 4: success!") + # Now deliver all those blocks we announced. + [ test_node.send_message(msg_block(x)) for x in blocks ] + + print("Part 5: Testing handling of unconnecting headers") + # First we test that receipt of an unconnecting header doesn't prevent + # chain sync. + for i in range(10): + test_node.last_getdata = None + blocks = [] + # Create two more blocks. + for j in range(2): + blocks.append(create_block(tip, create_coinbase(height), block_time)) + blocks[-1].solve() + tip = blocks[-1].sha256 + block_time += 1 + height += 1 + # Send the header of the second block -> this won't connect. + with mininode_lock: + test_node.last_getheaders = None + test_node.send_header_for_blocks([blocks[1]]) + test_node.wait_for_getheaders(timeout=1) + test_node.send_header_for_blocks(blocks) + test_node.wait_for_getdata([x.sha256 for x in blocks]) + [ test_node.send_message(msg_block(x)) for x in blocks ] + test_node.sync_with_ping() + assert_equal(int(self.nodes[0].getbestblockhash(), 16), blocks[1].sha256) + + blocks = [] + # Now we test that if we repeatedly don't send connecting headers, we + # don't go into an infinite loop trying to get them to connect. + MAX_UNCONNECTING_HEADERS = 10 + for j in range(MAX_UNCONNECTING_HEADERS+1): + blocks.append(create_block(tip, create_coinbase(height), block_time)) + blocks[-1].solve() + tip = blocks[-1].sha256 + block_time += 1 + height += 1 + + for i in range(1, MAX_UNCONNECTING_HEADERS): + # Send a header that doesn't connect, check that we get a getheaders. + with mininode_lock: + test_node.last_getheaders = None + test_node.send_header_for_blocks([blocks[i]]) + test_node.wait_for_getheaders(timeout=1) + + # Next header will connect, should re-set our count: + test_node.send_header_for_blocks([blocks[0]]) + + # Remove the first two entries (blocks[1] would connect): + blocks = blocks[2:] + + # Now try to see how many unconnecting headers we can send + # before we get disconnected. Should be 5*MAX_UNCONNECTING_HEADERS + for i in range(5*MAX_UNCONNECTING_HEADERS - 1): + # Send a header that doesn't connect, check that we get a getheaders. + with mininode_lock: + test_node.last_getheaders = None + test_node.send_header_for_blocks([blocks[i%len(blocks)]]) + test_node.wait_for_getheaders(timeout=1) + + # Eventually this stops working. + with mininode_lock: + self.last_getheaders = None + test_node.send_header_for_blocks([blocks[-1]]) + + # Should get disconnected + test_node.wait_for_disconnect() + with mininode_lock: + self.last_getheaders = True + + print("Part 5: success!") + # Finally, check that the inv node never received a getdata request, # throughout the test assert_equal(inv_node.last_getdata, None) diff --git a/src/net_processing.cpp b/src/net_processing.cpp index f6f8176be31c..1936f012f2f9 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -166,6 +166,8 @@ struct CNodeState { CBlockIndex *pindexLastCommonBlock; //! The best header we have sent our peer. CBlockIndex *pindexBestHeaderSent; + //! Length of current-streak of unconnecting headers announcements + int nUnconnectingHeaders; //! Whether we've started headers synchronization with this peer. bool fSyncStarted; //! When to potentially disconnect peer for stalling headers download @@ -190,6 +192,7 @@ struct CNodeState { hashLastUnknownBlock.SetNull(); pindexLastCommonBlock = NULL; pindexBestHeaderSent = NULL; + nUnconnectingHeaders = 0; fSyncStarted = false; nHeadersSyncTimeout = 0; nStallingSince = 0; @@ -1823,6 +1826,35 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, CBlockIndex *pindexLast = NULL; { LOCK(cs_main); + CNodeState *nodestate = State(pfrom->GetId()); + + // If this looks like it could be a block announcement (nCount < + // MAX_BLOCKS_TO_ANNOUNCE), use special logic for handling headers that + // don't connect: + // - Send a getheaders message in response to try to connect the chain. + // - The peer can send up to MAX_UNCONNECTING_HEADERS in a row that + // don't connect before giving DoS points + // - Once a headers message is received that is valid and does connect, + // nUnconnectingHeaders gets reset back to 0. + if (nCount > 0 && mapBlockIndex.find(headers[0].hashPrevBlock) == mapBlockIndex.end() && nCount < MAX_BLOCKS_TO_ANNOUNCE) { + nodestate->nUnconnectingHeaders++; + connman.PushMessage(pfrom, NetMsgType::GETHEADERS, chainActive.GetLocator(pindexBestHeader), uint256()); + LogPrint("net", "received header %s: missing prev block %s, sending getheaders (%d) to end (peer=%d, nUnconnectingHeaders=%d)\n", + headers[0].GetHash().ToString(), + headers[0].hashPrevBlock.ToString(), + pindexBestHeader->nHeight, + pfrom->id, nodestate->nUnconnectingHeaders); + // Set hashLastUnknownBlock for this peer, so that if we + // eventually get the headers - even from a different peer - + // we can use this peer to download. + UpdateBlockAvailability(pfrom->GetId(), headers.back().GetHash()); + + if (nodestate->nUnconnectingHeaders % MAX_UNCONNECTING_HEADERS == 0) { + Misbehaving(pfrom->GetId(), 20); + } + return true; + } + uint256 hashLastBlock; for (const CBlockHeader& header : headers) { if (!hashLastBlock.IsNull() && header.hashPrevBlock != hashLastBlock) { @@ -1847,6 +1879,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, { LOCK(cs_main); + CNodeState *nodestate = State(pfrom->GetId()); + if (nodestate->nUnconnectingHeaders > 0) { + LogPrint("net", "peer=%d: resetting nUnconnectingHeaders (%d -> 0)\n", pfrom->id, nodestate->nUnconnectingHeaders); + } + nodestate->nUnconnectingHeaders = 0; + if (pindexLast) UpdateBlockAvailability(pfrom->GetId(), pindexLast->GetBlockHash()); @@ -1873,7 +1911,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } bool fCanDirectFetch = CanDirectFetch(chainparams.GetConsensus()); - CNodeState *nodestate = State(pfrom->GetId()); // If this set of headers is valid and ends in a block with at least as // much work as our tip, download as much as possible. if (fCanDirectFetch && pindexLast->IsValid(BLOCK_VALID_TREE) && chainActive.Tip()->nChainWork <= pindexLast->nChainWork) { diff --git a/src/validation.h b/src/validation.h index 683121a2a651..54e9d2975dd9 100644 --- a/src/validation.h +++ b/src/validation.h @@ -143,6 +143,9 @@ static const bool DEFAULT_FEEFILTER = true; /** Maximum number of headers to announce when relaying blocks with headers message.*/ static const unsigned int MAX_BLOCKS_TO_ANNOUNCE = 8; +/** Maximum number of unconnecting headers announcements before DoS score */ +static const int MAX_UNCONNECTING_HEADERS = 10; + static const bool DEFAULT_PEERBLOOMFILTERS = true; struct BlockHasher From f9f3b8d93835bcea2f8b416d60a894609220c635 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 18 Jul 2016 08:23:38 +0200 Subject: [PATCH 42/47] Merge #8295: Mining-related fixups for 0.13.0 c1d61fb Add warning if -blockminsize is used. (Suhas Daftuar) 27362dd Remove -blockminsize option (Suhas Daftuar) d2e46e1 Remove addScoreTxs() (Suhas Daftuar) 6dd4bc2 Exclude witness transactions in addPackageTxs() pre-segwit activation (Suhas Daftuar) f15c2cd CreateNewBlock: add support for size-accounting to addPackageTxs (Suhas Daftuar) --- contrib/devtools/check-doc.py | 2 +- src/init.cpp | 4 +- src/miner.cpp | 84 ++++++++--------------------------- src/miner.h | 15 ++++--- src/policy/policy.h | 3 +- 5 files changed, 31 insertions(+), 77 deletions(-) diff --git a/contrib/devtools/check-doc.py b/contrib/devtools/check-doc.py index 8c73cf1e8a73..fa1e137587a6 100755 --- a/contrib/devtools/check-doc.py +++ b/contrib/devtools/check-doc.py @@ -21,7 +21,7 @@ REGEX_ARG = re.compile(r'(?:map(?:Multi)?Args(?:\.count\(|\[)|Get(?:Bool)?Arg\()\"(\-[^\"]+?)\"') REGEX_DOC = re.compile(r'HelpMessageOpt\(\"(\-[^\"=]+?)(?:=|\")') # list unsupported, deprecated and duplicate args as they need no documentation -SET_DOC_OPTIONAL = set(['-rpcssl', '-benchmark', '-h', '-help', '-socks', '-tor', '-debugnet', '-whitelistalwaysrelay']) +SET_DOC_OPTIONAL = set(['-rpcssl', '-benchmark', '-h', '-help', '-socks', '-tor', '-debugnet', '-whitelistalwaysrelay', '-blockminsize']) def main(): used = check_output(CMD_GREP_ARGS, shell=True) diff --git a/src/init.cpp b/src/init.cpp index 45c471f28c73..c9d87fa358a2 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -563,7 +563,6 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-mempoolreplacement", strprintf(_("Enable transaction replacement in the memory pool (default: %u)"), DEFAULT_ENABLE_REPLACEMENT)); strUsage += HelpMessageGroup(_("Block creation options:")); - strUsage += HelpMessageOpt("-blockminsize=", strprintf(_("Set minimum block size in bytes (default: %u)"), DEFAULT_BLOCK_MIN_SIZE)); strUsage += HelpMessageOpt("-blockmaxsize=", strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE)); strUsage += HelpMessageOpt("-blockprioritysize=", strprintf(_("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), DEFAULT_BLOCK_PRIORITY_SIZE)); if (showDebug) @@ -1045,6 +1044,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (GetBoolArg("-whitelistalwaysrelay", false)) InitWarning(_("Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay.")); + if (mapArgs.count("-blockminsize")) + InitWarning("Unsupported argument -blockminsize ignored."); + // Checkmempool and checkblockindex default to true in regtest mode int ratio = std::min(std::max(GetArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0), 1000000); if (ratio != 0) { diff --git a/src/miner.cpp b/src/miner.cpp index 1b0e2a12aaf9..6c361d5eb048 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -82,11 +82,6 @@ BlockAssembler::BlockAssembler(const CChainParams& _chainparams) nBlockMaxSize = GetArg("-blockmaxsize", DEFAULT_BLOCK_MAX_SIZE); // Limit to between 1K and MAX_BLOCK_SIZE-1K for sanity: nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MaxBlockSize(fDIP0001ActiveAtTip)-1000), nBlockMaxSize)); - - // Minimum block size you want to create; block will be filled with free transactions - // until there are no more or the block reaches this size: - nBlockMinSize = GetArg("-blockminsize", DEFAULT_BLOCK_MIN_SIZE); - nBlockMinSize = std::min(nBlockMaxSize, nBlockMinSize); } void BlockAssembler::resetBlock() @@ -215,13 +210,26 @@ bool BlockAssembler::TestPackage(uint64_t packageSize, unsigned int packageSigOp return true; } -// Block size and sigops have already been tested. Check that all transactions -// are final. -bool BlockAssembler::TestPackageFinality(const CTxMemPool::setEntries& package) +// Perform transaction-level checks before adding to block: +// - transaction finality (locktime) +// - premature witness (in case segwit transactions are added to mempool before +// segwit activation) +// - serialized size (in case -blockmaxsize is in use) +bool BlockAssembler::TestPackageTransactions(const CTxMemPool::setEntries& package) { + uint64_t nPotentialBlockSize = nBlockSize; // only used with fNeedSizeAccounting BOOST_FOREACH (const CTxMemPool::txiter it, package) { if (!IsFinalTx(it->GetTx(), nHeight, nLockTimeCutoff)) return false; + if (!fIncludeWitness && !it->GetTx().wit.IsNull()) + return false; + if (fNeedSizeAccounting) { + uint64_t nTxSize = ::GetSerializeSize(it->GetTx(), SER_NETWORK, PROTOCOL_VERSION); + if (nPotentialBlockSize + nTxSize >= nBlockMaxSize) { + return false; + } + nPotentialBlockSize += nTxSize; + } } return true; } @@ -289,62 +297,6 @@ void BlockAssembler::AddToBlock(CTxMemPool::txiter iter) } } -void BlockAssembler::addScoreTxs() -{ - std::priority_queue, ScoreCompare> clearedTxs; - CTxMemPool::setEntries waitSet; - CTxMemPool::indexed_transaction_set::index::type::iterator mi = mempool.mapTx.get().begin(); - CTxMemPool::txiter iter; - while (!blockFinished && (mi != mempool.mapTx.get().end() || !clearedTxs.empty())) - { - // If no txs that were previously postponed are available to try - // again, then try the next highest score tx - if (clearedTxs.empty()) { - iter = mempool.mapTx.project<0>(mi); - mi++; - } - // If a previously postponed tx is available to try again, then it - // has higher score than all untried so far txs - else { - iter = clearedTxs.top(); - clearedTxs.pop(); - } - - // If tx already in block, skip (added by addPriorityTxs) - if (inBlock.count(iter)) { - continue; - } - - // If tx is dependent on other mempool txs which haven't yet been included - // then put it in the waitSet - if (isStillDependent(iter)) { - waitSet.insert(iter); - continue; - } - - // If the fee rate is below the min fee rate for mining, then we're done - // adding txs based on score (fee rate) - if (iter->GetModifiedFee() < ::minRelayTxFee.GetFee(iter->GetTxSize()) && nBlockSize >= nBlockMinSize) { - return; - } - - // If this tx fits in the block add it, otherwise keep looping - if (TestForBlock(iter)) { - AddToBlock(iter); - - // This tx was successfully added, so - // add transactions that depend on this one to the priority queue to try again - BOOST_FOREACH(CTxMemPool::txiter child, mempool.GetMemPoolChildren(iter)) - { - if (waitSet.count(child)) { - clearedTxs.push(child); - waitSet.erase(child); - } - } - } - } -} - void BlockAssembler::UpdatePackagesForAdded(const CTxMemPool::setEntries& alreadyAdded, indexed_modified_transaction_set &mapModifiedTx) { @@ -494,7 +446,7 @@ void BlockAssembler::addPackageTxs() ancestors.insert(iter); // Test if all tx's are Final - if (!TestPackageFinality(ancestors)) { + if (!TestPackageTransactions(ancestors)) { if (fUsingModified) { mapModifiedTx.get().erase(modit); failedTx.insert(iter); @@ -573,7 +525,7 @@ void BlockAssembler::addPriorityTxs() // If now that this txs is added we've surpassed our desired priority size // or have dropped below the AllowFreeThreshold, then we're done adding priority txs if (nBlockSize >= nBlockPrioritySize || !AllowFree(actualPriority)) { - return; + break; } // This tx was successfully added, so diff --git a/src/miner.h b/src/miner.h index 188c80d03436..b4059f5c1735 100644 --- a/src/miner.h +++ b/src/miner.h @@ -140,7 +140,7 @@ class BlockAssembler CBlock* pblock; // Configuration parameters for the block size - unsigned int nBlockMaxSize, nBlockMinSize; + unsigned int nBlockMaxSize; // Information on the current status of the block uint64_t nBlockSize; @@ -154,7 +154,7 @@ class BlockAssembler int64_t nLockTimeCutoff; const CChainParams& chainparams; - // Variables used for addScoreTxs and addPriorityTxs + // Variables used for addPriorityTxs int lastFewTxs; bool blockFinished; @@ -171,14 +171,12 @@ class BlockAssembler void AddToBlock(CTxMemPool::txiter iter); // Methods for how to add transactions to a block. - /** Add transactions based on modified feerate */ - void addScoreTxs(); /** Add transactions based on tx "priority" */ void addPriorityTxs(); /** Add transactions based on feerate including unconfirmed ancestors */ void addPackageTxs(); - // helper function for addScoreTxs and addPriorityTxs + // helper function for addPriorityTxs /** Test if tx will still "fit" in the block */ bool TestForBlock(CTxMemPool::txiter iter); /** Test if tx still has unconfirmed parents not yet in block */ @@ -189,8 +187,11 @@ class BlockAssembler void onlyUnconfirmed(CTxMemPool::setEntries& testSet); /** Test if a new package would "fit" in the block */ bool TestPackage(uint64_t packageSize, unsigned int packageSigOps); - /** Test if a set of transactions are all final */ - bool TestPackageFinality(const CTxMemPool::setEntries& package); + /** Perform checks on each transaction in a package: + * locktime, premature-witness, serialized size (if necessary) + * These checks should always succeed, and they're here + * only as an extra check in case of suboptimal node configuration */ + bool TestPackageTransactions(const CTxMemPool::setEntries& package); /** Return true if given transaction from mapTx has already been evaluated, * or if the transaction's cached data in mapTx is incorrect. */ bool SkipMapTxEntry(CTxMemPool::txiter it, indexed_modified_transaction_set &mapModifiedTx, CTxMemPool::setEntries &failedTx); diff --git a/src/policy/policy.h b/src/policy/policy.h index 69383c2e39a6..8da0f3884287 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -14,9 +14,8 @@ class CCoinsViewCache; -/** Default for -blockmaxsize and -blockminsize, which control the range of sizes the mining code will create **/ +/** Default for -blockmaxsize, which controls the maximum size of block the mining code will create **/ static const unsigned int DEFAULT_BLOCK_MAX_SIZE = 750000; -static const unsigned int DEFAULT_BLOCK_MIN_SIZE = 0; /** Default for -blockprioritysize, maximum space for zero/low-fee transactions **/ static const unsigned int DEFAULT_BLOCK_PRIORITY_SIZE = 10000; // was 50000 in 0.12.0 and it is 0 in Bitcoin since 0.12 /** The maximum size for transactions we're willing to relay/mine */ From 6a993236befbbf8e5495328df1d8d3f8c56e8a43 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Mon, 18 Sep 2017 13:22:21 +0200 Subject: [PATCH 43/47] Remove SegWit related checks added by backporting of Bitcoin #8295 Also remove nBlockMinSize check from addPackageTxs. Removed by SegWit related commits in Bitcoin. --- src/miner.cpp | 15 +-------------- src/miner.h | 2 +- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/src/miner.cpp b/src/miner.cpp index 6c361d5eb048..1f72ff66110a 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -212,24 +212,11 @@ bool BlockAssembler::TestPackage(uint64_t packageSize, unsigned int packageSigOp // Perform transaction-level checks before adding to block: // - transaction finality (locktime) -// - premature witness (in case segwit transactions are added to mempool before -// segwit activation) -// - serialized size (in case -blockmaxsize is in use) bool BlockAssembler::TestPackageTransactions(const CTxMemPool::setEntries& package) { - uint64_t nPotentialBlockSize = nBlockSize; // only used with fNeedSizeAccounting BOOST_FOREACH (const CTxMemPool::txiter it, package) { if (!IsFinalTx(it->GetTx(), nHeight, nLockTimeCutoff)) return false; - if (!fIncludeWitness && !it->GetTx().wit.IsNull()) - return false; - if (fNeedSizeAccounting) { - uint64_t nTxSize = ::GetSerializeSize(it->GetTx(), SER_NETWORK, PROTOCOL_VERSION); - if (nPotentialBlockSize + nTxSize >= nBlockMaxSize) { - return false; - } - nPotentialBlockSize += nTxSize; - } } return true; } @@ -421,7 +408,7 @@ void BlockAssembler::addPackageTxs() packageSigOps = modit->nSigOpCountWithAncestors; } - if (packageFees < ::minRelayTxFee.GetFee(packageSize) && nBlockSize >= nBlockMinSize) { + if (packageFees < ::minRelayTxFee.GetFee(packageSize)) { // Everything else we might consider has a lower fee rate return; } diff --git a/src/miner.h b/src/miner.h index b4059f5c1735..4c8d6ef5b13e 100644 --- a/src/miner.h +++ b/src/miner.h @@ -188,7 +188,7 @@ class BlockAssembler /** Test if a new package would "fit" in the block */ bool TestPackage(uint64_t packageSize, unsigned int packageSigOps); /** Perform checks on each transaction in a package: - * locktime, premature-witness, serialized size (if necessary) + * locktime * These checks should always succeed, and they're here * only as an extra check in case of suboptimal node configuration */ bool TestPackageTransactions(const CTxMemPool::setEntries& package); From a9f0aedb3465c0241febbead9657ca5a87fe00da Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 18 Jul 2016 09:04:31 +0200 Subject: [PATCH 44/47] Merge #8320: Fix 0.12 release notes on block relaying d6dc1bc Fix 0.12 release notes on block relaying (Krzysztof Jurewicz) --- doc/release-notes/bitcoin/release-notes-0.12.0.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/doc/release-notes/bitcoin/release-notes-0.12.0.md b/doc/release-notes/bitcoin/release-notes-0.12.0.md index 85c020a9cd0b..cf74a1797520 100644 --- a/doc/release-notes/bitcoin/release-notes-0.12.0.md +++ b/doc/release-notes/bitcoin/release-notes-0.12.0.md @@ -104,9 +104,6 @@ announcing their headers directly, instead of just announcing the hash. In a reorganization, all new headers are sent, instead of just the new tip. This can often prevent an extra roundtrip before the actual block is downloaded. -With this change, pruning nodes are now able to relay new blocks to compatible -peers. - Memory pool limiting -------------------- @@ -188,6 +185,14 @@ the OP_RETURN. The limit on OP_RETURN output size is now applied to the entire serialized scriptPubKey, 83 bytes by default. (the previous 80 byte default plus three bytes overhead) +Relay: New and only new blocks relayed when pruning +--------------------------------------------------- + +When running in pruned mode, the client will now relay new blocks. When +responding to the `getblocks` message, only hashes of blocks that are on disk +and are likely to remain there for some reasonable time window (1 hour) will be +returned (previously all relevant hashes were returned). + Relay and Mining: Priority transactions --------------------------------------- @@ -887,5 +892,3 @@ Thanks to everyone who directly contributed to this release: - zathras-crypto As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/). - - From f8a7a2c88d7aafba739bb753a06c6eb8c3ce9e57 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Wed, 27 Dec 2017 19:02:57 +0100 Subject: [PATCH 45/47] Move bitcoin.ico/png and bitcoin_testnet.ico/png one dir up This also overwrites/dashifies icons/bitcoin_testnet.ico which was introduced in Bitcoin #8285. The icons were previously located in the drkblue theme directory while the path used in dash.qrc was poining to the non-theme icons directory. Also, the icons were never ported to the other themes. This commit moves them one level up until someone actually ports these to the other themes (if ever needed). --- src/qt/res/icons/bitcoin_testnet.ico | Bin 57251 -> 15086 bytes .../icons/{drkblue => }/bitcoin_testnet.png | Bin src/qt/res/icons/drkblue/bitcoin.png | Bin 5046 -> 0 bytes src/qt/res/icons/drkblue/bitcoin_testnet.ico | Bin 15086 -> 0 bytes 4 files changed, 0 insertions(+), 0 deletions(-) rename src/qt/res/icons/{drkblue => }/bitcoin_testnet.png (100%) delete mode 100644 src/qt/res/icons/drkblue/bitcoin.png delete mode 100644 src/qt/res/icons/drkblue/bitcoin_testnet.ico diff --git a/src/qt/res/icons/bitcoin_testnet.ico b/src/qt/res/icons/bitcoin_testnet.ico index 909194ecd2e10985bbca35c3cd26fd1adb4730b8..b86e2a7039463144a4d6270df8b2374eb14d1308 100644 GIT binary patch literal 15086 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 literal 57251 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 N250BL5H*Z+s*3%&l;+rD=4 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 From f61a754020e4922dc87f29a2f20a6ea6b86214fb Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Wed, 27 Dec 2017 21:53:06 +0100 Subject: [PATCH 46/47] Disable free transactions in TestPackageSelection Dash allows free transactions by default, mixing up the expected ordering of transactions in TestPackageSelection --- src/test/miner_tests.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 5cb7575921a8..5740e79d1143 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -78,6 +78,9 @@ bool TestSequenceLocks(const CTransaction &tx, int flags) // Note that this test assumes blockprioritysize is 0. void TestPackageSelection(const CChainParams& chainparams, CScript scriptPubKey, std::vector& txFirst) { + // Disable free transactions, otherwise TX selection is non-deterministic + SoftSetArg("-blockprioritysize", "0"); + // Test the ancestor feerate transaction selection. TestMemPoolEntryHelper entry; From 9c2e970858812bcd8a96c58982a72cde8b3298dd Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Thu, 28 Dec 2017 15:52:20 +0100 Subject: [PATCH 47/47] Fix review nits --- contrib/debian/dashd.bash-completion | 2 +- doc/release-process.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/debian/dashd.bash-completion b/contrib/debian/dashd.bash-completion index da0bc29409b9..e2f51e6f6533 100644 --- a/contrib/debian/dashd.bash-completion +++ b/contrib/debian/dashd.bash-completion @@ -1,2 +1,2 @@ contrib/dashd.bash-completion dashd -contrib/dash-cli.bash-completion dash-cli \ No newline at end of file +contrib/dash-cli.bash-completion dash-cli diff --git a/doc/release-process.md b/doc/release-process.md index fb8f7d1b2f8e..bc8dacc64011 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -1,7 +1,7 @@ Release Process ==================== -* Update translations (ping wumpus on IRC) see [translation_process.md](https://github.com/dashpay/dash/blob/master/doc/translation_process.md#synchronising-translations). +* Update translations, see [translation_process.md](https://github.com/dashpay/dash/blob/master/doc/translation_process.md#synchronising-translations). * Update hardcoded [seeds](/contrib/seeds) * * *