diff --git a/.github/workflows/dev-builds.yaml b/.github/workflows/dev-builds.yaml index 1e354b982f..dc1ec6600b 100644 --- a/.github/workflows/dev-builds.yaml +++ b/.github/workflows/dev-builds.yaml @@ -94,10 +94,10 @@ jobs: - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f - name: Build and package - run: TARGETS="x86_64-apple-darwin11" ./make.sh docker-release-git + run: TARGETS="x86_64-apple-darwin18" ./make.sh docker-release-git - - name: Publish artifact - x86_64-apple-darwin11 + - name: Publish artifact - x86_64-apple-darwin18 uses: actions/upload-artifact@e448a9b857ee2131e752b06002bf0e093c65e571 with: - name: defichain-${{ env.BUILD_VERSION }}-x86_64-apple-darwin11 - path: ./build/defichain-${{ env.BUILD_VERSION }}-x86_64-apple-darwin11.tar.gz + name: defichain-${{ env.BUILD_VERSION }}-x86_64-apple-darwin18 + path: ./build/defichain-${{ env.BUILD_VERSION }}-x86_64-apple-darwin18.tar.gz diff --git a/build-aux/m4/ax_boost_chrono.m4 b/build-aux/m4/ax_boost_chrono.m4 deleted file mode 100644 index 6ea77b9b3e..0000000000 --- a/build-aux/m4/ax_boost_chrono.m4 +++ /dev/null @@ -1,118 +0,0 @@ -# =========================================================================== -# https://www.gnu.org/software/autoconf-archive/ax_boost_chrono.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_BOOST_CHRONO -# -# DESCRIPTION -# -# Test for Chrono library from the Boost C++ libraries. The macro requires -# a preceding call to AX_BOOST_BASE. Further documentation is available at -# . -# -# This macro calls: -# -# AC_SUBST(BOOST_CHRONO_LIB) -# -# And sets: -# -# HAVE_BOOST_CHRONO -# -# LICENSE -# -# Copyright (c) 2012 Xiyue Deng -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 4 - -AC_DEFUN([AX_BOOST_CHRONO], -[ - AC_ARG_WITH([boost-chrono], - AS_HELP_STRING([--with-boost-chrono@<:@=special-lib@:>@], - [use the Chrono library from boost - it is possible to specify a certain library for the linker - e.g. --with-boost-chrono=boost_chrono-gcc-mt ]), - [ - if test "$withval" = "no"; then - want_boost="no" - elif test "$withval" = "yes"; then - want_boost="yes" - ax_boost_user_chrono_lib="" - else - want_boost="yes" - ax_boost_user_chrono_lib="$withval" - fi - ], - [want_boost="yes"] - ) - - if test "x$want_boost" = "xyes"; then - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([AC_CANONICAL_BUILD]) - CPPFLAGS_SAVED="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" - export CPPFLAGS - - LDFLAGS_SAVED="$LDFLAGS" - LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" - export LDFLAGS - - AC_CACHE_CHECK(whether the Boost::Chrono library is available, - ax_cv_boost_chrono, - [AC_LANG_PUSH([C++]) - CXXFLAGS_SAVE=$CXXFLAGS - - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], - [[boost::chrono::system_clock::time_point* time = new boost::chrono::system_clock::time_point; delete time;]])], - ax_cv_boost_chrono=yes, ax_cv_boost_chrono=no) - CXXFLAGS=$CXXFLAGS_SAVE - AC_LANG_POP([C++]) - ]) - if test "x$ax_cv_boost_chrono" = "xyes"; then - AC_SUBST(BOOST_CPPFLAGS) - - AC_DEFINE(HAVE_BOOST_CHRONO,,[define if the Boost::Chrono library is available]) - BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` - - LDFLAGS_SAVE=$LDFLAGS - if test "x$ax_boost_user_chrono_lib" = "x"; then - for libextension in `ls $BOOSTLIBDIR/libboost_chrono*.so* $BOOSTLIBDIR/libboost_chrono*.dylib* $BOOSTLIBDIR/libboost_chrono*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_chrono.*\)\.so.*$;\1;' -e 's;^lib\(boost_chrono.*\)\.dylib.*$;\1;' -e 's;^lib\(boost_chrono.*\)\.a.*$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, exit, - [BOOST_CHRONO_LIB="-l$ax_lib"; AC_SUBST(BOOST_CHRONO_LIB) link_chrono="yes"; break], - [link_chrono="no"]) - done - if test "x$link_chrono" != "xyes"; then - for libextension in `ls $BOOSTLIBDIR/boost_chrono*.dll* $BOOSTLIBDIR/boost_chrono*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_chrono.*\)\.dll.*$;\1;' -e 's;^\(boost_chrono.*\)\.a.*$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, exit, - [BOOST_CHRONO_LIB="-l$ax_lib"; AC_SUBST(BOOST_CHRONO_LIB) link_chrono="yes"; break], - [link_chrono="no"]) - done - fi - - else - for ax_lib in $ax_boost_user_chrono_lib boost_chrono-$ax_boost_user_chrono_lib; do - AC_CHECK_LIB($ax_lib, exit, - [BOOST_CHRONO_LIB="-l$ax_lib"; AC_SUBST(BOOST_CHRONO_LIB) link_chrono="yes"; break], - [link_chrono="no"]) - done - - fi - if test "x$ax_lib" = "x"; then - AC_MSG_ERROR(Could not find a version of the library!) - fi - if test "x$link_chrono" = "xno"; then - AC_MSG_ERROR(Could not link against $ax_lib !) - fi - fi - - CPPFLAGS="$CPPFLAGS_SAVED" - LDFLAGS="$LDFLAGS_SAVED" - fi -]) diff --git a/build-aux/m4/ax_boost_thread.m4 b/build-aux/m4/ax_boost_thread.m4 deleted file mode 100644 index 9f0bd0b23c..0000000000 --- a/build-aux/m4/ax_boost_thread.m4 +++ /dev/null @@ -1,150 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_boost_thread.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_BOOST_THREAD -# -# DESCRIPTION -# -# Test for Thread library from the Boost C++ libraries. The macro requires -# a preceding call to AX_BOOST_BASE. Further documentation is available at -# . -# -# This macro calls: -# -# AC_SUBST(BOOST_THREAD_LIB) -# -# And sets: -# -# HAVE_BOOST_THREAD -# -# LICENSE -# -# Copyright (c) 2009 Thomas Porschberg -# Copyright (c) 2009 Michael Tindal -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 27 - -AC_DEFUN([AX_BOOST_THREAD], -[ - AC_ARG_WITH([boost-thread], - AS_HELP_STRING([--with-boost-thread@<:@=special-lib@:>@], - [use the Thread library from boost - it is possible to specify a certain library for the linker - e.g. --with-boost-thread=boost_thread-gcc-mt ]), - [ - if test "$withval" = "no"; then - want_boost="no" - elif test "$withval" = "yes"; then - want_boost="yes" - ax_boost_user_thread_lib="" - else - want_boost="yes" - ax_boost_user_thread_lib="$withval" - fi - ], - [want_boost="yes"] - ) - - if test "x$want_boost" = "xyes"; then - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([AC_CANONICAL_BUILD]) - CPPFLAGS_SAVED="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" - export CPPFLAGS - - LDFLAGS_SAVED="$LDFLAGS" - LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" - export LDFLAGS - - AC_CACHE_CHECK(whether the Boost::Thread library is available, - ax_cv_boost_thread, - [AC_LANG_PUSH([C++]) - CXXFLAGS_SAVE=$CXXFLAGS - - if test "x$host_os" = "xsolaris" ; then - CXXFLAGS="-pthreads $CXXFLAGS" - elif test "x$host_os" = "xmingw32" ; then - CXXFLAGS="-mthreads $CXXFLAGS" - else - CXXFLAGS="-pthread $CXXFLAGS" - fi - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], - [[boost::thread_group thrds; - return 0;]])], - ax_cv_boost_thread=yes, ax_cv_boost_thread=no) - CXXFLAGS=$CXXFLAGS_SAVE - AC_LANG_POP([C++]) - ]) - if test "x$ax_cv_boost_thread" = "xyes"; then - if test "x$host_os" = "xsolaris" ; then - BOOST_CPPFLAGS="-pthreads $BOOST_CPPFLAGS" - elif test "x$host_os" = "xmingw32" ; then - BOOST_CPPFLAGS="-mthreads $BOOST_CPPFLAGS" - else - BOOST_CPPFLAGS="-pthread $BOOST_CPPFLAGS" - fi - - AC_SUBST(BOOST_CPPFLAGS) - - AC_DEFINE(HAVE_BOOST_THREAD,,[define if the Boost::Thread library is available]) - BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` - - LDFLAGS_SAVE=$LDFLAGS - case "x$host_os" in - *bsd* ) - LDFLAGS="-pthread $LDFLAGS" - break; - ;; - esac - if test "x$ax_boost_user_thread_lib" = "x"; then - ax_lib= - for libextension in `ls -r $BOOSTLIBDIR/libboost_thread* 2>/dev/null | sed 's,.*/lib,,' | sed 's,\..*,,'`; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, exit, - [BOOST_THREAD_LIB="-l$ax_lib"; AC_SUBST(BOOST_THREAD_LIB) link_thread="yes"; break], - [link_thread="no"]) - done - if test "x$link_thread" != "xyes"; then - for libextension in `ls -r $BOOSTLIBDIR/boost_thread* 2>/dev/null | sed 's,.*/,,' | sed 's,\..*,,'`; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, exit, - [BOOST_THREAD_LIB="-l$ax_lib"; AC_SUBST(BOOST_THREAD_LIB) link_thread="yes"; break], - [link_thread="no"]) - done - fi - - else - for ax_lib in $ax_boost_user_thread_lib boost_thread-$ax_boost_user_thread_lib; do - AC_CHECK_LIB($ax_lib, exit, - [BOOST_THREAD_LIB="-l$ax_lib"; AC_SUBST(BOOST_THREAD_LIB) link_thread="yes"; break], - [link_thread="no"]) - done - - fi - if test "x$ax_lib" = "x"; then - AC_MSG_ERROR(Could not find a version of the boost_thread library!) - fi - if test "x$link_thread" = "xno"; then - AC_MSG_ERROR(Could not link against $ax_lib !) - else - case "x$host_os" in - *bsd* ) - BOOST_LDFLAGS="-pthread $BOOST_LDFLAGS" - break; - ;; - esac - - fi - fi - - CPPFLAGS="$CPPFLAGS_SAVED" - LDFLAGS="$LDFLAGS_SAVED" - fi -]) diff --git a/build-aux/m4/ax_cxx_compile_stdcxx.m4 b/build-aux/m4/ax_cxx_compile_stdcxx.m4 index f147cee3b1..f0a3badf59 100644 --- a/build-aux/m4/ax_cxx_compile_stdcxx.m4 +++ b/build-aux/m4/ax_cxx_compile_stdcxx.m4 @@ -45,9 +45,9 @@ dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro dnl (serial version number 13). AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl - m4_if([$1], [11], [], - [$1], [14], [], - [$1], [17], [m4_fatal([support for C++17 not yet implemented in AX_CXX_COMPILE_STDCXX])], + m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], + [$1], [14], [ax_cxx_compile_alternatives="14 1y"], + [$1], [17], [ax_cxx_compile_alternatives="17 1z"], [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl m4_if([$2], [], [], [$2], [ext], [], @@ -57,26 +57,13 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], [$3], [optional], [ax_cxx_compile_cxx$1_required=false], [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) - m4_if([$4], [], [ax_cxx_compile_cxx$1_try_default=true], - [$4], [default], [ax_cxx_compile_cxx$1_try_default=true], - [$4], [nodefault], [ax_cxx_compile_cxx$1_try_default=false], - [m4_fatal([invalid fourth argument `$4' to AX_CXX_COMPILE_STDCXX])]) AC_LANG_PUSH([C++])dnl ac_success=no - m4_if([$4], [nodefault], [], [dnl - AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, - ax_cv_cxx_compile_cxx$1, - [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], - [ax_cv_cxx_compile_cxx$1=yes], - [ax_cv_cxx_compile_cxx$1=no])]) - if test x$ax_cv_cxx_compile_cxx$1 = xyes; then - ac_success=yes - fi]) - m4_if([$2], [noext], [], [dnl if test x$ac_success = xno; then - for switch in -std=gnu++$1 -std=gnu++0x; do + for alternative in ${ax_cxx_compile_alternatives}; do + switch="-std=gnu++${alternative}" cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, $cachevar, @@ -102,22 +89,27 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl dnl HP's aCC needs +std=c++11 according to: dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf dnl Cray's crayCC needs "-h std=c++11" - for switch in -std=c++$1 -std=c++0x +std=c++$1 "-h std=c++$1"; do - cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) - AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, - $cachevar, - [ac_save_CXX="$CXX" - CXX="$CXX $switch" - AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], - [eval $cachevar=yes], - [eval $cachevar=no]) - CXX="$ac_save_CXX"]) - if eval test x\$$cachevar = xyes; then - CXX="$CXX $switch" - if test -n "$CXXCPP" ; then - CXXCPP="$CXXCPP $switch" + for alternative in ${ax_cxx_compile_alternatives}; do + for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break fi - ac_success=yes + done + if test x$ac_success = xyes; then break fi done @@ -154,6 +146,11 @@ m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 ) +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 +) dnl Tests for new features in C++11 @@ -191,11 +188,13 @@ namespace cxx11 struct Base { + virtual ~Base() {} virtual void f() {} }; struct Derived : public Base { + virtual ~Derived() override {} virtual void f() override {} }; @@ -524,7 +523,7 @@ namespace cxx14 } - namespace test_digit_seperators + namespace test_digit_separators { constexpr auto ten_million = 100'000'000; @@ -566,3 +565,287 @@ namespace cxx14 #endif // __cplusplus >= 201402L ]]) + + +dnl Tests for new features in C++17 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[ +// If the compiler admits that it is not ready for C++17, why torture it? +// Hopefully, this will speed up the test. +#ifndef __cplusplus +#error "This is not a C++ compiler" +#elif __cplusplus < 201703L +#error "This is not a C++17 compiler" +#else +#include +#include +#include +namespace cxx17 +{ + namespace test_constexpr_lambdas + { + constexpr int foo = [](){return 42;}(); + } + namespace test::nested_namespace::definitions + { + } + namespace test_fold_expression + { + template + int multiply(Args... args) + { + return (args * ... * 1); + } + template + bool all(Args... args) + { + return (args && ...); + } + } + namespace test_extended_static_assert + { + static_assert (true); + } + namespace test_auto_brace_init_list + { + auto foo = {5}; + auto bar {5}; + static_assert(std::is_same, decltype(foo)>::value); + static_assert(std::is_same::value); + } + namespace test_typename_in_template_template_parameter + { + template typename X> struct D; + } + namespace test_fallthrough_nodiscard_maybe_unused_attributes + { + int f1() + { + return 42; + } + [[nodiscard]] int f2() + { + [[maybe_unused]] auto unused = f1(); + switch (f1()) + { + case 17: + f1(); + [[fallthrough]]; + case 42: + f1(); + } + return f1(); + } + } + namespace test_extended_aggregate_initialization + { + struct base1 + { + int b1, b2 = 42; + }; + struct base2 + { + base2() { + b3 = 42; + } + int b3; + }; + struct derived : base1, base2 + { + int d; + }; + derived d1 {{1, 2}, {}, 4}; // full initialization + derived d2 {{}, {}, 4}; // value-initialized bases + } + namespace test_general_range_based_for_loop + { + struct iter + { + int i; + int& operator* () + { + return i; + } + const int& operator* () const + { + return i; + } + iter& operator++() + { + ++i; + return *this; + } + }; + struct sentinel + { + int i; + }; + bool operator== (const iter& i, const sentinel& s) + { + return i.i == s.i; + } + bool operator!= (const iter& i, const sentinel& s) + { + return !(i == s); + } + struct range + { + iter begin() const + { + return {0}; + } + sentinel end() const + { + return {5}; + } + }; + void f() + { + range r {}; + for (auto i : r) + { + [[maybe_unused]] auto v = i; + } + } + } + namespace test_lambda_capture_asterisk_this_by_value + { + struct t + { + int i; + int foo() + { + return [*this]() + { + return i; + }(); + } + }; + } + namespace test_enum_class_construction + { + enum class byte : unsigned char + {}; + byte foo {42}; + } + namespace test_constexpr_if + { + template + int f () + { + if constexpr(cond) + { + return 13; + } + else + { + return 42; + } + } + } + namespace test_selection_statement_with_initializer + { + int f() + { + return 13; + } + int f2() + { + if (auto i = f(); i > 0) + { + return 3; + } + switch (auto i = f(); i + 4) + { + case 17: + return 2; + default: + return 1; + } + } + } + namespace test_template_argument_deduction_for_class_templates + { + template + struct pair + { + pair (T1 p1, T2 p2) + : m1 {p1}, + m2 {p2} + {} + T1 m1; + T2 m2; + }; + void f() + { + [[maybe_unused]] auto p = pair{13, 42u}; + } + } + namespace test_non_type_auto_template_parameters + { + template + struct B + {}; + B<5> b1; + B<'a'> b2; + } + namespace test_structured_bindings + { + int arr[2] = { 1, 2 }; + std::pair pr = { 1, 2 }; + auto f1() -> int(&)[2] + { + return arr; + } + auto f2() -> std::pair& + { + return pr; + } + struct S + { + int x1 : 2; + volatile double y1; + }; + S f3() + { + return {}; + } + auto [ x1, y1 ] = f1(); + auto& [ xr1, yr1 ] = f1(); + auto [ x2, y2 ] = f2(); + auto& [ xr2, yr2 ] = f2(); + const auto [ x3, y3 ] = f3(); + } + namespace test_exception_spec_type_system + { + struct Good {}; + struct Bad {}; + void g1() noexcept; + void g2(); + template + Bad + f(T*, T*); + template + Good + f(T1*, T2*); + static_assert (std::is_same_v); + } + namespace test_inline_variables + { + template void f(T) + {} + template inline T g(T) + { + return T{}; + } + template<> inline void f<>(int) + {} + template<> int g<>(int) + { + return 5; + } + } +} // namespace cxx17 +#endif // __cplusplus < 201703L +]]) + diff --git a/build_msvc/defi_config.h b/build_msvc/defi_config.h index 89f27811fd..02f91daed8 100644 --- a/build_msvc/defi_config.h +++ b/build_msvc/defi_config.h @@ -43,9 +43,6 @@ /* define if the Boost library is available */ #define HAVE_BOOST /**/ -/* define if the Boost::Chrono library is available */ -#define HAVE_BOOST_CHRONO /**/ - /* define if the Boost::Filesystem library is available */ #define HAVE_BOOST_FILESYSTEM /**/ @@ -55,9 +52,6 @@ /* define if the Boost::System library is available */ #define HAVE_BOOST_SYSTEM /**/ -/* define if the Boost::Thread library is available */ -#define HAVE_BOOST_THREAD /**/ - /* define if the Boost::Unit_Test_Framework library is available */ #define HAVE_BOOST_UNIT_TEST_FRAMEWORK /**/ @@ -330,12 +324,6 @@ /* Define if the visibility attribute is supported. */ #define HAVE_VISIBILITY_ATTRIBUTE 1 -/* Define this symbol if boost sleep works */ -/* #undef HAVE_WORKING_BOOST_SLEEP */ - -/* Define this symbol if boost sleep_for works */ -#define HAVE_WORKING_BOOST_SLEEP_FOR 1 - /* Define to the sub-directory where libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" diff --git a/ci/test/00_setup_env_amd64_asan.sh b/ci/test/00_setup_env_amd64_asan.sh index 4aa3c630c3..a524e276d9 100644 --- a/ci/test/00_setup_env_amd64_asan.sh +++ b/ci/test/00_setup_env_amd64_asan.sh @@ -7,7 +7,7 @@ export LC_ALL=C.UTF-8 export HOST=x86_64-unknown-linux-gnu -export PACKAGES="clang llvm python3-zmq qtbase5-dev qttools5-dev-tools libssl1.0-dev libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-test-dev libboost-thread-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev libprotobuf-dev protobuf-compiler libqrencode-dev" +export PACKAGES="clang llvm python3-zmq qtbase5-dev qttools5-dev-tools libssl1.0-dev libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-test-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev libprotobuf-dev protobuf-compiler libqrencode-dev" export NO_DEPENDS=1 export GOAL="install" export DEFI_CONFIG="--enable-zmq --with-incompatible-bdb CPPFLAGS=-DDEBUG_LOCKORDER --with-sanitizers=address,integer,undefined CC=clang CXX=clang++" diff --git a/ci/test/00_setup_env_amd64_fuzz.sh b/ci/test/00_setup_env_amd64_fuzz.sh index bfc46ae7ce..33081a1ab4 100644 --- a/ci/test/00_setup_env_amd64_fuzz.sh +++ b/ci/test/00_setup_env_amd64_fuzz.sh @@ -7,7 +7,7 @@ export LC_ALL=C.UTF-8 export HOST=x86_64-unknown-linux-gnu -export PACKAGES="clang llvm python3 libssl1.0-dev libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-test-dev libboost-thread-dev" +export PACKAGES="clang llvm python3 libssl1.0-dev libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-test-dev" export NO_DEPENDS=1 export RUN_UNIT_TESTS=false export RUN_FUNCTIONAL_TESTS=false diff --git a/ci/test/00_setup_env_amd64_trusty.sh b/ci/test/00_setup_env_amd64_trusty.sh index 9b32c66a9a..9d37cdbf5c 100644 --- a/ci/test/00_setup_env_amd64_trusty.sh +++ b/ci/test/00_setup_env_amd64_trusty.sh @@ -8,7 +8,7 @@ export LC_ALL=C.UTF-8 export HOST=x86_64-unknown-linux-gnu export DOCKER_NAME_TAG=ubuntu:14.04 -export PACKAGES="python3-zmq qtbase5-dev qttools5-dev-tools libicu-dev libpng-dev libssl-dev libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-test-dev libboost-thread-dev libdb5.1++-dev libzmq3-dev libprotobuf-dev protobuf-compiler libqrencode-dev" +export PACKAGES="python3-zmq qtbase5-dev qttools5-dev-tools libicu-dev libpng-dev libssl-dev libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-test-dev libdb5.1++-dev libzmq3-dev libprotobuf-dev protobuf-compiler libqrencode-dev" export NO_DEPENDS=1 export RUN_FUNCTIONAL_TESTS=false export GOAL="install" diff --git a/ci/test/00_setup_env_amd64_tsan.sh b/ci/test/00_setup_env_amd64_tsan.sh index 6a5ef7b570..6dec401dd0 100644 --- a/ci/test/00_setup_env_amd64_tsan.sh +++ b/ci/test/00_setup_env_amd64_tsan.sh @@ -8,7 +8,7 @@ export LC_ALL=C.UTF-8 export HOST=x86_64-unknown-linux-gnu export DOCKER_NAME_TAG=ubuntu:16.04 -export PACKAGES="clang llvm python3-zmq qtbase5-dev qttools5-dev-tools libssl-dev libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-test-dev libboost-thread-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev libprotobuf-dev protobuf-compiler libqrencode-dev" +export PACKAGES="clang llvm python3-zmq qtbase5-dev qttools5-dev-tools libssl-dev libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-test-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev libprotobuf-dev protobuf-compiler libqrencode-dev" export NO_DEPENDS=1 export GOAL="install" export DEFI_CONFIG="--enable-zmq --disable-wallet CPPFLAGS=-DDEBUG_LOCKORDER --with-sanitizers=thread --disable-hardening --disable-asm CC=clang CXX=clang++" diff --git a/ci/test/00_setup_env_mac.sh b/ci/test/00_setup_env_mac.sh index 1da55be1dd..e6bfbd6169 100644 --- a/ci/test/00_setup_env_mac.sh +++ b/ci/test/00_setup_env_mac.sh @@ -6,9 +6,10 @@ export LC_ALL=C.UTF-8 -export HOST=x86_64-apple-darwin14 +export HOST=x86_64-apple-darwin18 export PACKAGES="cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python3-dev python3-setuptools" -export OSX_SDK=10.11 +export XCODE_VERSION=11.3.1 +export XCODE_BUILD_ID=11C505 export RUN_UNIT_TESTS=false export RUN_FUNCTIONAL_TESTS=false export GOAL="deploy" diff --git a/ci/test/05_before_script.sh b/ci/test/05_before_script.sh index 202b7ef3b7..7b97902919 100755 --- a/ci/test/05_before_script.sh +++ b/ci/test/05_before_script.sh @@ -10,11 +10,14 @@ DOCKER_EXEC echo \> \$HOME/.defi # Make sure default datadir does not exist and mkdir -p depends/SDKs depends/sdk-sources -if [ -n "$OSX_SDK" ] && [ ! -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then - curl --location --fail $SDK_URL/MacOSX${OSX_SDK}.sdk.tar.gz -o depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz +OSX_SDK_BASENAME="Xcode-${XCODE_VERSION}-${XCODE_BUILD_ID}-extracted-SDK-with-libcxx-headers.tar.gz" +OSX_SDK_PATH="${DEPENDS_DIR}/sdk-sources/${OSX_SDK_BASENAME}" + +if [ -n "$XCODE_VERSION" ] && [ ! -f "$OSX_SDK_PATH" ]; then + curl --location --fail "${SDK_URL}/${OSX_SDK_BASENAME}" -o "$OSX_SDK_PATH" fi -if [ -n "$OSX_SDK" ] && [ -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then - tar -C depends/SDKs -xf depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz +if [ -n "$XCODE_VERSION" ] && [ -f "$OSX_SDK_PATH" ]; then + DOCKER_EXEC tar -C "${DEPENDS_DIR}/SDKs" -xf "$OSX_SDK_PATH" fi if [[ $HOST = *-mingw32 ]]; then DOCKER_EXEC update-alternatives --set $HOST-g++ \$\(which $HOST-g++-posix\) diff --git a/configure.ac b/configure.ac index fd6027de8a..89e8249078 100644 --- a/configure.ac +++ b/configure.ac @@ -61,8 +61,10 @@ case $host in lt_cv_deplibs_check_method="pass_all" ;; esac -dnl Require C++11 compiler (no GNU extensions) -AX_CXX_COMPILE_STDCXX([11], [noext], [mandatory], [nodefault]) + +dnl Require C++17 compiler (no GNU extensions) +AX_CXX_COMPILE_STDCXX([17], [noext], [mandatory]) + dnl Check if -latomic is required for CHECK_ATOMIC @@ -495,7 +497,7 @@ case $host in AC_MSG_ERROR("windres not found") fi - CPPFLAGS="$CPPFLAGS -D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -D_WIN32_WINNT=0x0601" + CPPFLAGS="$CPPFLAGS -D_MT -DWIN32 -D_WINDOWS -D_WIN32_WINNT=0x0601" LEVELDB_TARGET_FLAGS="-DOS_WINDOWS" if test "x$CXXFLAGS_overridden" = "xno"; then CXXFLAGS="$CXXFLAGS -w" @@ -997,8 +999,6 @@ if test x$want_boost = xno; then fi AX_BOOST_SYSTEM AX_BOOST_FILESYSTEM -AX_BOOST_THREAD -AX_BOOST_CHRONO dnl Boost 1.56 through 1.62 allow using std::atomic instead of its own atomic dnl counter implementations. In 1.63 and later the std::atomic approach is default. @@ -1065,7 +1065,7 @@ fi if test x$use_boost = xyes; then -BOOST_LIBS="$BOOST_LDFLAGS $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB $BOOST_THREAD_LIB $BOOST_CHRONO_LIB" +BOOST_LIBS="$BOOST_LDFLAGS $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB" dnl If boost (prior to 1.57) was built without c++11, it emulated scoped enums @@ -1103,57 +1103,6 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ LIBS="$TEMP_LIBS" CPPFLAGS="$TEMP_CPPFLAGS" -dnl Boost >= 1.50 uses sleep_for rather than the now-deprecated sleep, however -dnl it was broken from 1.50 to 1.52 when backed by nanosleep. Use sleep_for if -dnl a working version is available, else fall back to sleep. sleep was removed -dnl after 1.56. -dnl If neither is available, abort. -TEMP_LIBS="$LIBS" -LIBS="$BOOST_LIBS $LIBS" -TEMP_CPPFLAGS="$CPPFLAGS" -CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" -AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - #include - #include - ]],[[ - #if BOOST_VERSION >= 105000 && (!defined(BOOST_HAS_NANOSLEEP) || BOOST_VERSION >= 105200) - boost::this_thread::sleep_for(boost::chrono::milliseconds(0)); - #else - choke me - #endif - ]])], - [boost_sleep=yes; - AC_DEFINE(HAVE_WORKING_BOOST_SLEEP_FOR, 1, [Define this symbol if boost sleep_for works])], - [boost_sleep=no]) -LIBS="$TEMP_LIBS" -CPPFLAGS="$TEMP_CPPFLAGS" - -if test x$boost_sleep != xyes; then -TEMP_LIBS="$LIBS" -LIBS="$BOOST_LIBS $LIBS" -TEMP_CPPFLAGS="$CPPFLAGS" -CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" -AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - #include - #include - #include - ]],[[ - #if BOOST_VERSION <= 105600 - boost::this_thread::sleep(boost::posix_time::milliseconds(0)); - #else - choke me - #endif - ]])], - [boost_sleep=yes; AC_DEFINE(HAVE_WORKING_BOOST_SLEEP, 1, [Define this symbol if boost sleep works])], - [boost_sleep=no]) -LIBS="$TEMP_LIBS" -CPPFLAGS="$TEMP_CPPFLAGS" -fi - -if test x$boost_sleep != xyes; then - AC_MSG_ERROR(No working boost sleep implementation found.) -fi - fi if test x$use_pkgconfig = xyes; then diff --git a/contrib/dockerfiles/x86_64-apple-darwin11.dockerfile b/contrib/dockerfiles/x86_64-apple-darwin18.dockerfile similarity index 98% rename from contrib/dockerfiles/x86_64-apple-darwin11.dockerfile rename to contrib/dockerfiles/x86_64-apple-darwin18.dockerfile index c42737cae4..10c17fab2a 100644 --- a/contrib/dockerfiles/x86_64-apple-darwin11.dockerfile +++ b/contrib/dockerfiles/x86_64-apple-darwin18.dockerfile @@ -1,4 +1,4 @@ -ARG TARGET=x86_64-apple-darwin11 +ARG TARGET=x86_64-apple-darwin18 # ----------- FROM ubuntu:18.04 as builder-base diff --git a/depends/README.md b/depends/README.md index 69bc2a0222..e18ba57967 100644 --- a/depends/README.md +++ b/depends/README.md @@ -25,7 +25,7 @@ Common `host-platform-triplets` for cross compilation are: - `i686-pc-linux-gnu` for Linux 32 bit - `x86_64-pc-linux-gnu` for x86 Linux - `x86_64-w64-mingw32` for Win64 -- `x86_64-apple-darwin14` for macOS +- `x86_64-apple-darwin18` for macOS - `arm-linux-gnueabihf` for Linux ARM 32 bit - `aarch64-linux-gnu` for Linux ARM 64 bit - `riscv32-linux-gnu` for Linux RISC-V 32 bit diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk index a1c943d60b..b14ce09cb8 100644 --- a/depends/hosts/darwin.mk +++ b/depends/hosts/darwin.mk @@ -1,7 +1,10 @@ -OSX_MIN_VERSION=10.10 -OSX_SDK_VERSION=10.11 -OSX_SDK=$(SDK_PATH)/MacOSX$(OSX_SDK_VERSION).sdk -LD64_VERSION=253.9 +OSX_MIN_VERSION=10.14 +OSX_SDK_VERSION=10.15.1 +XCODE_VERSION=11.3.1 +XCODE_BUILD_ID=11C505 +OSX_SDK=$(SDK_PATH)/Xcode-$(XCODE_VERSION)-$(XCODE_BUILD_ID)-extracted-SDK-with-libcxx-headers +LD64_VERSION=530 + 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/bdb.mk b/depends/packages/bdb.mk index 6cdb79592b..f983c754ab 100644 --- a/depends/packages/bdb.mk +++ b/depends/packages/bdb.mk @@ -9,7 +9,7 @@ define $(package)_set_vars $(package)_config_opts=--disable-shared --enable-cxx --disable-replication $(package)_config_opts_mingw32=--enable-mingw $(package)_config_opts_linux=--with-pic -$(package)_cxxflags=-std=c++11 +$(package)_cxxflags=-std=c++17 $(package)_cppflags_mingw32=-DUNICODE -D_UNICODE endef diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk index c84c5d0ab1..3188720254 100644 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -19,8 +19,8 @@ $(package)_toolset_$(host_os)=gcc $(package)_archiver_$(host_os)=$($(package)_ar) $(package)_toolset_darwin=darwin $(package)_archiver_darwin=$($(package)_libtool) -$(package)_config_libraries=chrono,filesystem,system,thread,test -$(package)_cxxflags=-std=c++11 -fvisibility=hidden +$(package)_config_libraries=filesystem,system,test +$(package)_cxxflags=-std=c++17 -fvisibility=hidden $(package)_cxxflags_linux=-fPIC endef diff --git a/depends/packages/native_cctools.mk b/depends/packages/native_cctools.mk index a065256c1c..74c32c4e38 100644 --- a/depends/packages/native_cctools.mk +++ b/depends/packages/native_cctools.mk @@ -1,45 +1,55 @@ package=native_cctools -$(package)_version=807d6fd1be5d2224872e381870c0a75387fe05e6 -$(package)_download_path=https://github.com/theuni/cctools-port/archive +$(package)_version=4da2f3b485bcf4cef526f30c0b8c0bcda99cdbb4 +$(package)_download_path=https://github.com/tpoechtrager/cctools-port/archive $(package)_file_name=$($(package)_version).tar.gz -$(package)_sha256_hash=a09c9ba4684670a0375e42d9d67e7f12c1f62581a27f28f7c825d6d7032ccc6a +$(package)_sha256_hash=a2d491c0981cef72fee2b833598f20f42a6c44a7614a61c439bda93d56446fec $(package)_build_subdir=cctools -$(package)_clang_version=3.7.1 -$(package)_clang_download_path=https://llvm.org/releases/$($(package)_clang_version) +$(package)_clang_version=8.0.0 +$(package)_clang_download_path=https://releases.llvm.org/$($(package)_clang_version) $(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)_clang_sha256_hash=9ef854b71949f825362a119bf2597f744836cb571131ae6b721cd102ffea8cd0 + +$(package)_libtapi_version=3efb201881e7a76a21e0554906cf306432539cef +$(package)_libtapi_download_path=https://github.com/tpoechtrager/apple-libtapi/archive +$(package)_libtapi_download_file=$($(package)_libtapi_version).tar.gz +$(package)_libtapi_file_name=$($(package)_libtapi_version).tar.gz +$(package)_libtapi_sha256_hash=380c1ca37cfa04a8699d0887a8d3ee1ad27f3d08baba78887c73b09485c0fbd3 + $(package)_extra_sources=$($(package)_clang_file_name) +$(package)_extra_sources += $($(package)_libtapi_file_name) define $(package)_fetch_cmds $(call fetch_file,$(package),$($(package)_download_path),$($(package)_download_file),$($(package)_file_name),$($(package)_sha256_hash)) && \ -$(call fetch_file,$(package),$($(package)_clang_download_path),$($(package)_clang_download_file),$($(package)_clang_file_name),$($(package)_clang_sha256_hash)) +$(call fetch_file,$(package),$($(package)_clang_download_path),$($(package)_clang_download_file),$($(package)_clang_file_name),$($(package)_clang_sha256_hash)) && \ +$(call fetch_file,$(package),$($(package)_libtapi_download_path),$($(package)_libtapi_download_file),$($(package)_libtapi_file_name),$($(package)_libtapi_sha256_hash)) endef define $(package)_extract_cmds mkdir -p $($(package)_extract_dir) && \ echo "$($(package)_sha256_hash) $($(package)_source)" > $($(package)_extract_dir)/.$($(package)_file_name).hash && \ echo "$($(package)_clang_sha256_hash) $($(package)_source_dir)/$($(package)_clang_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ + echo "$($(package)_libtapi_sha256_hash) $($(package)_source_dir)/$($(package)_libtapi_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ $(build_SHA256SUM) -c $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - mkdir -p toolchain/bin toolchain/lib/clang/3.5/include && \ + mkdir -p toolchain/bin toolchain/lib/clang/$($(package)_clang_version)/include && \ + mkdir -p libtapi && \ + tar --no-same-owner --strip-components=1 -C libtapi -xf $($(package)_source_dir)/$($(package)_libtapi_file_name) && \ tar --no-same-owner --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 && \ tar --no-same-owner --strip-components=1 -xf $($(package)_source) endef define $(package)_set_vars -$(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++ + $(package)_config_opts=--target=$(host) --disable-lto-support --with-libtapi=$($(package)_extract_dir) + $(package)_ldflags+=-Wl,-rpath=\\$$$$$$$$\$$$$$$$$ORIGIN/../lib + $(package)_cc=$($(package)_extract_dir)/toolchain/bin/clang + $(package)_cxx=$($(package)_extract_dir)/toolchain/bin/clang++ endef define $(package)_preprocess_cmds - cd $($(package)_build_subdir); ./autogen.sh && \ - sed -i.old "/define HAVE_PTHREADS/d" ld64/src/ld/InputFiles.h + CC=$($(package)_cc) CXX=$($(package)_cxx) INSTALLPREFIX=$($(package)_extract_dir) ./libtapi/build.sh && \ + CC=$($(package)_cc) CXX=$($(package)_cxx) INSTALLPREFIX=$($(package)_extract_dir) ./libtapi/install.sh && \ + sed -i.old "/define HAVE_PTHREADS/d" $($(package)_build_subdir)/ld64/src/ld/InputFiles.h endef define $(package)_config_cmds @@ -52,6 +62,9 @@ endef define $(package)_stage_cmds $(MAKE) DESTDIR=$($(package)_staging_dir) install && \ + mkdir -p $($(package)_staging_prefix_dir)/lib/ && \ + cd $($(package)_extract_dir) && \ + cp lib/libtapi.so.6 $($(package)_staging_prefix_dir)/lib/ && \ 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 && \ @@ -59,7 +72,6 @@ define $(package)_stage_cmds 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/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 + cp bin/dsymutil $($(package)_staging_prefix_dir)/bin/$(host)-dsymutil endef + diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index 9ac037ebb5..f9b26a1bf3 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -10,7 +10,7 @@ define $(package)_set_vars $(package)_config_opts += --without-libsodium --without-libgssapi_krb5 --without-pgm --without-norm --without-vmci $(package)_config_opts += --disable-libunwind --disable-radix-tree --without-gcov $(package)_config_opts_linux=--with-pic - $(package)_cxxflags=-std=c++11 + $(package)_cxxflags=-std=c++17 endef define $(package)_preprocess_cmds diff --git a/doc/build-unix.md b/doc/build-unix.md index aaf3a24683..fb8ee8e599 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -81,7 +81,7 @@ Build requirements: Now, you can either build from self-compiled [depends](/depends/README.md) or install the required dependencies: - sudo apt-get install libssl-dev libevent-dev libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-test-dev libboost-thread-dev + sudo apt-get install libssl-dev libevent-dev libboost-system-dev libboost-filesystem-dev libboost-test-dev BerkeleyDB is required for the wallet. diff --git a/doc/dependencies.md b/doc/dependencies.md index 70bc5e6ed3..e0f13c9a59 100644 --- a/doc/dependencies.md +++ b/doc/dependencies.md @@ -7,11 +7,11 @@ These are the dependencies currently used by Bitcoin Core. You can find instruct | --- | --- | --- | --- | --- | --- | | Berkeley DB | [4.8.30](https://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html) | 4.8.x | No | | | | Boost | [1.70.0](https://www.boost.org/users/download/) | [1.47.0](https://github.com/bitcoin/bitcoin/pull/8920) | No | | | -| Clang | | [3.3+](https://releases.llvm.org/download.html) (C++11 support) | | | | +| Clang | | [5.0+](https://releases.llvm.org/download.html) (C++17 support) | | | | | Expat | [2.2.7](https://libexpat.github.io/) | | No | Yes | | | fontconfig | [2.12.1](https://www.freedesktop.org/software/fontconfig/release/) | | No | Yes | | | FreeType | [2.7.1](https://download.savannah.gnu.org/releases/freetype) | | No | | | -| GCC | | [4.8+](https://gcc.gnu.org/) (C++11 support) | | | | +| GCC | | [7+](https://gcc.gnu.org/) (C++17 support) | | | | | HarfBuzz-NG | | | | | | | libevent | [2.1.8-stable](https://github.com/libevent/libevent/releases) | 2.0.22 | No | | | | libpng | | | | | [Yes](https://github.com/bitcoin/bitcoin/blob/master/depends/packages/qt.mk) | diff --git a/make.sh b/make.sh index f98d89118e..40299dac8d 100755 --- a/make.sh +++ b/make.sh @@ -22,7 +22,7 @@ setup_vars() { # shellcheck disable=SC2206 # This intentionally word-splits the array as env arg can only be strings. - # Other options available: x86_64-w64-mingw32 x86_64-apple-darwin11 + # Other options available: x86_64-w64-mingw32 x86_64-apple-darwin18 TARGETS=(${TARGETS:-"x86_64-pc-linux-gnu"}) } @@ -167,7 +167,7 @@ docker_build() { echo "> docker-build"; for target in "${targets[@]}"; do - if [[ "$target" == "x86_64-apple-darwin11" ]]; then + if [[ "$target" == "x86_64-apple-darwin18" ]]; then pkg_ensure_mac_sdk fi local img="${img_prefix}-${target}:${img_version}" @@ -340,8 +340,8 @@ pkg_install_deps() { } pkg_ensure_mac_sdk() { - local sdk_name="MacOSX10.11.sdk" - local pkg="${sdk_name}.tar.xz" + local sdk_name="Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers" + local pkg="${sdk_name}.tar.gz" echo "> ensuring mac sdk" @@ -349,9 +349,9 @@ pkg_ensure_mac_sdk() { pushd ./depends/SDKs >/dev/null if [[ ! -d "$sdk_name" ]]; then if [[ ! -f "${pkg}" ]]; then - wget https://github.com/phracker/MacOSX-SDKs/releases/download/10.15/MacOSX10.11.sdk.tar.xz + wget https://bitcoincore.org/depends-sources/sdks/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers.tar.gz fi - tar -xvf "${pkg}" + tar -zxvf "${pkg}" fi rm "${pkg}" 2>/dev/null || true popd >/dev/null diff --git a/src/Makefile.am b/src/Makefile.am index 0bc3a6518e..0fd2d8b98f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -193,7 +193,6 @@ DEFI_CORE_H = \ node/psbt.h \ node/transaction.h \ noui.h \ - optional.h \ outputtype.h \ policy/feerate.h \ policy/fees.h \ @@ -245,7 +244,6 @@ DEFI_CORE_H = \ util/error.h \ util/fees.h \ util/system.h \ - util/memory.h \ util/moneystr.h \ util/rbf.h \ util/string.h \ diff --git a/src/addrman.cpp b/src/addrman.cpp index 96252bd93f..e82e0dfc32 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -5,6 +5,7 @@ #include +#include #include #include @@ -59,7 +60,7 @@ double CAddrInfo::GetChance(int64_t nNow) const fChance *= 0.01; // deprioritize 66% after each failed attempt, but at most 1/28th to avoid the search taking forever or overly penalizing outages. - fChance *= pow(0.66, std::min(nAttempts, 8)); + fChance *= std::pow(0.66, std::min(nAttempts, 8)); return fChance; } diff --git a/src/bench/checkqueue.cpp b/src/bench/checkqueue.cpp index 684b45f654..ac4551bd8d 100644 --- a/src/bench/checkqueue.cpp +++ b/src/bench/checkqueue.cpp @@ -6,10 +6,9 @@ #include #include #include -#include -#include #include +#include static const int MIN_CORES = 2; static const size_t BATCHES = 101; @@ -36,10 +35,7 @@ static void CCheckQueueSpeedPrevectorJob(benchmark::State& state) void swap(PrevectorJob& x){p.swap(x.p);}; }; CCheckQueue queue {QUEUE_BATCH_SIZE}; - boost::thread_group tg; - for (auto x = 0; x < std::max(MIN_CORES, GetNumCores()); ++x) { - tg.create_thread([&]{queue.Thread();}); - } + queue.StartWorkerThreads(GetNumCores() - 1); while (state.KeepRunning()) { // Make insecure_rand here so that each iteration is identical. FastRandomContext insecure_rand(true); @@ -55,7 +51,6 @@ static void CCheckQueueSpeedPrevectorJob(benchmark::State& state) // it is done explicitly here for clarity control.Wait(); } - tg.interrupt_all(); - tg.join_all(); + queue.StopWorkerThreads(); } BENCHMARK(CCheckQueueSpeedPrevectorJob, 1400); diff --git a/src/bench/coin_selection.cpp b/src/bench/coin_selection.cpp index 2f8c97c477..f2e3eab542 100644 --- a/src/bench/coin_selection.cpp +++ b/src/bench/coin_selection.cpp @@ -16,7 +16,7 @@ static void addCoin(const CAmount& nValue, const CWallet& wallet, std::vector(&wallet, MakeTransactionRef(std::move(tx)))); + wtxs.push_back(std::make_unique(&wallet, MakeTransactionRef(std::move(tx)))); } // Simple benchmark for wallet coin selection. Note that it maybe be necessary @@ -70,7 +70,7 @@ static void add_coin(const CAmount& nValue, int nInput, std::vector CMutableTransaction tx; tx.vout.resize(nInput + 1); tx.vout[nInput].nValue = nValue; - std::unique_ptr wtx = MakeUnique(&testWallet, MakeTransactionRef(std::move(tx))); + std::unique_ptr wtx = std::make_unique(&testWallet, MakeTransactionRef(std::move(tx))); set.emplace_back(COutput(wtx.get(), nInput, 0, true, true, true).GetInputCoin(), 0, true, 0, 0); wtxn.emplace_back(std::move(wtx)); } diff --git a/src/bench/examples.cpp b/src/bench/examples.cpp index e4d1708aff..f03eaf4173 100644 --- a/src/bench/examples.cpp +++ b/src/bench/examples.cpp @@ -10,7 +10,7 @@ static void Sleep100ms(benchmark::State& state) { while (state.KeepRunning()) { - MilliSleep(100); + UninterruptibleSleep(std::chrono::milliseconds{100}); } } diff --git a/src/bench/wallet_balance.cpp b/src/bench/wallet_balance.cpp index a0889b97f3..8412920a2a 100644 --- a/src/bench/wallet_balance.cpp +++ b/src/bench/wallet_balance.cpp @@ -4,11 +4,12 @@ #include #include -#include #include #include #include +#include + static void WalletBalance(benchmark::State& state, const bool set_dirty, const bool add_watchonly, const bool add_mine) { const auto& ADDRESS_WATCHONLY = ADDRESS_BCRT1_UNSPENDABLE; @@ -22,11 +23,11 @@ static void WalletBalance(benchmark::State& state, const bool set_dirty, const b } - const Optional address_mine{add_mine ? Optional{getnewaddress(wallet)} : nullopt}; + const std::optional address_mine{add_mine ? std::optional{getnewaddress(wallet)} : std::nullopt}; if (add_watchonly) importaddress(wallet, ADDRESS_WATCHONLY); for (int i = 0; i < 100; ++i) { - generatetoaddress(address_mine.get_value_or(ADDRESS_WATCHONLY)); + generatetoaddress(address_mine.value_or(ADDRESS_WATCHONLY)); generatetoaddress(ADDRESS_WATCHONLY); } SyncWithValidationInterfaceQueue(); diff --git a/src/chainparams.cpp b/src/chainparams.cpp index d315507db8..b994dc3f85 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -14,11 +14,11 @@ #include #include +#include #include #include #include -#include std::vector CChainParams::CreateGenesisMasternodes() { @@ -32,15 +32,15 @@ std::vector CChainParams::CreateGenesisMasternodes() txNew.vin[0].scriptSig = CScript(); // << 486604799 << CScriptNum(4) << std::vector((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); CTxDestination operatorDest = DecodeDestination(addrs.operatorAddress, *this); - assert(operatorDest.which() == PKHashType || operatorDest.which() == WitV0KeyHashType); + assert(operatorDest.index() == PKHashType || operatorDest.index() == WitV0KeyHashType); CTxDestination ownerDest = DecodeDestination(addrs.ownerAddress, *this); - assert(ownerDest.which() == PKHashType || ownerDest.which() == WitV0KeyHashType); + assert(ownerDest.index() == PKHashType || ownerDest.index() == WitV0KeyHashType); - CKeyID operatorAuthKey = operatorDest.which() == PKHashType ? CKeyID(*boost::get(&operatorDest)) : CKeyID(*boost::get(&operatorDest)) ; + CKeyID operatorAuthKey = operatorDest.index() == PKHashType ? CKeyID(std::get(operatorDest)) : CKeyID(std::get(operatorDest)) ; genesisTeam.insert(operatorAuthKey); CDataStream metadata(DfTxMarker, SER_NETWORK, PROTOCOL_VERSION); metadata << static_cast(CustomTxType::CreateMasternode) - << static_cast(operatorDest.which()) << operatorAuthKey; + << static_cast(operatorDest.index()) << operatorAuthKey; CScript scriptMeta; scriptMeta << OP_RETURN << ToByteVector(metadata); @@ -879,11 +879,11 @@ class CRegTestParams : public CChainParams { }; /// Check for fork height based flag, validate and set the value to a target var -boost::optional UpdateHeightValidation(const std::string& argName, const std::string& argFlag, int& argTarget) { +std::optional UpdateHeightValidation(const std::string& argName, const std::string& argFlag, int& argTarget) { if (gArgs.IsArgSet(argFlag)) { int64_t height = gArgs.GetArg(argFlag, argTarget); if (height < -1 || height >= std::numeric_limits::max()) { - auto lowerArgName = boost::to_lower_copy(argName); + std::string lowerArgName = ToLower(argFlag); throw std::runtime_error(strprintf( "Activation height %ld for %s is out of valid range. Use -1 to disable %s.", height, argName, lowerArgName)); @@ -908,7 +908,7 @@ void CRegTestParams::UpdateActivationParametersFromArgs(const ArgsManager& args) UpdateHeightValidation("Dakota Crescent", "-dakotacrescentheight", consensus.DakotaCrescentHeight); auto eunosHeight = UpdateHeightValidation("Eunos", "-eunosheight", consensus.EunosHeight); if (eunosHeight.has_value()){ - consensus.EunosKampungHeight = static_cast(eunosHeight.get()); + consensus.EunosKampungHeight = static_cast(eunosHeight.value()); } UpdateHeightValidation("Eunos Paya", "-eunospayaheight", consensus.EunosPayaHeight); UpdateHeightValidation("Fork canning", "-fortcanningheight", consensus.FortCanningHeight); diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp index 95b7836b52..fc2526f43e 100644 --- a/src/chainparamsbase.cpp +++ b/src/chainparamsbase.cpp @@ -7,7 +7,6 @@ #include #include -#include #include @@ -37,13 +36,13 @@ const CBaseChainParams& BaseParams() std::unique_ptr CreateBaseChainParams(const std::string& chain) { if (chain == CBaseChainParams::MAIN) - return MakeUnique("", 8554); + return std::make_unique("", 8554); else if (chain == CBaseChainParams::TESTNET) - return MakeUnique("testnet3", 18554); + return std::make_unique("testnet3", 18554); else if (chain == CBaseChainParams::DEVNET) - return MakeUnique("devnet", 20554); + return std::make_unique("devnet", 20554); else if (chain == CBaseChainParams::REGTEST) - return MakeUnique("regtest", 19554); + return std::make_unique("regtest", 19554); else throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain)); } diff --git a/src/checkqueue.h b/src/checkqueue.h index 4cdc74e565..19599d556b 100644 --- a/src/checkqueue.h +++ b/src/checkqueue.h @@ -6,13 +6,12 @@ #define DEFI_CHECKQUEUE_H #include +#include +#include #include #include -#include -#include - template class CCheckQueueControl; @@ -31,67 +30,69 @@ class CCheckQueue { private: //! Mutex to protect the inner state - boost::mutex mutex; + Mutex m_mutex; //! Worker threads block on this when out of work - boost::condition_variable condWorker; + std::condition_variable m_worker_cv; //! Master thread blocks on this when out of work - boost::condition_variable condMaster; + std::condition_variable m_master_cv; //! The queue of elements to be processed. //! As the order of booleans doesn't matter, it is used as a LIFO (stack) - std::vector queue; + std::vector queue GUARDED_BY(m_mutex); //! The number of workers (including the master) that are idle. - int nIdle; + int nIdle GUARDED_BY(m_mutex){0}; //! The total number of workers (including the master). - int nTotal; + int nTotal GUARDED_BY(m_mutex){0}; //! The temporary evaluation result. - bool fAllOk; + bool fAllOk GUARDED_BY(m_mutex){true}; /** * Number of verifications that haven't completed yet. * This includes elements that are no longer queued, but still in the * worker's own batches. */ - unsigned int nTodo; + unsigned int nTodo GUARDED_BY(m_mutex){0}; //! The maximum number of elements to be processed in one batch - unsigned int nBatchSize; + const unsigned int nBatchSize; + + std::vector m_worker_threads; + bool m_request_stop GUARDED_BY(m_mutex){false}; /** Internal function that does bulk of the verification work. */ - bool Loop(bool fMaster = false) + bool Loop(bool fMaster) { - boost::condition_variable& cond = fMaster ? condMaster : condWorker; + std::condition_variable& cond = fMaster ? m_master_cv : m_worker_cv; std::vector vChecks; vChecks.reserve(nBatchSize); unsigned int nNow = 0; bool fOk = true; do { { - boost::unique_lock lock(mutex); + WAIT_LOCK(m_mutex, lock); // first do the clean-up of the previous loop run (allowing us to do it in the same critsect) if (nNow) { fAllOk &= fOk; nTodo -= nNow; if (nTodo == 0 && !fMaster) // We processed the last element; inform the master it can exit and return the result - condMaster.notify_one(); + m_master_cv.notify_one(); } else { // first iteration nTotal++; } // logically, the do loop starts here - while (queue.empty()) { + while (queue.empty() && !m_request_stop) { if (fMaster && nTodo == 0) { nTotal--; bool fRet = fAllOk; // reset the status for new work later - if (fMaster) - fAllOk = true; + fAllOk = true; // return the current status return fRet; } @@ -99,6 +100,10 @@ class CCheckQueue cond.wait(lock); // wait nIdle--; } + if (m_request_stop) { + return false; + } + // Decide how many work units to process now. // * Do not try to do everything at once, but aim for increasingly smaller batches so // all workers finish approximately simultaneously. @@ -125,15 +130,27 @@ class CCheckQueue public: //! Mutex to ensure only one concurrent CCheckQueueControl - boost::mutex ControlMutex; + Mutex m_control_mutex; //! Create a new check queue - explicit CCheckQueue(unsigned int nBatchSizeIn) : nIdle(0), nTotal(0), fAllOk(true), nTodo(0), nBatchSize(nBatchSizeIn) {} + explicit CCheckQueue(unsigned int nBatchSizeIn) : nBatchSize(nBatchSizeIn) {} - //! Worker thread - void Thread() + //! Create a pool of new worker threads. + void StartWorkerThreads(const int threads_num) { - Loop(); + { + LOCK(m_mutex); + nIdle = 0; + nTotal = 0; + fAllOk = true; + } + assert(m_worker_threads.empty()); + for (int n = 0; n < threads_num; ++n) { + m_worker_threads.emplace_back([this, n]() { + util::ThreadRename(strprintf("scriptch.%i", n)); + Loop(false /* worker thread */); + }); + } } //! Wait until execution finishes, and return whether all evaluations were successful. @@ -145,20 +162,33 @@ class CCheckQueue //! Add a batch of checks to the queue void Add(std::vector& vChecks) { - boost::unique_lock lock(mutex); + LOCK(m_mutex); for (T& check : vChecks) { queue.push_back(T()); check.swap(queue.back()); } nTodo += vChecks.size(); if (vChecks.size() == 1) - condWorker.notify_one(); + m_worker_cv.notify_one(); else if (vChecks.size() > 1) - condWorker.notify_all(); + m_worker_cv.notify_all(); + } + + //! Stop all of the worker threads. + void StopWorkerThreads() + { + WITH_LOCK(m_mutex, m_request_stop = true); + m_worker_cv.notify_all(); + for (std::thread& t : m_worker_threads) { + t.join(); + } + m_worker_threads.clear(); + WITH_LOCK(m_mutex, m_request_stop = false); } ~CCheckQueue() { + assert(m_worker_threads.empty()); } }; @@ -182,7 +212,7 @@ class CCheckQueueControl { // passed queue is supposed to be unused, or nullptr if (pqueue != nullptr) { - ENTER_CRITICAL_SECTION(pqueue->ControlMutex); + ENTER_CRITICAL_SECTION(pqueue->m_control_mutex); } } @@ -206,7 +236,7 @@ class CCheckQueueControl if (!fDone) Wait(); if (pqueue != nullptr) { - LEAVE_CRITICAL_SECTION(pqueue->ControlMutex); + LEAVE_CRITICAL_SECTION(pqueue->m_control_mutex); } } }; diff --git a/src/defi-cli.cpp b/src/defi-cli.cpp index 06e958c326..b6342d7e97 100644 --- a/src/defi-cli.cpp +++ b/src/defi-cli.cpp @@ -483,7 +483,7 @@ static int CommandLineRPC(int argc, char *argv[]) } catch (const CConnectionFailed&) { if (fWait) - MilliSleep(1000); + UninterruptibleSleep(std::chrono::milliseconds{1000}); else throw; } diff --git a/src/defid.cpp b/src/defid.cpp index a05d699adb..517b357d3c 100644 --- a/src/defid.cpp +++ b/src/defid.cpp @@ -47,7 +47,7 @@ static void WaitForShutdown() { while (!ShutdownRequested()) { - MilliSleep(200); + UninterruptibleSleep(std::chrono::milliseconds{200}); } Interrupt(); } diff --git a/src/flushablestorage.h b/src/flushablestorage.h index c9a9ffcea1..0cba8924c7 100644 --- a/src/flushablestorage.h +++ b/src/flushablestorage.h @@ -5,16 +5,17 @@ #ifndef DEFI_FLUSHABLESTORAGE_H #define DEFI_FLUSHABLESTORAGE_H +#include + #include #include -#include #include #include -#include +#include using TBytes = std::vector; -using MapKV = std::map>; +using MapKV = std::map>; template static TBytes DbTypeToBytes(const T& value) { @@ -166,7 +167,7 @@ class CStorageLevelDB : public CStorageKV { return batch.SizeEstimate(); } std::unique_ptr NewIterator() override { - return MakeUnique(std::unique_ptr(db.NewIterator())); + return std::make_unique(std::unique_ptr(db.NewIterator())); } void Compact(const TBytes& begin, const TBytes& end) { db.CompactRange(refTBytes(begin), refTBytes(end)); @@ -291,7 +292,7 @@ class CFlushableStorageKV : public CStorageKV { if (it == changed.end()) { return db.Read(key, value); } else if (it->second) { - value = it->second.get(); + value = it->second.value(); return true; } else { return false; @@ -303,7 +304,7 @@ class CFlushableStorageKV : public CStorageKV { if (!db.Erase(it.first)) { return false; } - } else if (!db.Write(it.first, it.second.get())) { + } else if (!db.Write(it.first, it.second.value())) { return false; } } @@ -317,7 +318,7 @@ class CFlushableStorageKV : public CStorageKV { return memusage::DynamicUsage(changed); } std::unique_ptr NewIterator() override { - return MakeUnique(db.NewIterator(), changed); + return std::make_unique(db.NewIterator(), changed); } MapKV& GetRaw() { @@ -331,7 +332,7 @@ class CFlushableStorageKV : public CStorageKV { template class CLazySerialize { - Optional value; + std::optional value; std::unique_ptr& it; public: @@ -427,8 +428,8 @@ class CStorageIteratorWrapper { // Creates an iterator to single level key value storage template CStorageIteratorWrapper NewKVIterator(const KeyType& key, MapKV& map) { - auto emptyParent = MakeUnique(); - auto flushableIterator = MakeUnique(std::move(emptyParent), map); + auto emptyParent = std::make_unique(); + auto flushableIterator = std::make_unique(std::move(emptyParent), map); CStorageIteratorWrapper it{std::move(flushableIterator)}; it.Seek(key); return it; @@ -482,7 +483,7 @@ class CStorageView { } // second type of 'ReadBy' (may be 'GetBy'?) template - boost::optional ReadBy(KeyType const & id) const { + std::optional ReadBy(KeyType const & id) const { ResultType result; if (ReadBy(id, result)) return {result}; @@ -497,7 +498,9 @@ class CStorageView { template void ForEach(std::function)> callback, KeyType const & start = {}) { for(auto it = LowerBound(start); it.Valid(); it.Next()) { - boost::this_thread::interruption_point(); + if (ShutdownRequested()) { + break; + } if (!callback(it.Key(), it.Value())) { break; diff --git a/src/httprpc.cpp b/src/httprpc.cpp index 8dfc133351..e53fb0edaa 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -196,7 +196,7 @@ static bool HTTPReq_JSONRPC(HTTPRequest* req, const std::string &) /* Deter brute-forcing If this results in a DoS the user really shouldn't have their RPC port exposed. */ - MilliSleep(250); + UninterruptibleSleep(std::chrono::milliseconds{250}); req->WriteHeader("WWW-Authenticate", WWW_AUTH_HEADER_DATA); req->WriteReply(HTTP_UNAUTHORIZED); @@ -277,7 +277,7 @@ bool StartHTTPRPC() } struct event_base* eventBase = EventBase(); assert(eventBase); - httpRPCTimerInterface = MakeUnique(eventBase); + httpRPCTimerInterface = std::make_unique(eventBase); RPCSetTimerInterface(httpRPCTimerInterface.get()); return true; } diff --git a/src/index/blockfilterindex.cpp b/src/index/blockfilterindex.cpp index f45cd06e41..849bbb5159 100644 --- a/src/index/blockfilterindex.cpp +++ b/src/index/blockfilterindex.cpp @@ -107,8 +107,8 @@ BlockFilterIndex::BlockFilterIndex(BlockFilterType filter_type, fs::create_directories(path); m_name = filter_name + " block filter index"; - m_db = MakeUnique(path / "db", n_cache_size, f_memory, f_wipe); - m_filter_fileseq = MakeUnique(std::move(path), "fltr", FLTR_FILE_CHUNK_SIZE); + m_db = std::make_unique(path / "db", n_cache_size, f_memory, f_wipe); + m_filter_fileseq = std::make_unique(std::move(path), "fltr", FLTR_FILE_CHUNK_SIZE); } bool BlockFilterIndex::Init() diff --git a/src/index/txindex.cpp b/src/index/txindex.cpp index cca08fd0f9..0e46109d55 100644 --- a/src/index/txindex.cpp +++ b/src/index/txindex.cpp @@ -9,8 +9,6 @@ #include #include -#include - constexpr char DB_BEST_BLOCK = 'B'; constexpr char DB_TXINDEX = 't'; constexpr char DB_TXINDEX_BLOCK = 'T'; @@ -152,7 +150,6 @@ bool TxIndex::DB::MigrateData(CBlockTreeDB& block_tree_db, const CBlockLocator& bool interrupted = false; std::unique_ptr cursor(block_tree_db.NewIterator()); for (cursor->Seek(begin_key); cursor->Valid(); cursor->Next()) { - boost::this_thread::interruption_point(); if (ShutdownRequested()) { interrupted = true; break; @@ -225,7 +222,7 @@ bool TxIndex::DB::MigrateData(CBlockTreeDB& block_tree_db, const CBlockLocator& } TxIndex::TxIndex(size_t n_cache_size, bool f_memory, bool f_wipe) - : m_db(MakeUnique(n_cache_size, f_memory, f_wipe)) + : m_db(std::make_unique(n_cache_size, f_memory, f_wipe)) {} TxIndex::~TxIndex() {} diff --git a/src/init.cpp b/src/init.cpp index 989450937f..b67fab06f7 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -9,7 +9,6 @@ #include -#include #include #include #include @@ -22,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -71,10 +69,7 @@ #include #endif -#include #include -#include -#include #if ENABLE_ZMQ #include @@ -157,7 +152,7 @@ NODISCARD static bool CreatePidFile() static std::unique_ptr globalVerifyHandle; -static boost::thread_group threadGroup; +std::vector threadGroup; static CScheduler scheduler; void Interrupt() @@ -216,9 +211,12 @@ void Shutdown(InitInterfaces& interfaces) StopTorControl(); // After everything has been shut down, but before things get flushed, stop the - // CScheduler/checkqueue threadGroup - threadGroup.interrupt_all(); - threadGroup.join_all(); + // CScheduler/checkqueue threaGroup + scheduler.stop(); + for (auto& thread : threadGroup) { + if (thread.joinable()) thread.join(); + } + StopScriptCheckWorkerThreads(); // After the threads that potentially access these pointers have been stopped, // destruct and reset all to nullptr. @@ -722,6 +720,10 @@ static void ThreadImport(std::vector vImportFiles) break; // This error is logged in OpenBlockFile LogPrintf("Reindexing block file blk%05u.dat...\n", (unsigned int)nFile); LoadExternalBlockFile(chainparams, file, &pos); + if (ShutdownRequested()) { + LogPrintf("Shutdown requested. Exit %s\n", __func__); + return; + } nFile++; } pblocktree->WriteReindexing(false); @@ -739,6 +741,10 @@ static void ThreadImport(std::vector vImportFiles) fs::path pathBootstrapOld = GetDataDir() / "bootstrap.dat.old"; LogPrintf("Importing bootstrap.dat...\n"); LoadExternalBlockFile(chainparams, file); + if (ShutdownRequested()) { + LogPrintf("Shutdown requested. Exit %s\n", __func__); + return; + } RenameOver(pathBootstrap, pathBootstrapOld); } else { LogPrintf("Warning: Could not open bootstrap file %s\n", pathBootstrap.string()); @@ -1109,15 +1115,6 @@ bool AppInitParameterInteraction() incrementalRelayFee = CFeeRate(n); } - // -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency - nScriptCheckThreads = gArgs.GetArg("-par", DEFAULT_SCRIPTCHECK_THREADS); - if (nScriptCheckThreads <= 0) - nScriptCheckThreads += GetNumCores(); - if (nScriptCheckThreads <= 1) - nScriptCheckThreads = 0; - else if (nScriptCheckThreads > MAX_SCRIPTCHECK_THREADS) - nScriptCheckThreads = MAX_SCRIPTCHECK_THREADS; - // block pruning; get the amount of disk space (in MiB) to allot for block & undo files int64_t nPruneArg = gArgs.GetArg("-prune", 0); if (nPruneArg < 0) { @@ -1258,7 +1255,7 @@ bool AppInitLockDataDirectory() void SetupAnchorSPVDatabases(bool resync) { // Close and open database panchors.reset(); - panchors = MakeUnique(nDefaultDbCache << 20, false, gArgs.GetBoolArg("-spv", true) && resync); + panchors = std::make_unique(nDefaultDbCache << 20, false, gArgs.GetBoolArg("-spv", true) && resync); // load anchors after spv due to spv (and spv height) not set before (no last height yet) if (gArgs.GetBoolArg("-spv", true)) { @@ -1267,11 +1264,11 @@ void SetupAnchorSPVDatabases(bool resync) { // Open database based on network if (Params().NetworkIDString() == "regtest") { - spv::pspv = MakeUnique(); + spv::pspv = std::make_unique(); } else if (Params().NetworkIDString() == "test" || Params().NetworkIDString() == "devnet") { - spv::pspv = MakeUnique(false, nMinDbCache << 20, false, resync); + spv::pspv = std::make_unique(false, nMinDbCache << 20, false, resync); } else { - spv::pspv = MakeUnique(true, nMinDbCache << 20, false, resync); + spv::pspv = std::make_unique(true, nMinDbCache << 20, false, resync); } } } @@ -1327,15 +1324,27 @@ bool AppInitMain(InitInterfaces& interfaces) InitSignatureCache(); InitScriptExecutionCache(); - LogPrintf("Using %u threads for script verification\n", nScriptCheckThreads); - if (nScriptCheckThreads) { - for (int i=0; i= 1) { + g_parallel_script_checks = true; + StartScriptCheckWorkerThreads(script_threads); } // Start the lightweight task scheduler thread - CScheduler::Function serviceLoop = std::bind(&CScheduler::serviceQueue, &scheduler); - threadGroup.create_thread(std::bind(&TraceThread, "scheduler", serviceLoop)); + scheduler.m_service_thread = std::thread([&] { TraceThread("scheduler", [&] { scheduler.serviceQueue(); }); }); GetMainSignals().RegisterBackgroundSignalScheduler(scheduler); GetMainSignals().RegisterWithMempoolSignals(mempool); @@ -1384,7 +1393,7 @@ bool AppInitMain(InitInterfaces& interfaces) // need to reindex later. assert(!g_banman); - g_banman = MakeUnique(GetDataDir() / "banlist.dat", &uiInterface, gArgs.GetArg("-bantime", DEFAULT_MISBEHAVING_BANTIME)); + g_banman = std::make_unique(GetDataDir() / "banlist.dat", &uiInterface, gArgs.GetArg("-bantime", DEFAULT_MISBEHAVING_BANTIME)); assert(!g_connman); g_connman = std::unique_ptr(new CConnman(GetRand(std::numeric_limits::max()), GetRand(std::numeric_limits::max()))); @@ -1543,7 +1552,7 @@ bool AppInitMain(InitInterfaces& interfaces) try { LOCK(cs_main); // This statement makes ::ChainstateActive() usable. - g_chainstate = MakeUnique(); + g_chainstate = std::make_unique(); UnloadBlockIndex(); // new CBlockTreeDB tries to delete the existing file, which @@ -1608,9 +1617,9 @@ bool AppInitMain(InitInterfaces& interfaces) }); pcustomcsDB.reset(); - pcustomcsDB = MakeUnique(GetDataDir() / "enhancedcs", nCustomCacheSize, false, fReset || fReindexChainState); + pcustomcsDB = std::make_unique(GetDataDir() / "enhancedcs", nCustomCacheSize, false, fReset || fReindexChainState); pcustomcsview.reset(); - pcustomcsview = MakeUnique(*pcustomcsDB.get()); + pcustomcsview = std::make_unique(*pcustomcsDB.get()); if (!fReset && !fReindexChainState) { if (!pcustomcsDB->IsEmpty() && pcustomcsview->GetDbVersion() != CCustomCSView::DbVersion) { strLoadError = _("Account database is unsuitable").translated; @@ -1624,11 +1633,11 @@ bool AppInitMain(InitInterfaces& interfaces) // make account history db paccountHistoryDB.reset(); if (gArgs.GetBoolArg("-acindex", DEFAULT_ACINDEX)) { - paccountHistoryDB = MakeUnique(GetDataDir() / "history", nCustomCacheSize, false, fReset || fReindexChainState); + paccountHistoryDB = std::make_unique(GetDataDir() / "history", nCustomCacheSize, false, fReset || fReindexChainState); } pburnHistoryDB.reset(); - pburnHistoryDB = MakeUnique(GetDataDir() / "burn", nCustomCacheSize, false, fReset || fReindexChainState); + pburnHistoryDB = std::make_unique(GetDataDir() / "burn", nCustomCacheSize, false, fReset || fReindexChainState); // If necessary, upgrade from older database format. // This is a no-op if we cleared the coinsviewdb with -reindex or -reindex-chainstate @@ -1745,7 +1754,7 @@ bool AppInitMain(InitInterfaces& interfaces) // ********************************************************* Step 8: start indexers if (gArgs.GetBoolArg("-txindex", DEFAULT_TXINDEX)) { - g_txindex = MakeUnique(nTxIndexCache, false, fReindex); + g_txindex = std::make_unique(nTxIndexCache, false, fReindex); g_txindex->Start(); } @@ -1767,9 +1776,9 @@ bool AppInitMain(InitInterfaces& interfaces) LOCK(cs_main); panchorauths.reset(); - panchorauths = MakeUnique(); + panchorauths = std::make_unique(); panchorAwaitingConfirms.reset(); - panchorAwaitingConfirms = MakeUnique(); + panchorAwaitingConfirms = std::make_unique(); SetupAnchorSPVDatabases(gArgs.GetBoolArg("-spv_resync", fReindex || fReindexChainState)); // Check if DB version changed @@ -1838,7 +1847,7 @@ bool AppInitMain(InitInterfaces& interfaces) vImportFiles.push_back(strFile); } - threadGroup.create_thread(std::bind(&ThreadImport, vImportFiles)); + threadGroup.emplace_back(ThreadImport, vImportFiles); // Wait for genesis block to be processed { @@ -1977,8 +1986,8 @@ bool AppInitMain(InitInterfaces& interfaces) auto& coinbaseScript = stakerParams.coinbaseScript; CTxDestination destination = DecodeDestination(op); - operatorId = destination.which() == PKHashType ? CKeyID(*boost::get(&destination)) : - destination.which() == WitV0KeyHashType ? CKeyID(*boost::get(&destination)) : CKeyID(); + operatorId = destination.index() == PKHashType ? CKeyID(std::get(destination)) : + destination.index() == WitV0KeyHashType ? CKeyID(std::get(destination)) : CKeyID(); if (operatorId.IsNull()) { LogPrintf("Error: wrong masternode_operator address (%s)\n", op); @@ -2045,13 +2054,11 @@ bool AppInitMain(InitInterfaces& interfaces) } // Mint proof-of-stake blocks in background - threadGroup.create_thread( - std::bind(TraceThread>, "CoinStaker", [=]() { - // Run ThreadStaker - pos::ThreadStaker threadStaker; - threadStaker(std::move(stakersParams), std::move(chainparams)); - } - )); + threadGroup.emplace_back(TraceThread>, "CoinStaker", [=]() { + // Run ThreadStaker + pos::ThreadStaker threadStaker; + threadStaker(stakersParams, chainparams); + }); } return true; diff --git a/src/interfaces/chain.cpp b/src/interfaces/chain.cpp index 70a76e5091..6f43b23e61 100644 --- a/src/interfaces/chain.cpp +++ b/src/interfaces/chain.cpp @@ -47,28 +47,28 @@ class LockImpl : public Chain::Lock LockImpl(CCriticalSection& mutex) : m_mutex(mutex) { } - Optional getHeight() override + std::optional getHeight() override { LockAssertion lock(m_mutex); int height = ::ChainActive().Height(); if (height >= 0) { return height; } - return nullopt; + return std::nullopt; } - Optional getBlockHeight(const uint256& hash) override + std::optional getBlockHeight(const uint256& hash) override { LockAssertion lock(m_mutex); CBlockIndex* block = LookupBlockIndex(hash); if (block && ::ChainActive().Contains(block)) { return block->nHeight; } - return nullopt; + return std::nullopt; } int getBlockDepth(const uint256& hash) override { - const Optional tip_height = getHeight(); - const Optional height = getBlockHeight(hash); + const std::optional tip_height = getHeight(); + const std::optional height = getBlockHeight(hash); return tip_height && height ? *tip_height - *height + 1 : 0; } uint256 getBlockHash(int height) override @@ -98,7 +98,7 @@ class LockImpl : public Chain::Lock CBlockIndex* block = ::ChainActive()[height]; return block && ((block->nStatus & BLOCK_HAVE_DATA) != 0) && block->nTx > 0; } - Optional findFirstBlockWithTimeAndHeight(int64_t time, int height, uint256* hash) override + std::optional findFirstBlockWithTimeAndHeight(int64_t time, int height, uint256* hash) override { LockAssertion lock(m_mutex); CBlockIndex* block = ::ChainActive().FindEarliestAtLeast(time, height); @@ -106,9 +106,9 @@ class LockImpl : public Chain::Lock if (hash) *hash = block->GetBlockHash(); return block->nHeight; } - return nullopt; + return std::nullopt; } - Optional findPruned(int start_height, Optional stop_height) override + std::optional findPruned(int start_height, std::optional stop_height) override { LockAssertion lock(m_mutex); if (::fPruneMode) { @@ -120,9 +120,9 @@ class LockImpl : public Chain::Lock block = block->pprev; } } - return nullopt; + return std::nullopt; } - Optional findFork(const uint256& hash, Optional* height) override + std::optional findFork(const uint256& hash, std::optional* height) override { LockAssertion lock(m_mutex); const CBlockIndex* block = LookupBlockIndex(hash); @@ -137,20 +137,20 @@ class LockImpl : public Chain::Lock if (fork) { return fork->nHeight; } - return nullopt; + return std::nullopt; } CBlockLocator getTipLocator() override { LockAssertion lock(m_mutex); return ::ChainActive().GetLocator(); } - Optional findLocatorFork(const CBlockLocator& locator) override + std::optional findLocatorFork(const CBlockLocator& locator) override { LockAssertion lock(m_mutex); if (CBlockIndex* fork = FindForkInGlobalIndex(::ChainActive(), locator)) { return fork->nHeight; } - return nullopt; + return std::nullopt; } bool checkFinalTx(const CTransaction& tx) override { @@ -250,7 +250,7 @@ class ChainImpl : public Chain public: std::unique_ptr lock() override { - return MakeUnique(::cs_main); + return std::make_unique(::cs_main); } bool findBlock(const uint256& hash, CBlock* block, int64_t* time, int64_t* time_max) override { @@ -280,7 +280,7 @@ class ChainImpl : public Chain return pcustomcsview->CanSpend(nodeId, height); } - boost::optional mnExists(const uint256 & nodeId) const override + std::optional mnExists(const uint256 & nodeId) const override { LOCK(cs_main); return pcustomcsview->GetMasternode(nodeId); @@ -365,7 +365,7 @@ class ChainImpl : public Chain } std::unique_ptr handleNotifications(Notifications& notifications) override { - return MakeUnique(*this, notifications); + return std::make_unique(*this, notifications); } void waitForNotificationsIfNewBlocksConnected(const uint256& old_tip) override { @@ -379,7 +379,7 @@ class ChainImpl : public Chain } std::unique_ptr handleRpc(const CRPCCommand& command) override { - return MakeUnique(command); + return std::make_unique(command); } bool rpcEnableDeprecated(const std::string& method) override { return IsDeprecatedRPCEnabled(method); } void rpcRunLater(const std::string& name, std::function fn, int64_t seconds) override @@ -397,6 +397,6 @@ class ChainImpl : public Chain }; } // namespace -std::unique_ptr MakeChain() { return MakeUnique(); } +std::unique_ptr MakeChain() { return std::make_unique(); } } // namespace interfaces diff --git a/src/interfaces/chain.h b/src/interfaces/chain.h index 8c904912bd..22f10827cd 100644 --- a/src/interfaces/chain.h +++ b/src/interfaces/chain.h @@ -5,11 +5,12 @@ #ifndef DEFI_INTERFACES_CHAIN_H #define DEFI_INTERFACES_CHAIN_H -#include // For Optional and nullopt #include // For CTransactionRef #include +#include #include +#include #include #include #include @@ -71,12 +72,12 @@ class Chain //! Get current chain height, not including genesis block (returns 0 if //! chain only contains genesis block, nullopt if chain does not contain //! any blocks). - virtual Optional getHeight() = 0; + virtual std::optional getHeight() = 0; //! Get block height above genesis block. Returns 0 for genesis block, //! 1 for following block, and so on. Returns nullopt for a block not //! included in the current chain. - virtual Optional getBlockHeight(const uint256& hash) = 0; + virtual std::optional getBlockHeight(const uint256& hash) = 0; //! Get block depth. Returns 1 for chain tip, 2 for preceding block, and //! so on. Returns 0 for a block not included in the current chain. @@ -101,11 +102,11 @@ class Chain //! given height, or nullopt if there is no block with a high enough //! timestamp and height. Also return the block hash as an optional output parameter //! (to avoid the cost of a second lookup in case this information is needed.) - virtual Optional findFirstBlockWithTimeAndHeight(int64_t time, int height, uint256* hash) = 0; + virtual std::optional findFirstBlockWithTimeAndHeight(int64_t time, int height, uint256* hash) = 0; //! Return height of last block in the specified range which is pruned, or //! nullopt if no block in the range is pruned. Range is inclusive. - virtual Optional findPruned(int start_height = 0, Optional stop_height = nullopt) = 0; + virtual std::optional findPruned(int start_height = 0, std::optional stop_height = std::nullopt) = 0; //! Return height of the specified block if it is on the chain, otherwise //! return the height of the highest block on chain that's an ancestor @@ -113,7 +114,7 @@ class Chain //! Also return the height of the specified block as an optional output //! parameter (to avoid the cost of a second hash lookup in case this //! information is desired). - virtual Optional findFork(const uint256& hash, Optional* height) = 0; + virtual std::optional findFork(const uint256& hash, std::optional* height) = 0; //! Get locator for the current chain tip. virtual CBlockLocator getTipLocator() = 0; @@ -121,7 +122,7 @@ class Chain //! Return height of the highest block on chain in common with the locator, //! which will either be the original block used to create the locator, //! or one of its ancestors. - virtual Optional findLocatorFork(const CBlockLocator& locator) = 0; + virtual std::optional findLocatorFork(const CBlockLocator& locator) = 0; //! Check if transaction will be final given chain height current time. virtual bool checkFinalTx(const CTransaction& tx) = 0; @@ -151,7 +152,7 @@ class Chain virtual void findCoins(std::map& coins) = 0; virtual bool mnCanSpend(const uint256 & nodeId, int height) const = 0; - virtual boost::optional mnExists(const uint256 & nodeId) const = 0; + virtual std::optional mnExists(const uint256 & nodeId) const = 0; virtual std::unique_ptr existTokenGuessId(const std::string & str, DCT_ID & id) const = 0; //! Estimate fraction of total transactions verified if blocks up to diff --git a/src/interfaces/handler.cpp b/src/interfaces/handler.cpp index 0262ec712f..eb3d257328 100644 --- a/src/interfaces/handler.cpp +++ b/src/interfaces/handler.cpp @@ -4,7 +4,6 @@ #include -#include #include #include @@ -26,7 +25,7 @@ class HandlerImpl : public Handler std::unique_ptr MakeHandler(boost::signals2::connection connection) { - return MakeUnique(std::move(connection)); + return std::make_unique(std::move(connection)); } } // namespace interfaces diff --git a/src/key_io.cpp b/src/key_io.cpp index 126d92d9da..29e5378554 100644 --- a/src/key_io.cpp +++ b/src/key_io.cpp @@ -5,19 +5,13 @@ #include #include #include -#include