From e0ec4c3db6bd516fb975f33db6474c4251ee14ba Mon Sep 17 00:00:00 2001 From: Dcorral Date: Mon, 13 Jun 2022 13:16:08 +0200 Subject: [PATCH 01/82] Fixes type check on verbose parameter --- src/masternodes/rpc_vault.cpp | 7 +++++-- src/rpc/client.cpp | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/masternodes/rpc_vault.cpp b/src/masternodes/rpc_vault.cpp index 838a5b251b..ba1aab2d5a 100644 --- a/src/masternodes/rpc_vault.cpp +++ b/src/masternodes/rpc_vault.cpp @@ -573,8 +573,11 @@ UniValue getvault(const JSONRPCRequest& request) { RPCTypeCheck(request.params, {UniValue::VSTR}, false); if (auto res = GetRPCResultCache().TryGet(request)) return *res; - bool verbose = request.params[1].getBool(); CVaultId vaultId = ParseHashV(request.params[0], "vaultId"); + bool verbose{false}; + if (request.params.size() > 1) { + verbose = request.params[1].get_bool(); + } LOCK(cs_main); @@ -1836,7 +1839,7 @@ static const CRPCCommand commands[] = {"vault", "createvault", &createvault, {"ownerAddress", "schemeId", "inputs"}}, {"vault", "closevault", &closevault, {"id", "returnAddress", "inputs"}}, {"vault", "listvaults", &listvaults, {"options", "pagination"}}, - {"vault", "getvault", &getvault, {"id"}}, + {"vault", "getvault", &getvault, {"id", "verbose"}}, {"vault", "listvaulthistory", &listvaulthistory, {"id", "options"}}, {"vault", "updatevault", &updatevault, {"id", "parameters", "inputs"}}, {"vault", "deposittovault", &deposittovault, {"id", "from", "amount", "inputs"}}, diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 907f3c2b99..2219aade11 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -259,6 +259,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "listvaulthistory", 1, "options" }, { "listvaults", 0, "options" }, { "listvaults", 1, "pagination" }, + { "getvault", 1, "verbose" }, { "listauctions", 0, "pagination" }, { "listauctionhistory", 1, "pagination" }, { "estimateloan", 1, "tokens" }, From 4700496b396b438617b91e5b63b080bb307eabe2 Mon Sep 17 00:00:00 2001 From: dcorral Date: Thu, 7 Jul 2022 09:57:33 +0200 Subject: [PATCH 02/82] Add high precission string for getvault verbose --- src/masternodes/rpc_accounts.cpp | 2 +- src/masternodes/rpc_vault.cpp | 45 ++++++++++++++++----- test/functional/feature_loan_priceupdate.py | 23 +++++++++-- 3 files changed, 55 insertions(+), 15 deletions(-) diff --git a/src/masternodes/rpc_accounts.cpp b/src/masternodes/rpc_accounts.cpp index 6cfec584c1..fa20337bd3 100644 --- a/src/masternodes/rpc_accounts.cpp +++ b/src/masternodes/rpc_accounts.cpp @@ -1904,7 +1904,7 @@ UniValue getburninfo(const JSONRPCRequest& request) { }; burnView->ForEachAccountHistory(calculateBurnAmounts); - + UniValue result(UniValue::VOBJ); result.pushKV("address", ScriptToString(burnAddress)); result.pushKV("amount", ValueFromAmount(burntDFI)); diff --git a/src/masternodes/rpc_vault.cpp b/src/masternodes/rpc_vault.cpp index 84f506dbb7..0f7f021984 100644 --- a/src/masternodes/rpc_vault.cpp +++ b/src/masternodes/rpc_vault.cpp @@ -153,13 +153,15 @@ namespace { UniValue loanBalances{UniValue::VARR}; UniValue interestAmounts{UniValue::VARR}; UniValue interestsPerBlockBalances{UniValue::VARR}; + std::map> interestsPerBlockHighPrecission; + base_uint<128> interestsPerBlockValueHighPrecission{0}; + TAmounts interestsPerBlock{}; + CAmount totalInterestsPerBlock{0}; if (auto loanTokens = pcustomcsview->GetLoanTokens(vaultId)) { TAmounts totalBalances{}; TAmounts interestBalances{}; CAmount totalInterests{0}; - CAmount totalInterestsPerBlock{0}; - TAmounts interestsPerBlock{}; for (const auto& loan : loanTokens->balances) { auto token = pcustomcsview->GetLoanTokenByID(loan.first); @@ -173,9 +175,15 @@ namespace { auto price = priceFeed.val->priceRecord[0]; totalInterests += MultiplyAmounts(price, totalInterest); if (verbose) { - auto interestPerBlock = rate->interestPerBlock.GetLow64(); - interestsPerBlock.insert({loan.first, interestPerBlock}); - totalInterestsPerBlock += MultiplyAmounts(price, static_cast(interestPerBlock)); + if (height >= Params().GetConsensus().FortCanningHillHeight) { + auto interestPerBlockHighPrecission = rate->interestPerBlock; + interestsPerBlockValueHighPrecission += (static_cast>(price) * interestPerBlockHighPrecission / COIN); + interestsPerBlockHighPrecission[loan.first] += interestPerBlockHighPrecission; + } else { + auto interestPerBlock = rate->interestPerBlock.GetLow64(); + interestsPerBlock.insert({loan.first, interestPerBlock}); + totalInterestsPerBlock += MultiplyAmounts(price, static_cast(interestPerBlock)); + } } } @@ -188,10 +196,6 @@ namespace { interestValue = ValueFromAmount(totalInterests); loanBalances = AmountsToJSON(totalBalances); interestAmounts = AmountsToJSON(interestBalances); - if (verbose) { - interestsPerBlockBalances = AmountsToJSON(interestsPerBlock); - totalInterestsPerBlockValue = ValueFromAmount(totalInterestsPerBlock); - } } result.pushKV("vaultId", vaultId.GetHex()); @@ -208,6 +212,7 @@ namespace { ratioValue = -1; collateralRatio = -1; totalInterestsPerBlockValue = -1; + interestsPerBlockValueHighPrecission = -1; } result.pushKV("collateralValue", collValue); result.pushKV("loanValue", loanValue); @@ -221,8 +226,26 @@ namespace { nextCollateralRatio = int(rate.val->ratio()); result.pushKV("nextCollateralRatio", nextCollateralRatio); } - result.pushKV("interestPerBlockValue", totalInterestsPerBlockValue); - result.pushKV("interestsPerBlock", interestsPerBlockBalances); + if (height >= Params().GetConsensus().FortCanningHillHeight) { + result.pushKV("interestPerBlockValue", GetInterestPerBlockHighPrecisionString(interestsPerBlockValueHighPrecission)); + UniValue interestsPerBlockBalances(UniValue::VARR); + for (auto it=interestsPerBlockHighPrecission.begin(); it != interestsPerBlockHighPrecission.end(); ++it) + { + auto tokenId = it->first; + auto interestPerBlock = it->second; + + auto token = pcustomcsview->GetToken(tokenId); + auto amountStr = GetInterestPerBlockHighPrecisionString(interestPerBlock); + auto tokenSymbol = token->CreateSymbolKey(tokenId); + interestsPerBlockBalances.push_back(amountStr + "@" + tokenSymbol); + } + result.pushKV("interestsPerBlock", interestsPerBlockBalances); + } else { + interestsPerBlockBalances = AmountsToJSON(interestsPerBlock); + totalInterestsPerBlockValue = ValueFromAmount(totalInterestsPerBlock); + result.pushKV("interestPerBlockValue", totalInterestsPerBlockValue); + result.pushKV("interestsPerBlock", interestsPerBlockBalances); + } } return result; } diff --git a/test/functional/feature_loan_priceupdate.py b/test/functional/feature_loan_priceupdate.py index 3525952414..378eb9d033 100755 --- a/test/functional/feature_loan_priceupdate.py +++ b/test/functional/feature_loan_priceupdate.py @@ -7,7 +7,7 @@ from test_framework.authproxy import JSONRPCException from test_framework.test_framework import DefiTestFramework -from decimal import Decimal +from decimal import Decimal, ROUND_DOWN from test_framework.util import assert_equal @@ -18,9 +18,10 @@ class PriceUpdateTest (DefiTestFramework): def set_test_params(self): self.num_nodes = 1 self.setup_clean_chain = True + self.FCH = 400 self.extra_args = [ - ['-txnotokens=0', '-amkheight=1', '-bayfrontheight=1', '-eunosheight=1', '-txindex=1', '-fortcanningheight=1'] - ] + ['-txnotokens=0', '-amkheight=1', '-bayfrontheight=1', '-eunosheight=1', '-txindex=1', '-fortcanningheight=1', f'-fortcanninghillheight={self.FCH}'] + ] def run_test(self): self.nodes[0].generate(300) @@ -346,5 +347,21 @@ def run_test(self): realInteresAfterOneBlock = Decimal(vaultAfterUpdate["interestAmounts"][0].split('@')[0]) assert_equal(realInteresAfterOneBlock, expectedInterestAfterOneBlock) + # Go after FCH for high precission interestPerBlock and interestPerBlockValue + self.nodes[0].generate(self.FCH - self.nodes[0].getblockcount()) + + vaultAfterUpdate = self.nodes[0].getvault(vaultId1, True) + assert_equal(vaultAfterUpdate["collateralRatio"], vaultBeforeUpdate["nextCollateralRatio"]) + assert_equal(vaultAfterUpdate["nextCollateralRatio"], 3213) + interestPerBlockTSLA = vaultAfterUpdate["interestsPerBlock"][0].split('@')[0] + amountInterestTSLA = vaultAfterUpdate["interestAmounts"][0].split('@')[0] + self.nodes[0].generate(1) + + # Check one block interest is added correctly + vaultAfterUpdate = self.nodes[0].getvault(vaultId1, True) + expectedInterestAfterOneBlock = Decimal(Decimal(amountInterestTSLA) + Decimal(interestPerBlockTSLA)).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN) + realInteresAfterOneBlock = Decimal(vaultAfterUpdate["interestAmounts"][0].split('@')[0]) + assert_equal(realInteresAfterOneBlock, expectedInterestAfterOneBlock) + if __name__ == '__main__': PriceUpdateTest().main() From 35b00eb2dc03a403e5475b9f92d4f63227c5219d Mon Sep 17 00:00:00 2001 From: dcorral Date: Thu, 7 Jul 2022 10:18:49 +0200 Subject: [PATCH 03/82] Fixes error, return -1 when there are locked tokens --- src/masternodes/rpc_vault.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/masternodes/rpc_vault.cpp b/src/masternodes/rpc_vault.cpp index 0f7f021984..51138d464e 100644 --- a/src/masternodes/rpc_vault.cpp +++ b/src/masternodes/rpc_vault.cpp @@ -227,25 +227,25 @@ namespace { result.pushKV("nextCollateralRatio", nextCollateralRatio); } if (height >= Params().GetConsensus().FortCanningHillHeight) { - result.pushKV("interestPerBlockValue", GetInterestPerBlockHighPrecisionString(interestsPerBlockValueHighPrecission)); - UniValue interestsPerBlockBalances(UniValue::VARR); - for (auto it=interestsPerBlockHighPrecission.begin(); it != interestsPerBlockHighPrecission.end(); ++it) - { - auto tokenId = it->first; - auto interestPerBlock = it->second; - - auto token = pcustomcsview->GetToken(tokenId); - auto amountStr = GetInterestPerBlockHighPrecisionString(interestPerBlock); - auto tokenSymbol = token->CreateSymbolKey(tokenId); - interestsPerBlockBalances.push_back(amountStr + "@" + tokenSymbol); + if(isVaultTokenLocked){ + result.pushKV("interestPerBlockValue", -1); + } else { + result.pushKV("interestPerBlockValue", GetInterestPerBlockHighPrecisionString(interestsPerBlockValueHighPrecission)); + for (auto it=interestsPerBlockHighPrecission.begin(); it != interestsPerBlockHighPrecission.end(); ++it) { + auto tokenId = it->first; + auto interestPerBlock = it->second; + auto token = pcustomcsview->GetToken(tokenId); + auto amountStr = GetInterestPerBlockHighPrecisionString(interestPerBlock); + auto tokenSymbol = token->CreateSymbolKey(tokenId); + interestsPerBlockBalances.push_back(amountStr + "@" + tokenSymbol); + } } - result.pushKV("interestsPerBlock", interestsPerBlockBalances); } else { interestsPerBlockBalances = AmountsToJSON(interestsPerBlock); totalInterestsPerBlockValue = ValueFromAmount(totalInterestsPerBlock); result.pushKV("interestPerBlockValue", totalInterestsPerBlockValue); - result.pushKV("interestsPerBlock", interestsPerBlockBalances); } + result.pushKV("interestsPerBlock", interestsPerBlockBalances); } return result; } From 40d2fdaac14d54a2d45d4cbc1a9c2f34d5745f34 Mon Sep 17 00:00:00 2001 From: Peter John Bushnell Date: Mon, 11 Jul 2022 11:55:08 +0100 Subject: [PATCH 04/82] Remove Boost Thread and Chrono (#1349) * Remove boost::chrono and boost::sleep * Remove Boost mutex * Remove Boost thread_group * Remove Boost thread/mutex from SPV * Remove Boost interruption_point * Replace Boost shared_mutex with C++17 std::shared_mutex * Remove Boost Chrono and Thread from build system * Add missing include * Remove duplicate start of scheduler thread * Remove Boost case_conv * Remove Boost join and transformed * Do not interrupt ForEach loop * Add notes to interrupt replacements Co-authored-by: Prasanna Loganathar --- build-aux/m4/ax_boost_chrono.m4 | 118 --------------------- build-aux/m4/ax_boost_thread.m4 | 150 --------------------------- build_msvc/defi_config.h | 12 --- ci/test/00_setup_env_amd64_asan.sh | 2 +- ci/test/00_setup_env_amd64_fuzz.sh | 2 +- ci/test/00_setup_env_amd64_trusty.sh | 2 +- ci/test/00_setup_env_amd64_tsan.sh | 2 +- configure.ac | 57 +--------- depends/packages/boost.mk | 2 +- doc/build-unix.md | 2 +- src/addrman.cpp | 3 +- src/bench/checkqueue.cpp | 11 +- src/bench/examples.cpp | 2 +- src/chainparams.cpp | 4 +- src/checkqueue.h | 88 ++++++++++------ src/defi-cli.cpp | 2 +- src/defid.cpp | 2 +- src/flushablestorage.h | 6 +- src/httprpc.cpp | 2 +- src/index/txindex.cpp | 3 - src/init.cpp | 71 +++++++------ src/masternodes/anchors.h | 6 +- src/miner.cpp | 16 +-- src/node/coinstats.cpp | 7 +- src/node/coinstats.h | 3 +- src/random.cpp | 2 +- src/rpc/blockchain.cpp | 8 +- src/rpc/mining.cpp | 4 +- src/rpc/server.cpp | 7 +- src/rpc/server.h | 3 + src/scheduler.cpp | 51 +++------ src/scheduler.h | 56 +++++----- src/script/sigcache.cpp | 12 ++- src/spv/bitcoin/BRPeer.cpp | 13 ++- src/spv/bitcoin/BRPeer.h | 5 +- src/spv/bitcoin/BRPeerManager.cpp | 9 +- src/spv/bitcoin/BRPeerManager.h | 2 + src/spv/bitcoin/BRWallet.cpp | 9 +- src/spv/spv_wrapper.h | 8 +- src/test/checkqueue_tests.cpp | 77 +++++--------- src/test/cuckoocache_tests.cpp | 16 ++- src/test/oracles_tests.cpp | 19 +--- src/test/reverselock_tests.cpp | 43 ++++++-- src/test/scheduler_tests.cpp | 67 ++++++------ src/test/setup_common.cpp | 12 +-- src/test/setup_common.h | 4 +- src/test/storage_tests.cpp | 4 - src/test/transaction_tests.cpp | 7 +- src/test/util_tests.cpp | 4 +- src/txdb.cpp | 4 - src/util/system.h | 7 -- src/util/time.cpp | 23 +--- src/util/time.h | 4 +- src/validation.cpp | 34 +++--- src/validation.h | 17 +-- src/wallet/db.cpp | 11 +- src/wallet/walletdb.cpp | 8 -- test/lint/lint-includes.sh | 8 -- 58 files changed, 375 insertions(+), 758 deletions(-) delete mode 100644 build-aux/m4/ax_boost_chrono.m4 delete mode 100644 build-aux/m4/ax_boost_thread.m4 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_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/configure.ac b/configure.ac index c722553352..eb5d5297f3 100644 --- a/configure.ac +++ b/configure.ac @@ -519,7 +519,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" @@ -1083,8 +1083,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. @@ -1151,7 +1149,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 @@ -1189,57 +1187,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/depends/packages/boost.mk b/depends/packages/boost.mk index 662a4daaa0..b799f2fb91 100644 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -32,7 +32,7 @@ $(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)_config_libraries=filesystem,system,test $(package)_cxxflags=-std=c++17 -fvisibility=hidden $(package)_cxxflags_linux=-fPIC endef 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/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/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/chainparams.cpp b/src/chainparams.cpp index 702c3825e7..269361adb4 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -15,11 +15,11 @@ #include #include +#include #include #include #include -#include bool fMockNetwork = false; @@ -941,7 +941,7 @@ std::optional UpdateHeightValidation(const std::string& argName, const std: 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)); 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 57a8e43041..5e7a40fc8c 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 356253fbdf..c6931ebb4d 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 b5ebd9bb30..fd41d96a0d 100644 --- a/src/flushablestorage.h +++ b/src/flushablestorage.h @@ -5,6 +5,8 @@ #ifndef DEFI_FLUSHABLESTORAGE_H #define DEFI_FLUSHABLESTORAGE_H +#include + #include #include #include @@ -12,8 +14,6 @@ #include -#include - using TBytes = std::vector; using MapKV = std::map>; @@ -498,8 +498,6 @@ 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 (!callback(it.Key(), it.Value())) { break; } diff --git a/src/httprpc.cpp b/src/httprpc.cpp index 9fe0ce1e4d..52213d166b 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -197,7 +197,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); diff --git a/src/index/txindex.cpp b/src/index/txindex.cpp index 6ad9230cc1..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; diff --git a/src/init.cpp b/src/init.cpp index 490c136d3d..ac461bce05 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 @@ -75,10 +73,7 @@ #include #endif -#include #include -#include -#include #if ENABLE_ZMQ #include @@ -161,7 +156,7 @@ NODISCARD static bool CreatePidFile() static std::unique_ptr globalVerifyHandle; -static boost::thread_group threadGroup; +std::vector threadGroup; static CScheduler scheduler; #if HAVE_SYSTEM @@ -236,9 +231,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. @@ -760,6 +758,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); @@ -777,6 +779,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()); @@ -1175,15 +1181,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) { @@ -1421,15 +1418,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); @@ -2001,7 +2010,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 { @@ -2208,13 +2217,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/masternodes/anchors.h b/src/masternodes/anchors.h index 713b058425..d27b7a026b 100644 --- a/src/masternodes/anchors.h +++ b/src/masternodes/anchors.h @@ -9,6 +9,7 @@ #include