aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build-aux/m4/bitcoin_qt.m4106
-rw-r--r--build_msvc/bitcoin_config.h8
-rwxr-xr-xci/test/00_setup_env.sh2
-rw-r--r--ci/test/00_setup_env_i686_centos.sh2
-rw-r--r--ci/test/00_setup_env_mac.sh2
-rw-r--r--configure.ac5
-rwxr-xr-xcontrib/devtools/symbol-check.py10
-rw-r--r--contrib/gitian-descriptors/gitian-linux.yml1
-rw-r--r--contrib/gitian-descriptors/gitian-osx.yml1
-rw-r--r--contrib/guix/manifest.scm2
-rw-r--r--contrib/init/bitcoind.openrc7
-rw-r--r--depends/README.md2
-rw-r--r--depends/packages/libxcb.mk15
-rw-r--r--depends/packages/libxkbcommon.mk32
-rw-r--r--depends/packages/packages.mk4
-rw-r--r--depends/packages/qt.mk50
-rw-r--r--depends/packages/zlib.mk31
-rw-r--r--depends/patches/qt/drop_lrelease_dependency.patch2
-rw-r--r--depends/patches/qt/fix_android_jni_static.patch2
-rw-r--r--depends/patches/qt/fix_android_qmake_conf.patch24
-rw-r--r--depends/patches/qt/fix_configure_mac.patch50
-rw-r--r--depends/patches/qt/fix_lib_paths.patch193
-rw-r--r--depends/patches/qt/fix_mingw_cross_compile.patch25
-rw-r--r--depends/patches/qt/fix_no_printer.patch4
-rw-r--r--depends/patches/qt/fix_powerpc_libpng.patch23
-rw-r--r--depends/patches/qt/fix_qpainter_non_determinism.patch4
-rw-r--r--depends/patches/qt/fix_qt_pkgconfig.patch12
-rw-r--r--depends/patches/qt/fix_rcc_determinism.patch15
-rw-r--r--depends/patches/qt/fix_riscv64_arch.patch14
-rw-r--r--depends/patches/qt/freetype_back_compat.patch28
-rw-r--r--depends/patches/qt/no-xlib.patch17
-rw-r--r--depends/patches/qt/no_sdk_version_check.patch20
-rw-r--r--depends/patches/qt/xkb-default.patch26
-rw-r--r--doc/developer-notes.md5
-rw-r--r--src/Makefile.am3
-rw-r--r--src/bench/coin_selection.cpp4
-rw-r--r--src/bitcoind.cpp123
-rw-r--r--src/chainparamsbase.cpp9
-rw-r--r--src/httprpc.cpp2
-rw-r--r--src/index/blockfilterindex.cpp4
-rw-r--r--src/index/txindex.cpp2
-rw-r--r--src/init.cpp13
-rw-r--r--src/init.h5
-rw-r--r--src/interfaces/chain.h3
-rw-r--r--src/interfaces/handler.cpp5
-rw-r--r--src/miner.cpp12
-rw-r--r--src/miner.h4
-rw-r--r--src/net.cpp12
-rw-r--r--src/net_processing.cpp307
-rw-r--r--src/node/coin.cpp3
-rw-r--r--src/node/coinstats.cpp13
-rw-r--r--src/node/coinstats.h3
-rw-r--r--src/node/interfaces.cpp71
-rw-r--r--src/node/transaction.cpp7
-rw-r--r--src/qt/bitcoin.cpp1
-rw-r--r--src/qt/guiutil.cpp20
-rw-r--r--src/qt/psbtoperationsdialog.cpp2
-rw-r--r--src/qt/receivecoinsdialog.cpp3
-rw-r--r--src/qt/sendcoinsdialog.cpp4
-rw-r--r--src/qt/transactionview.cpp2
-rw-r--r--src/rpc/blockchain.cpp155
-rw-r--r--src/rpc/mining.cpp170
-rw-r--r--src/rpc/request.h6
-rw-r--r--src/rpc/server.cpp33
-rw-r--r--src/rpc/server.h2
-rw-r--r--src/rpc/util.cpp19
-rw-r--r--src/rpc/util.h20
-rw-r--r--src/script/descriptor.cpp46
-rw-r--r--src/shutdown.cpp56
-rw-r--r--src/test/allocator_tests.cpp3
-rw-r--r--src/test/blockfilter_index_tests.cpp2
-rw-r--r--src/test/checkqueue_tests.cpp15
-rw-r--r--src/test/dbwrapper_tests.cpp5
-rw-r--r--src/test/denialofservice_tests.cpp13
-rw-r--r--src/test/fuzz/FuzzedDataProvider.h1
-rw-r--r--src/test/fuzz/coins_view.cpp2
-rw-r--r--src/test/fuzz/descriptor_parse.cpp1
-rw-r--r--src/test/fuzz/eval_script.cpp1
-rw-r--r--src/test/fuzz/key.cpp1
-rw-r--r--src/test/fuzz/parse_univalue.cpp1
-rw-r--r--src/test/fuzz/process_message.cpp1
-rw-r--r--src/test/fuzz/process_messages.cpp1
-rw-r--r--src/test/fuzz/psbt.cpp1
-rw-r--r--src/test/fuzz/script.cpp1
-rw-r--r--src/test/fuzz/script_flags.cpp1
-rw-r--r--src/test/fuzz/signature_checker.cpp3
-rw-r--r--src/test/miner_tests.cpp38
-rw-r--r--src/test/net_tests.cpp11
-rw-r--r--src/test/rpc_tests.cpp1
-rw-r--r--src/test/util/logging.cpp1
-rw-r--r--src/test/util/mining.cpp2
-rw-r--r--src/test/util/setup_common.cpp11
-rw-r--r--src/test/util_tests.cpp2
-rw-r--r--src/test/validation_block_tests.cpp4
-rw-r--r--src/txdb.cpp5
-rw-r--r--src/txrequest.cpp3
-rw-r--r--src/util/memory.h20
-rw-r--r--src/util/system.cpp2
-rw-r--r--src/util/system.h1
-rw-r--r--src/util/tokenpipe.cpp108
-rw-r--r--src/util/tokenpipe.h127
-rw-r--r--src/validation.cpp8
-rw-r--r--src/validation.h3
-rw-r--r--src/wallet/bdb.cpp8
-rw-r--r--src/wallet/db.h3
-rw-r--r--src/wallet/interfaces.cpp4
-rw-r--r--src/wallet/rpcdump.cpp120
-rw-r--r--src/wallet/rpcwallet.cpp315
-rw-r--r--src/wallet/rpcwallet.h2
-rw-r--r--src/wallet/salvage.cpp2
-rw-r--r--src/wallet/scriptpubkeyman.cpp18
-rw-r--r--src/wallet/sqlite.cpp5
-rw-r--r--src/wallet/test/coinselector_tests.cpp2
-rw-r--r--src/wallet/test/wallet_tests.cpp2
-rw-r--r--src/wallet/wallet.cpp6
-rw-r--r--src/wallet/walletdb.cpp6
-rw-r--r--src/zmq/zmqabstractnotifier.h3
-rwxr-xr-xtest/functional/wallet_groups.py16
-rwxr-xr-xtest/fuzz/test_runner.py54
119 files changed, 1590 insertions, 1264 deletions
diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4
index b559baba23..1fd88db08f 100644
--- a/build-aux/m4/bitcoin_qt.m4
+++ b/build-aux/m4/bitcoin_qt.m4
@@ -111,9 +111,7 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[
dnl For Qt5, we can check a header to find out whether Qt is build
dnl statically. When Qt is built statically, some plugins must be linked into
dnl the final binary as well.
- dnl With Qt5, languages moved into core and the WindowsIntegration plugin was
- dnl added.
- dnl _BITCOIN_QT_CHECK_STATIC_PLUGINS does a quick link-check and appends the
+ dnl _BITCOIN_QT_CHECK_STATIC_PLUGIN does a quick link-check and appends the
dnl results to QT_LIBS.
BITCOIN_QT_CHECK([
TEMP_CPPFLAGS=$CPPFLAGS
@@ -122,20 +120,41 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[
CXXFLAGS="$PIC_FLAGS $CXXFLAGS"
_BITCOIN_QT_IS_STATIC
if test "x$bitcoin_cv_static_qt" = xyes; then
- _BITCOIN_QT_FIND_STATIC_PLUGINS
+ _BITCOIN_QT_CHECK_STATIC_LIBS
+
+ if test "x$qt_plugin_path" != x; then
+ QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms -L$qt_plugin_path/styles"
+ if test -d "$qt_plugin_path/accessible"; then
+ QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible"
+ fi
+ if test -d "$qt_plugin_path/platforms/android"; then
+ QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms/android -lqtfreetype -lEGL"
+ fi
+ fi
+
AC_DEFINE(QT_STATICPLUGIN, 1, [Define this symbol if qt plugins are static])
if test "x$TARGET_OS" != xandroid; then
- _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QMinimalIntegrationPlugin)],[-lqminimal])
+ _BITCOIN_QT_CHECK_STATIC_PLUGIN([QMinimalIntegrationPlugin], [-lqminimal])
AC_DEFINE(QT_QPA_PLATFORM_MINIMAL, 1, [Define this symbol if the minimal qt platform exists])
fi
if test "x$TARGET_OS" = xwindows; then
- _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)],[-lqwindows])
+ dnl Linking against wtsapi32 is required. See #17749 and
+ dnl https://bugreports.qt.io/browse/QTBUG-27097.
+ AX_CHECK_LINK_FLAG([-lwtsapi32], [QT_LIBS="$QT_LIBS -lwtsapi32"], [AC_MSG_ERROR([could not link against -lwtsapi32])])
+ _BITCOIN_QT_CHECK_STATIC_PLUGIN([QWindowsIntegrationPlugin], [-lqwindows])
AC_DEFINE(QT_QPA_PLATFORM_WINDOWS, 1, [Define this symbol if the qt platform is windows])
elif test "x$TARGET_OS" = xlinux; then
- _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QXcbIntegrationPlugin)],[-lqxcb -lxcb-static])
+ dnl workaround for https://bugreports.qt.io/browse/QTBUG-74874
+ AX_CHECK_LINK_FLAG([-lxcb-shm], [QT_LIBS="-lxcb-shm $QT_LIBS"], [AC_MSG_ERROR([could not link against -lxcb-shm])])
+ _BITCOIN_QT_CHECK_STATIC_PLUGIN([QXcbIntegrationPlugin], [-lqxcb -lxcb-static])
AC_DEFINE(QT_QPA_PLATFORM_XCB, 1, [Define this symbol if the qt platform is xcb])
elif test "x$TARGET_OS" = xdarwin; then
- _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin)],[-lqcocoa])
+ AX_CHECK_LINK_FLAG([[-framework Carbon]],[QT_LIBS="$QT_LIBS -framework Carbon"],[AC_MSG_ERROR(could not link against Carbon framework)])
+ AX_CHECK_LINK_FLAG([[-framework IOSurface]],[QT_LIBS="$QT_LIBS -framework IOSurface"],[AC_MSG_ERROR(could not link against IOSurface framework)])
+ AX_CHECK_LINK_FLAG([[-framework Metal]],[QT_LIBS="$QT_LIBS -framework Metal"],[AC_MSG_ERROR(could not link against Metal framework)])
+ AX_CHECK_LINK_FLAG([[-framework QuartzCore]],[QT_LIBS="$QT_LIBS -framework QuartzCore"],[AC_MSG_ERROR(could not link against QuartzCore framework)])
+ _BITCOIN_QT_CHECK_STATIC_PLUGIN([QCocoaIntegrationPlugin], [-lqcocoa])
+ _BITCOIN_QT_CHECK_STATIC_PLUGIN([QMacStylePlugin], [-lqmacstyle])
AC_DEFINE(QT_QPA_PLATFORM_COCOA, 1, [Define this symbol if the qt platform is cocoa])
elif test "x$TARGET_OS" = xandroid; then
QT_LIBS="-Wl,--export-dynamic,--undefined=JNI_OnLoad -lqtforandroid -ljnigraphics -landroid -lqtfreetype -lQt5EglSupport $QT_LIBS"
@@ -284,51 +303,50 @@ AC_DEFUN([_BITCOIN_QT_IS_STATIC],[
])
])
-dnl Internal. Check if the link-requirements for static plugins are met.
+dnl Internal. Check if the link-requirements for a static plugin are met.
+dnl
+dnl _BITCOIN_QT_CHECK_STATIC_PLUGIN(PLUGIN, LIBRARIES)
+dnl --------------------------------------------------
+dnl
dnl Requires: INCLUDES and LIBS must be populated as necessary.
-dnl Inputs: $1: A series of Q_IMPORT_PLUGIN().
+dnl Inputs: $1: A static plugin name.
dnl Inputs: $2: The libraries that resolve $1.
dnl Output: QT_LIBS is prepended or configure exits.
-AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_PLUGINS],[
- AC_MSG_CHECKING(for static Qt plugins: $2)
+AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_PLUGIN], [
+ AC_MSG_CHECKING([for $1 ($2)])
CHECK_STATIC_PLUGINS_TEMP_LIBS="$LIBS"
LIBS="$2${qt_lib_suffix} $QT_LIBS $LIBS"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
- #define QT_STATICPLUGIN
- #include <QtPlugin>
- $1]],
- [[return 0;]])],
- [AC_MSG_RESULT(yes); QT_LIBS="$2${qt_lib_suffix} $QT_LIBS"],
- [AC_MSG_RESULT(no); BITCOIN_QT_FAIL(Could not resolve: $2)])
+ #include <QtPlugin>
+ Q_IMPORT_PLUGIN($1)
+ ]])],
+ [AC_MSG_RESULT([yes]); QT_LIBS="$2${qt_lib_suffix} $QT_LIBS"],
+ [AC_MSG_RESULT([no]); BITCOIN_QT_FAIL([$1 not found.])])
LIBS="$CHECK_STATIC_PLUGINS_TEMP_LIBS"
])
-dnl Internal. Find paths necessary for linking qt static plugins
-dnl Inputs: qt_plugin_path. optional.
-dnl Outputs: QT_LIBS is appended
-AC_DEFUN([_BITCOIN_QT_FIND_STATIC_PLUGINS],[
- if test "x$qt_plugin_path" != x; then
- QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms"
- if test -d "$qt_plugin_path/accessible"; then
- QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible"
- fi
- if test -d "$qt_plugin_path/platforms/android"; then
- QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms/android -lqtfreetype -lEGL"
- fi
- PKG_CHECK_MODULES([QTFONTDATABASE], [Qt5FontDatabaseSupport${qt_lib_suffix}], [QT_LIBS="-lQt5FontDatabaseSupport${qt_lib_suffix} $QT_LIBS"])
- PKG_CHECK_MODULES([QTEVENTDISPATCHER], [Qt5EventDispatcherSupport${qt_lib_suffix}], [QT_LIBS="-lQt5EventDispatcherSupport${qt_lib_suffix} $QT_LIBS"])
- PKG_CHECK_MODULES([QTTHEME], [Qt5ThemeSupport${qt_lib_suffix}], [QT_LIBS="-lQt5ThemeSupport${qt_lib_suffix} $QT_LIBS"])
- PKG_CHECK_MODULES([QTDEVICEDISCOVERY], [Qt5DeviceDiscoverySupport${qt_lib_suffix}], [QT_LIBS="-lQt5DeviceDiscoverySupport${qt_lib_suffix} $QT_LIBS"])
- PKG_CHECK_MODULES([QTACCESSIBILITY], [Qt5AccessibilitySupport${qt_lib_suffix}], [QT_LIBS="-lQt5AccessibilitySupport${qt_lib_suffix} $QT_LIBS"])
- PKG_CHECK_MODULES([QTFB], [Qt5FbSupport${qt_lib_suffix}], [QT_LIBS="-lQt5FbSupport${qt_lib_suffix} $QT_LIBS"])
- if test "x$TARGET_OS" = xlinux; then
- PKG_CHECK_MODULES([QTXCBQPA], [Qt5XcbQpa], [QT_LIBS="$QTXCBQPA_LIBS $QT_LIBS"])
- elif test "x$TARGET_OS" = xdarwin; then
- PKG_CHECK_MODULES([QTCLIPBOARD], [Qt5ClipboardSupport${qt_lib_suffix}], [QT_LIBS="-lQt5ClipboardSupport${qt_lib_suffix} $QT_LIBS"])
- PKG_CHECK_MODULES([QTGRAPHICS], [Qt5GraphicsSupport${qt_lib_suffix}], [QT_LIBS="-lQt5GraphicsSupport${qt_lib_suffix} $QT_LIBS"])
- PKG_CHECK_MODULES([QTCGL], [Qt5CglSupport${qt_lib_suffix}], [QT_LIBS="-lQt5CglSupport${qt_lib_suffix} $QT_LIBS"])
- fi
- fi
+dnl Internal. Check Qt static libs with PKG_CHECK_MODULES.
+dnl
+dnl _BITCOIN_QT_CHECK_STATIC_LIBS
+dnl -----------------------------
+dnl
+dnl Inputs: no inputs.
+dnl Outputs: QT_LIBS is prepended.
+AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_LIBS], [
+ PKG_CHECK_MODULES([QTFONTDATABASE], [Qt5FontDatabaseSupport${qt_lib_suffix}], [QT_LIBS="-lQt5FontDatabaseSupport${qt_lib_suffix} $QT_LIBS"])
+ PKG_CHECK_MODULES([QTEVENTDISPATCHER], [Qt5EventDispatcherSupport${qt_lib_suffix}], [QT_LIBS="-lQt5EventDispatcherSupport${qt_lib_suffix} $QT_LIBS"])
+ PKG_CHECK_MODULES([QTTHEME], [Qt5ThemeSupport${qt_lib_suffix}], [QT_LIBS="-lQt5ThemeSupport${qt_lib_suffix} $QT_LIBS"])
+ PKG_CHECK_MODULES([QTDEVICEDISCOVERY], [Qt5DeviceDiscoverySupport${qt_lib_suffix}], [QT_LIBS="-lQt5DeviceDiscoverySupport${qt_lib_suffix} $QT_LIBS"])
+ PKG_CHECK_MODULES([QTACCESSIBILITY], [Qt5AccessibilitySupport${qt_lib_suffix}], [QT_LIBS="-lQt5AccessibilitySupport${qt_lib_suffix} $QT_LIBS"])
+ PKG_CHECK_MODULES([QTFB], [Qt5FbSupport${qt_lib_suffix}], [QT_LIBS="-lQt5FbSupport${qt_lib_suffix} $QT_LIBS"])
+ if test "x$TARGET_OS" = xlinux; then
+ PKG_CHECK_MODULES([QTXCBQPA], [Qt5XcbQpa], [QT_LIBS="$QTXCBQPA_LIBS $QT_LIBS"])
+ elif test "x$TARGET_OS" = xdarwin; then
+ PKG_CHECK_MODULES([QTCLIPBOARD], [Qt5ClipboardSupport${qt_lib_suffix}], [QT_LIBS="-lQt5ClipboardSupport${qt_lib_suffix} $QT_LIBS"])
+ PKG_CHECK_MODULES([QTGRAPHICS], [Qt5GraphicsSupport${qt_lib_suffix}], [QT_LIBS="-lQt5GraphicsSupport${qt_lib_suffix} $QT_LIBS"])
+ elif test "x$TARGET_OS" = xwindows; then
+ PKG_CHECK_MODULES([QTWINDOWSUIAUTOMATION], [Qt5WindowsUIAutomationSupport${qt_lib_suffix}], [QT_LIBS="-lQt5WindowsUIAutomationSupport${qt_lib_suffix} $QT_LIBS"])
+ fi
])
dnl Internal. Find Qt libraries using pkg-config.
diff --git a/build_msvc/bitcoin_config.h b/build_msvc/bitcoin_config.h
index 40a30b9749..dd01cb29eb 100644
--- a/build_msvc/bitcoin_config.h
+++ b/build_msvc/bitcoin_config.h
@@ -92,9 +92,9 @@
don't. */
#define HAVE_DECL_BSWAP_64 0
-/* Define to 1 if you have the declaration of `daemon', and to 0 if you don't.
+/* Define to 1 if you have the declaration of `fork', and to 0 if you don't.
*/
-#define HAVE_DECL_DAEMON 0
+#define HAVE_DECL_FORK 0
/* Define to 1 if you have the declaration of `htobe16', and to 0 if you
don't. */
@@ -132,6 +132,10 @@
don't. */
#define HAVE_DECL_LE64TOH 0
+/* Define to 1 if you have the declaration of `setsid', and to 0 if you don't.
+ */
+#define HAVE_DECL_SETSID 0
+
/* Define to 1 if you have the declaration of `strerror_r', and to 0 if you
don't. */
#define HAVE_DECL_STRERROR_R 0
diff --git a/ci/test/00_setup_env.sh b/ci/test/00_setup_env.sh
index 72e29141a6..87cf8538f6 100755
--- a/ci/test/00_setup_env.sh
+++ b/ci/test/00_setup_env.sh
@@ -65,7 +65,7 @@ export BASE_OUTDIR=${BASE_OUTDIR:-$BASE_SCRATCH_DIR/out/$HOST}
export BASE_BUILD_DIR=${BASE_BUILD_DIR:-$BASE_SCRATCH_DIR/build}
export PREVIOUS_RELEASES_DIR=${PREVIOUS_RELEASES_DIR:-$BASE_ROOT_DIR/releases/$HOST}
export SDK_URL=${SDK_URL:-https://bitcoincore.org/depends-sources/sdks}
-export DOCKER_PACKAGES=${DOCKER_PACKAGES:-build-essential libtool autotools-dev automake pkg-config bsdmainutils curl ca-certificates ccache python3 rsync git procps}
+export DOCKER_PACKAGES=${DOCKER_PACKAGES:-build-essential libtool autotools-dev automake pkg-config bsdmainutils curl ca-certificates ccache python3 rsync git procps bison}
export GOAL=${GOAL:-install}
export DIR_QA_ASSETS=${DIR_QA_ASSETS:-${BASE_SCRATCH_DIR}/qa-assets}
export PATH=${BASE_ROOT_DIR}/ci/retry:$PATH
diff --git a/ci/test/00_setup_env_i686_centos.sh b/ci/test/00_setup_env_i686_centos.sh
index 1ec44a7a1a..07e7c2dc27 100644
--- a/ci/test/00_setup_env_i686_centos.sh
+++ b/ci/test/00_setup_env_i686_centos.sh
@@ -9,7 +9,7 @@ export LC_ALL=C.UTF-8
export HOST=i686-pc-linux-gnu
export CONTAINER_NAME=ci_i686_centos_8
export DOCKER_NAME_TAG=centos:8
-export DOCKER_PACKAGES="gcc-c++ glibc-devel.x86_64 libstdc++-devel.x86_64 glibc-devel.i686 libstdc++-devel.i686 ccache libtool make git python3 python3-zmq which patch lbzip2 dash rsync coreutils"
+export DOCKER_PACKAGES="gcc-c++ glibc-devel.x86_64 libstdc++-devel.x86_64 glibc-devel.i686 libstdc++-devel.i686 ccache libtool make git python3 python3-zmq which patch lbzip2 dash rsync coreutils bison"
export GOAL="install"
export BITCOIN_CONFIG="--enable-zmq --with-gui=qt5 --enable-reduce-exports --with-boost-process"
export CONFIG_SHELL="/bin/dash"
diff --git a/ci/test/00_setup_env_mac.sh b/ci/test/00_setup_env_mac.sh
index 645dcffd02..6ce3812447 100644
--- a/ci/test/00_setup_env_mac.sh
+++ b/ci/test/00_setup_env_mac.sh
@@ -9,7 +9,7 @@ export LC_ALL=C.UTF-8
export CONTAINER_NAME=ci_macos_cross
export DOCKER_NAME_TAG=ubuntu:20.04 # Check that Focal can cross-compile to macos (Focal is used in the gitian build as well)
export HOST=x86_64-apple-darwin18
-export PACKAGES="cmake imagemagick librsvg2-bin libz-dev libtiff-tools libtinfo5 python3-dev python3-setuptools xorriso"
+export PACKAGES="cmake imagemagick librsvg2-bin libz-dev libtiff-tools libtinfo5 python3-setuptools xorriso"
export XCODE_VERSION=11.3.1
export XCODE_BUILD_ID=11C505
export RUN_UNIT_TESTS=false
diff --git a/configure.ac b/configure.ac
index 391a75eeed..0b176e6039 100644
--- a/configure.ac
+++ b/configure.ac
@@ -922,8 +922,9 @@ AC_CHECK_DECLS([getifaddrs, freeifaddrs],,,
)
AC_CHECK_DECLS([strnlen])
-dnl Check for daemon(3), unrelated to --with-daemon (although used by it)
-AC_CHECK_DECLS([daemon])
+dnl These are used for daemonization in bitcoind
+AC_CHECK_DECLS([fork])
+AC_CHECK_DECLS([setsid])
AC_CHECK_DECLS([pipe2])
diff --git a/contrib/devtools/symbol-check.py b/contrib/devtools/symbol-check.py
index b30ed62521..436f179d61 100755
--- a/contrib/devtools/symbol-check.py
+++ b/contrib/devtools/symbol-check.py
@@ -73,6 +73,8 @@ ELF_ALLOWED_LIBRARIES = {
'ld-linux-riscv64-lp64d.so.1', # 64-bit RISC-V dynamic linker
# bitcoin-qt only
'libxcb.so.1', # part of X11
+'libxkbcommon.so.0', # keyboard keymapping
+'libxkbcommon-x11.so.0', # keyboard keymapping
'libfontconfig.so.1', # font support
'libfreetype.so.6', # font parsing
'libdl.so.2' # programming interface to dynamic linker
@@ -98,10 +100,15 @@ MACHO_ALLOWED_LIBRARIES = {
'CoreGraphics', # 2D rendering
'CoreServices', # operating system services
'CoreText', # interface for laying out text and handling fonts.
+'CoreVideo', # video processing
'Foundation', # base layer functionality for apps/frameworks
'ImageIO', # read and write image file formats.
'IOKit', # user-space access to hardware devices and drivers.
+'IOSurface', # cross process image/drawing buffers
'libobjc.A.dylib', # Objective-C runtime library
+'Metal', # 3D graphics
+'Security', # access control and authentication
+'QuartzCore', # animation
}
PE_ALLOWED_LIBRARIES = {
@@ -116,12 +123,15 @@ PE_ALLOWED_LIBRARIES = {
'dwmapi.dll', # desktop window manager
'GDI32.dll', # graphics device interface
'IMM32.dll', # input method editor
+'NETAPI32.dll',
'ole32.dll', # component object model
'OLEAUT32.dll', # OLE Automation API
'SHLWAPI.dll', # light weight shell API
+'USERENV.dll',
'UxTheme.dll',
'VERSION.dll', # version checking
'WINMM.dll', # WinMM audio API
+'WTSAPI32.dll',
}
class CPPFilt(object):
diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml
index b06fc782a3..52e2a0514a 100644
--- a/contrib/gitian-descriptors/gitian-linux.yml
+++ b/contrib/gitian-descriptors/gitian-linux.yml
@@ -11,6 +11,7 @@ packages:
- "autoconf"
- "automake"
- "binutils"
+- "bison"
- "bsdmainutils"
- "ca-certificates"
- "curl"
diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml
index 98c3888b45..c37ad5b842 100644
--- a/contrib/gitian-descriptors/gitian-osx.yml
+++ b/contrib/gitian-descriptors/gitian-osx.yml
@@ -23,7 +23,6 @@ packages:
- "imagemagick"
- "libz-dev"
- "python3"
-- "python3-dev"
- "python3-setuptools"
- "fonts-tuffy"
- "xorriso"
diff --git a/contrib/guix/manifest.scm b/contrib/guix/manifest.scm
index bd9f895dce..4228532cb1 100644
--- a/contrib/guix/manifest.scm
+++ b/contrib/guix/manifest.scm
@@ -3,6 +3,7 @@
(gnu packages autotools)
(gnu packages base)
(gnu packages bash)
+ (gnu packages bison)
(gnu packages cdrom)
(gnu packages check)
(gnu packages cmake)
@@ -219,6 +220,7 @@ chain for " target " development."))
autoconf
automake
pkg-config
+ bison
;; Scripting
perl
python-3
diff --git a/contrib/init/bitcoind.openrc b/contrib/init/bitcoind.openrc
index 86222295db..013a1a6070 100644
--- a/contrib/init/bitcoind.openrc
+++ b/contrib/init/bitcoind.openrc
@@ -60,16 +60,17 @@ start_pre() {
"${BITCOIND_PIDDIR}"
checkpath -f \
- -o ${BITCOIND_USER}:${BITCOIND_GROUP} \
+ -o "${BITCOIND_USER}:${BITCOIND_GROUP}" \
-m 0660 \
- ${BITCOIND_CONFIGFILE}
+ "${BITCOIND_CONFIGFILE}"
checkconfig || return 1
}
checkconfig()
{
- if ! grep -qs '^rpcpassword=' "${BITCOIND_CONFIGFILE}" ; then
+ if grep -qs '^rpcuser=' "${BITCOIND_CONFIGFILE}" && \
+ ! grep -qs '^rpcpassword=' "${BITCOIND_CONFIGFILE}" ; then
eerror ""
eerror "ERROR: You must set a secure rpcpassword to run bitcoind."
eerror "The setting must appear in ${BITCOIND_CONFIGFILE}"
diff --git a/depends/README.md b/depends/README.md
index e72c666474..a1d4a99084 100644
--- a/depends/README.md
+++ b/depends/README.md
@@ -54,7 +54,7 @@ The paths are automatically configured and no other options are needed unless ta
Common linux dependencies:
- sudo apt-get install make automake cmake curl g++-multilib libtool binutils-gold bsdmainutils pkg-config python3 patch
+ sudo apt-get install make automake cmake curl g++-multilib libtool binutils-gold bsdmainutils pkg-config python3 patch bison
For linux ARM cross compilation:
diff --git a/depends/packages/libxcb.mk b/depends/packages/libxcb.mk
index 2204b38195..710f43959c 100644
--- a/depends/packages/libxcb.mk
+++ b/depends/packages/libxcb.mk
@@ -15,25 +15,20 @@ $(package)_config_opts += --disable-composite --disable-damage --disable-dpms
$(package)_config_opts += --disable-dri2 --disable-dri3 --disable-glx
$(package)_config_opts += --disable-present --disable-randr --disable-record
$(package)_config_opts += --disable-render --disable-resource --disable-screensaver
-$(package)_config_opts += --disable-shape --disable-shm --disable-sync
+$(package)_config_opts += --disable-shape --disable-sync
$(package)_config_opts += --disable-xevie --disable-xfixes --disable-xfree86-dri
-$(package)_config_opts += --disable-xinerama --disable-xinput --disable-xkb
+$(package)_config_opts += --disable-xinerama --disable-xinput
$(package)_config_opts += --disable-xprint --disable-selinux --disable-xtest
$(package)_config_opts += --disable-xv --disable-xvmc
endef
define $(package)_preprocess_cmds
- cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub build-aux &&\
+ cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub build-aux && \
sed "s/pthread-stubs//" -i configure
endef
-# Don't install xcb headers to the default path in order to work around a qt
-# build issue: https://bugreports.qt.io/browse/QTBUG-34748
-# When using qt's internal libxcb, it may end up finding the real headers in
-# depends staging. Use a non-default path to avoid that.
-
define $(package)_config_cmds
- $($(package)_autoconf) --includedir=$(host_prefix)/include/xcb-shared
+ $($(package)_autoconf)
endef
define $(package)_build_cmds
@@ -45,5 +40,5 @@ define $(package)_stage_cmds
endef
define $(package)_postprocess_cmds
- rm -rf share/man share/doc lib/*.la
+ rm -rf share lib/*.la
endef
diff --git a/depends/packages/libxkbcommon.mk b/depends/packages/libxkbcommon.mk
new file mode 100644
index 0000000000..cdd5af194b
--- /dev/null
+++ b/depends/packages/libxkbcommon.mk
@@ -0,0 +1,32 @@
+package=libxkbcommon
+$(package)_version=0.8.4
+$(package)_download_path=https://xkbcommon.org/download/
+$(package)_file_name=$(package)-$($(package)_version).tar.xz
+$(package)_sha256_hash=60ddcff932b7fd352752d51a5c4f04f3d0403230a584df9a2e0d5ed87c486c8b
+$(package)_dependencies=libxcb
+
+define $(package)_set_vars
+$(package)_config_opts = --enable-option-checking --disable-dependency-tracking
+$(package)_config_opts += --disable-static --disable-docs
+endef
+
+define $(package)_preprocess_cmds
+ cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub build-aux
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE)
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install
+endef
+
+define $(package)_postprocess_cmds
+ rm -rf share/man share/doc lib/*.la
+endef
+
diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk
index 0f35ca0d2d..810068b686 100644
--- a/depends/packages/packages.mk
+++ b/depends/packages/packages.mk
@@ -1,10 +1,8 @@
packages:=boost libevent
-qt_packages = zlib
-
qrencode_packages = qrencode
-qt_linux_packages:=qt expat libxcb xcb_proto libXau xproto freetype fontconfig
+qt_linux_packages:=qt expat libxcb xcb_proto libXau xproto freetype fontconfig libxkbcommon
qt_android_packages=qt
qt_darwin_packages=qt
diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk
index 7d122ea5f9..0ac6f496c4 100644
--- a/depends/packages/qt.mk
+++ b/depends/packages/qt.mk
@@ -1,23 +1,21 @@
PACKAGE=qt
-$(package)_version=5.9.8
-$(package)_download_path=https://download.qt.io/official_releases/qt/5.9/$($(package)_version)/submodules
-$(package)_suffix=opensource-src-$($(package)_version).tar.xz
+$(package)_version=5.12.10
+$(package)_download_path=https://download.qt.io/official_releases/qt/5.12/$($(package)_version)/submodules
+$(package)_suffix=everywhere-src-$($(package)_version).tar.xz
$(package)_file_name=qtbase-$($(package)_suffix)
-$(package)_sha256_hash=9b9dec1f67df1f94bce2955c5604de992d529dde72050239154c56352da0907d
-$(package)_dependencies=zlib
-$(package)_linux_dependencies=freetype fontconfig libxcb
+$(package)_sha256_hash=8088f174e6d28e779516c083b6087b6a9e3c8322b4bc161fd1b54195e3c86940
+$(package)_linux_dependencies=freetype fontconfig libxcb libxkbcommon
$(package)_qt_libs=corelib network widgets gui plugins testlib
-$(package)_patches=fix_qt_pkgconfig.patch mac-qmake.conf fix_configure_mac.patch fix_no_printer.patch
-$(package)_patches+= fix_rcc_determinism.patch fix_riscv64_arch.patch xkb-default.patch no-xlib.patch
+$(package)_patches=fix_qt_pkgconfig.patch mac-qmake.conf fix_no_printer.patch no-xlib.patch
$(package)_patches+= fix_android_qmake_conf.patch fix_android_jni_static.patch dont_hardcode_pwd.patch
-$(package)_patches+= freetype_back_compat.patch drop_lrelease_dependency.patch fix_powerpc_libpng.patch
-$(package)_patches+= fix_mingw_cross_compile.patch fix_qpainter_non_determinism.patch
+$(package)_patches+= drop_lrelease_dependency.patch no_sdk_version_check.patch
+$(package)_patches+= fix_qpainter_non_determinism.patch fix_lib_paths.patch
$(package)_qttranslations_file_name=qttranslations-$($(package)_suffix)
-$(package)_qttranslations_sha256_hash=fb5a47799754af73d3bf501fe513342cfe2fc37f64e80df5533f6110e804220c
+$(package)_qttranslations_sha256_hash=e1de58ed108b7e0a138815ea60fd46a2c4e1fc31396a707e5630e92de79c53de
$(package)_qttools_file_name=qttools-$($(package)_suffix)
-$(package)_qttools_sha256_hash=a97556eb7b2f30252cdd8a598c396cfce2b2f79d2bae883af6d3b26a2cdcc63c
+$(package)_qttools_sha256_hash=b0cfa6e7aac41b7c61fc59acc04843d7a98f9e1840370611751bcfc1834a636c
$(package)_extra_sources = $($(package)_qttranslations_file_name)
$(package)_extra_sources += $($(package)_qttools_file_name)
@@ -26,6 +24,7 @@ define $(package)_set_vars
$(package)_config_opts_release = -release
$(package)_config_opts_release += -silent
$(package)_config_opts_debug = -debug
+$(package)_config_opts_debug += -optimized-tools
$(package)_config_opts += -bindir $(build_prefix)/bin
$(package)_config_opts += -c++std c++1z
$(package)_config_opts += -confirm-license
@@ -49,7 +48,6 @@ $(package)_config_opts += -no-mtdev
$(package)_config_opts += -no-openssl
$(package)_config_opts += -no-openvg
$(package)_config_opts += -no-reduce-relocations
-$(package)_config_opts += -no-qml-debug
$(package)_config_opts += -no-sctp
$(package)_config_opts += -no-securetransport
$(package)_config_opts += -no-sql-db2
@@ -63,17 +61,15 @@ $(package)_config_opts += -no-sql-sqlite
$(package)_config_opts += -no-sql-sqlite2
$(package)_config_opts += -no-system-proxies
$(package)_config_opts += -no-use-gold-linker
-$(package)_config_opts += -no-xinput2
$(package)_config_opts += -nomake examples
$(package)_config_opts += -nomake tests
$(package)_config_opts += -opensource
-$(package)_config_opts += -optimized-tools
$(package)_config_opts += -pkg-config
$(package)_config_opts += -prefix $(host_prefix)
$(package)_config_opts += -qt-libpng
$(package)_config_opts += -qt-pcre
$(package)_config_opts += -qt-harfbuzz
-$(package)_config_opts += -system-zlib
+$(package)_config_opts += -qt-zlib
$(package)_config_opts += -static
$(package)_config_opts += -v
$(package)_config_opts += -no-feature-bearermanagement
@@ -94,10 +90,10 @@ $(package)_config_opts += -no-feature-printdialog
$(package)_config_opts += -no-feature-printer
$(package)_config_opts += -no-feature-printpreviewdialog
$(package)_config_opts += -no-feature-printpreviewwidget
-$(package)_config_opts += -no-feature-regularexpression
$(package)_config_opts += -no-feature-sessionmanager
$(package)_config_opts += -no-feature-socks5
$(package)_config_opts += -no-feature-sql
+$(package)_config_opts += -no-feature-sqlmodel
$(package)_config_opts += -no-feature-statemachine
$(package)_config_opts += -no-feature-syntaxhighlighter
$(package)_config_opts += -no-feature-textbrowser
@@ -115,6 +111,7 @@ $(package)_config_opts += -no-feature-xml
$(package)_config_opts_darwin = -no-dbus
$(package)_config_opts_darwin += -no-opengl
$(package)_config_opts_darwin += -pch
+$(package)_config_opts_darwin += -device-option QMAKE_MACOSX_DEPLOYMENT_TARGET=$(OSX_MIN_VERSION)
ifneq ($(build_os),darwin)
$(package)_config_opts_darwin += -xplatform macx-clang-linux
@@ -129,13 +126,13 @@ endif
# for macOS on Apple Silicon (ARM) see https://bugreports.qt.io/browse/QTBUG-85279
$(package)_config_opts_arm_darwin += -device-option QMAKE_APPLE_DEVICE_ARCHS=arm64
-$(package)_config_opts_linux = -qt-xkbcommon-x11
-$(package)_config_opts_linux += -qt-xcb
+$(package)_config_opts_linux = -qt-xcb
$(package)_config_opts_linux += -no-xcb-xlib
$(package)_config_opts_linux += -no-feature-xlib
$(package)_config_opts_linux += -system-freetype
$(package)_config_opts_linux += -fontconfig
$(package)_config_opts_linux += -no-opengl
+$(package)_config_opts_linux += -no-feature-vulkan
$(package)_config_opts_linux += -dbus-runtime
$(package)_config_opts_arm_linux += -platform linux-g++ -xplatform bitcoin-linux-g++
$(package)_config_opts_i686_linux = -xplatform linux-g++-32
@@ -220,21 +217,16 @@ endef
# 8. Adjust a regex in toolchain.prf, to accommodate Guix's usage of
# CROSS_LIBRARY_PATH. See #15277.
define $(package)_preprocess_cmds
- patch -p1 -i $($(package)_patch_dir)/freetype_back_compat.patch && \
- patch -p1 -i $($(package)_patch_dir)/fix_powerpc_libpng.patch && \
patch -p1 -i $($(package)_patch_dir)/drop_lrelease_dependency.patch && \
patch -p1 -i $($(package)_patch_dir)/dont_hardcode_pwd.patch && \
patch -p1 -i $($(package)_patch_dir)/fix_qt_pkgconfig.patch && \
- patch -p1 -i $($(package)_patch_dir)/fix_configure_mac.patch && \
patch -p1 -i $($(package)_patch_dir)/fix_no_printer.patch && \
- patch -p1 -i $($(package)_patch_dir)/fix_rcc_determinism.patch && \
- patch -p1 -i $($(package)_patch_dir)/xkb-default.patch && \
patch -p1 -i $($(package)_patch_dir)/fix_android_qmake_conf.patch && \
patch -p1 -i $($(package)_patch_dir)/fix_android_jni_static.patch && \
- patch -p1 -i $($(package)_patch_dir)/fix_riscv64_arch.patch && \
patch -p1 -i $($(package)_patch_dir)/no-xlib.patch && \
- patch -p1 -i $($(package)_patch_dir)/fix_mingw_cross_compile.patch && \
patch -p1 -i $($(package)_patch_dir)/fix_qpainter_non_determinism.patch &&\
+ patch -p1 -i $($(package)_patch_dir)/no_sdk_version_check.patch && \
+ patch -p1 -i $($(package)_patch_dir)/fix_lib_paths.patch && \
sed -i.old "s|updateqm.commands = \$$$$\$$$$LRELEASE|updateqm.commands = $($(package)_extract_dir)/qttools/bin/lrelease|" qttranslations/translations/translations.pro && \
mkdir -p qtbase/mkspecs/macx-clang-linux &&\
cp -f qtbase/mkspecs/macx-clang/qplatformdefs.h qtbase/mkspecs/macx-clang-linux/ &&\
@@ -247,8 +239,8 @@ define $(package)_preprocess_cmds
sed -i.old "s|QMAKE_CFLAGS += |!host_build: QMAKE_CFLAGS = $($(package)_cflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \
sed -i.old "s|QMAKE_CXXFLAGS += |!host_build: QMAKE_CXXFLAGS = $($(package)_cxxflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \
sed -i.old "0,/^QMAKE_LFLAGS_/s|^QMAKE_LFLAGS_|!host_build: QMAKE_LFLAGS = $($(package)_ldflags)\n&|" qtbase/mkspecs/win32-g++/qmake.conf && \
- sed -i.old "s|QMAKE_CC = clang|QMAKE_CC = $($(package)_cc)|" qtbase/mkspecs/common/clang.conf && \
- sed -i.old "s|QMAKE_CXX = clang++|QMAKE_CXX = $($(package)_cxx)|" qtbase/mkspecs/common/clang.conf && \
+ sed -i.old "s|QMAKE_CC = \$$$$\$$$${CROSS_COMPILE}clang|QMAKE_CC = $($(package)_cc)|" qtbase/mkspecs/common/clang.conf && \
+ sed -i.old "s|QMAKE_CXX = \$$$$\$$$${CROSS_COMPILE}clang++|QMAKE_CXX = $($(package)_cxx)|" qtbase/mkspecs/common/clang.conf && \
sed -i.old "s/LIBRARY_PATH/(CROSS_)?\0/g" qtbase/mkspecs/features/toolchain.prf
endef
@@ -258,8 +250,6 @@ define $(package)_config_cmds
export PKG_CONFIG_PATH=$(host_prefix)/share/pkgconfig && \
cd qtbase && \
./configure $($(package)_config_opts) && \
- echo "host_build: QT_CONFIG ~= s/system-zlib/zlib" >> mkspecs/qconfig.pri && \
- echo "CONFIG += force_bootstrap" >> mkspecs/qconfig.pri && \
cd .. && \
$(MAKE) -C qtbase sub-src-clean && \
qtbase/bin/qmake -o qttranslations/Makefile qttranslations/qttranslations.pro && \
diff --git a/depends/packages/zlib.mk b/depends/packages/zlib.mk
deleted file mode 100644
index acb02020a8..0000000000
--- a/depends/packages/zlib.mk
+++ /dev/null
@@ -1,31 +0,0 @@
-package=zlib
-$(package)_version=1.2.11
-$(package)_download_path=https://www.zlib.net
-$(package)_file_name=$(package)-$($(package)_version).tar.gz
-$(package)_sha256_hash=c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1
-
-define $(package)_set_vars
-$(package)_config_opts= CC="$($(package)_cc)"
-$(package)_config_opts+=CFLAGS="$($(package)_cflags) $($(package)_cppflags) -fPIC"
-$(package)_config_opts+=RANLIB="$($(package)_ranlib)"
-$(package)_config_opts+=AR="$($(package)_ar)"
-$(package)_config_opts_darwin+=AR="$($(package)_libtool)"
-$(package)_config_opts_darwin+=ARFLAGS="-o"
-$(package)_config_opts_android+=CHOST=$(host)
-endef
-
-# zlib has its own custom configure script that takes in options like CC,
-# CFLAGS, RANLIB, AR, and ARFLAGS from the environment rather than from
-# command-line arguments.
-define $(package)_config_cmds
- env $($(package)_config_opts) ./configure --static --prefix=$(host_prefix)
-endef
-
-define $(package)_build_cmds
- $(MAKE) libz.a
-endef
-
-define $(package)_stage_cmds
- $(MAKE) DESTDIR=$($(package)_staging_dir) install
-endef
-
diff --git a/depends/patches/qt/drop_lrelease_dependency.patch b/depends/patches/qt/drop_lrelease_dependency.patch
index f6b2c9fc80..9b918af77c 100644
--- a/depends/patches/qt/drop_lrelease_dependency.patch
+++ b/depends/patches/qt/drop_lrelease_dependency.patch
@@ -14,7 +14,7 @@ diff --git a/qttranslations/translations/translations.pro b/qttranslations/trans
index 694544c..eff339d 100644
--- a/qttranslations/translations/translations.pro
+++ b/qttranslations/translations/translations.pro
-@@ -109,3 +109,2 @@ updateqm.commands = $$LRELEASE ${QMAKE_FILE_IN} -qm ${QMAKE_FILE_OUT}
+@@ -107,3 +107,2 @@ updateqm.commands = $$LRELEASE ${QMAKE_FILE_IN} -qm ${QMAKE_FILE_OUT}
silent:updateqm.commands = @echo lrelease ${QMAKE_FILE_IN} && $$updateqm.commands
-updateqm.depends = $$LRELEASE_EXE
updateqm.name = LRELEASE ${QMAKE_FILE_IN}
diff --git a/depends/patches/qt/fix_android_jni_static.patch b/depends/patches/qt/fix_android_jni_static.patch
index 2f6ff00f40..f891da6ddf 100644
--- a/depends/patches/qt/fix_android_jni_static.patch
+++ b/depends/patches/qt/fix_android_jni_static.patch
@@ -1,6 +1,6 @@
--- old/qtbase/src/plugins/platforms/android/androidjnimain.cpp
+++ new/qtbase/src/plugins/platforms/android/androidjnimain.cpp
-@@ -890,6 +890,14 @@
+@@ -897,6 +897,14 @@
__android_log_print(ANDROID_LOG_FATAL, "Qt", "registerNatives failed");
return -1;
}
diff --git a/depends/patches/qt/fix_android_qmake_conf.patch b/depends/patches/qt/fix_android_qmake_conf.patch
index 13bfff9776..3a8753fd1d 100644
--- a/depends/patches/qt/fix_android_qmake_conf.patch
+++ b/depends/patches/qt/fix_android_qmake_conf.patch
@@ -1,20 +1,10 @@
--- old/qtbase/mkspecs/android-clang/qmake.conf
+++ new/qtbase/mkspecs/android-clang/qmake.conf
-@@ -30,7 +30,7 @@
- QMAKE_CFLAGS += -target mips64el-none-linux-android
+@@ -47,7 +47,7 @@ ANDROID_STDCPP_PATH = $$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++_shared.so
+ ANDROID_USE_LLVM = true
- QMAKE_CFLAGS += -gcc-toolchain $$NDK_TOOLCHAIN_PATH
--QMAKE_LINK = $$QMAKE_CXX $$QMAKE_CFLAGS -Wl,--exclude-libs,libgcc.a
-+QMAKE_LINK = $$QMAKE_CXX $$QMAKE_CFLAGS -Wl,--exclude-libs,libgcc.a -nostdlib++
- QMAKE_CFLAGS += -DANDROID_HAS_WSTRING --sysroot=$$NDK_ROOT/sysroot \
- -isystem $$NDK_ROOT/sysroot/usr/include/$$NDK_TOOLS_PREFIX \
- -isystem $$NDK_ROOT/sources/cxx-stl/llvm-libc++/include \
-@@ -40,7 +40,7 @@
- ANDROID_SOURCES_CXX_STL_LIBDIR = $$NDK_ROOT/sources/cxx-stl/llvm-libc++/libs/$$ANDROID_TARGET_ARCH
-
- ANDROID_STDCPP_PATH = $$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++_shared.so
--ANDROID_CXX_STL_LIBS = -lc++
-+ANDROID_CXX_STL_LIBS = -lc++_shared
-
- QMAKE_ARM_CFLAGS_RELEASE = -Oz
- QMAKE_ARM_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -Oz
+ exists($$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++.so): \
+- ANDROID_CXX_STL_LIBS = -lc++
++ ANDROID_CXX_STL_LIBS = -lc++_shared
+ else: \
+ ANDROID_CXX_STL_LIBS = $$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++.so.$$replace(ANDROID_PLATFORM, "android-", "")
diff --git a/depends/patches/qt/fix_configure_mac.patch b/depends/patches/qt/fix_configure_mac.patch
deleted file mode 100644
index 0d7dd647de..0000000000
--- a/depends/patches/qt/fix_configure_mac.patch
+++ /dev/null
@@ -1,50 +0,0 @@
---- old/qtbase/mkspecs/features/mac/sdk.prf 2018-02-08 10:24:48.000000000 -0800
-+++ new/qtbase/mkspecs/features/mac/sdk.prf 2018-03-23 10:38:56.000000000 -0700
-@@ -8,21 +8,21 @@
- defineReplace(xcodeSDKInfo) {
- info = $$1
- equals(info, "Path"): \
-- info = --show-sdk-path
-+ infoarg = --show-sdk-path
- equals(info, "PlatformPath"): \
-- info = --show-sdk-platform-path
-+ infoarg = --show-sdk-platform-path
- equals(info, "SDKVersion"): \
-- info = --show-sdk-version
-+ infoarg = --show-sdk-version
- sdk = $$2
- isEmpty(sdk): \
- sdk = $$QMAKE_MAC_SDK
-
- isEmpty(QMAKE_MAC_SDK.$${sdk}.$${info}) {
-- QMAKE_MAC_SDK.$${sdk}.$${info} = $$system("/usr/bin/xcrun --sdk $$sdk $$info 2>/dev/null")
-+ QMAKE_MAC_SDK.$${sdk}.$${info} = $$system("/usr/bin/xcrun --sdk $$sdk $$infoarg 2>/dev/null")
- # --show-sdk-platform-path won't work for Command Line Tools; this is fine
- # only used by the XCTest backend to testlib
-- isEmpty(QMAKE_MAC_SDK.$${sdk}.$${info}):if(!isEmpty(QMAKE_XCODEBUILD_PATH)|!equals(info, "--show-sdk-platform-path")): \
-- error("Could not resolve SDK $$info for \'$$sdk\'")
-+ isEmpty(QMAKE_MAC_SDK.$${sdk}.$${info}):if(!isEmpty(QMAKE_XCODEBUILD_PATH)|!equals(infoarg, "--show-sdk-platform-path")): \
-+ error("Could not resolve SDK $$info for \'$$sdk\' using $$infoarg")
- cache(QMAKE_MAC_SDK.$${sdk}.$${info}, set stash, QMAKE_MAC_SDK.$${sdk}.$${info})
- }
-
---- old/qtbase/configure 2018-02-08 10:24:48.000000000 -0800
-+++ new/qtbase/configure 2018-03-23 05:42:29.000000000 -0700
-@@ -232,8 +232,13 @@
-
- sdk=$(getSingleQMakeVariable "QMAKE_MAC_SDK" "$1")
- if [ -z "$sdk" ]; then echo "QMAKE_MAC_SDK must be set when building on Mac" >&2; exit 1; fi
-- sysroot=$(/usr/bin/xcrun --sdk $sdk --show-sdk-path 2>/dev/null)
-- if [ -z "$sysroot" ]; then echo "Failed to resolve SDK path for '$sdk'" >&2; exit 1; fi
-+ sysroot=$(getSingleQMakeVariable "QMAKE_MAC_SDK_PATH" "$1")
-+
-+ echo "sysroot pre-configured as $sysroot";
-+ if [ -z "$sysroot" ]; then
-+ sysroot=$(/usr/bin/xcrun --sdk $sdk --show-sdk-path 2>/dev/null)
-+ if [ -z "$sysroot" ]; then echo "Failed to resolve SDK path for '$sdk'" >&2; exit 1; fi
-+ fi
-
- case "$sdk" in
- macosx*)
-
-
diff --git a/depends/patches/qt/fix_lib_paths.patch b/depends/patches/qt/fix_lib_paths.patch
new file mode 100644
index 0000000000..d1a15373f4
--- /dev/null
+++ b/depends/patches/qt/fix_lib_paths.patch
@@ -0,0 +1,193 @@
+--- old/qtbase/mkspecs/common/mac.conf
++++ new/qtbase/mkspecs/common/mac.conf
+@@ -14,7 +14,6 @@
+
+ QMAKE_RESOURCE = /Developer/Tools/Rez
+ QMAKE_EXTENSION_SHLIB = dylib
+-QMAKE_EXTENSIONS_AUX_SHLIB = tbd
+ QMAKE_LIBDIR =
+
+ # sdk.prf will prefix the proper SDK sysroot
+
+--- old/qtbase/mkspecs/features/qmake_use.prf
++++ new/qtbase/mkspecs/features/qmake_use.prf
+@@ -22,6 +22,8 @@
+ !defined(QMAKE_LIBS_$$nu, var): \
+ error("Library '$$lower($$replace(nu, _, -))' is not defined.")
+
++ QMAKE_LIBDIR += $$eval(QMAKE_LIBDIR_$$nu)
++
+ debug: \
+ LIBS$${suffix} += $$eval(QMAKE_LIBS_$${nu}_DEBUG) $$eval(QMAKE_LIBS_$$nu)
+ else: \
+
+--- old/qtbase/mkspecs/features/qt_configure.prf
++++ new/qtbase/mkspecs/features/qt_configure.prf
+@@ -526,98 +526,23 @@
+ return($$sysrootified)
+ }
+
+-# libs-var, libs, in-paths, out-paths-var
++# libs-var, libs, in-paths
+ defineTest(qtConfResolveLibs) {
+- ret = true
+- paths = $$3
+- out =
+- copy = false
+- for (l, 2) {
+- $$copy {
+- copy = false
+- out += $$l
+- } else: equals(l, "-s") {
+- # em++ flag to link libraries from emscripten-ports; passed on literally.
+- copy = true
+- out += $$l
+- } else: contains(l, "^-L.*") {
+- lp = $$replace(l, "^-L", )
+- gcc: lp = $$qtGccSysrootifiedPath($$lp)
+- !exists($$lp/.) {
+- qtLog("Library path $$val_escape(lp) is invalid.")
+- ret = false
+- } else {
+- paths += $$lp
+- }
+- } else: contains(l, "^-l.*") {
+- lib = $$replace(l, "^-l", )
+- lcan =
+- integrity:contains(lib, "^.*\\.a") {
+- # INTEGRITY compiler searches for exact filename
+- # if -l argument has .a suffix
+- lcan += $${lib}
+- } else: contains(lib, "^:.*") {
+- # Use exact filename when -l:filename syntax is used.
+- lib ~= s/^://
+- lcan += $${lib}
+- } else: unix {
+- # Under UNIX, we look for actual shared libraries, in addition
+- # to static ones.
+- shexts = $$QMAKE_EXTENSION_SHLIB $$QMAKE_EXTENSIONS_AUX_SHLIB
+- for (ext, shexts) {
+- lcan += $${QMAKE_PREFIX_SHLIB}$${lib}.$${ext}
+- }
+- lcan += \
+- $${QMAKE_PREFIX_STATICLIB}$${lib}.$${QMAKE_EXTENSION_STATICLIB}
+- } else {
+- # Under Windows, we look only for static libraries, as even for DLLs
+- # one actually links against a static import library.
+- mingw {
+- lcan += \
+- # MinGW supports UNIX-style library naming in addition to
+- # the MSVC style.
+- lib$${lib}.dll.a lib$${lib}.a \
+- # Fun fact: prefix-less libraries are also supported.
+- $${lib}.dll.a $${lib}.a
+- }
+- lcan += $${lib}.lib
+- }
+- l = $$qtConfFindInPathList($$lcan, $$paths $$EXTRA_LIBDIR $$QMAKE_DEFAULT_LIBDIRS)
+- isEmpty(l) {
+- qtLog("None of [$$val_escape(lcan)] found in [$$val_escape(paths)] and global paths.")
+- ret = false
+- } else {
+- out += $$l
+- }
+- } else {
+- out += $$l
+- }
+- }
+- $$1 = $$out
++ for (path, 3): \
++ pre_lflags += -L$$path
++ $$1 = $$pre_lflags $$2
+ export($$1)
+- !isEmpty(4) {
+- $$4 = $$paths
+- export($$4)
+- }
+- return($$ret)
+-}
+-
+-# source-var
+-defineTest(qtConfResolveAllLibs) {
+- ret = true
+- !qtConfResolveLibs($${1}.libs, $$eval($${1}.libs), , $${1}.libdirs): \
+- ret = false
+- for (b, $${1}.builds._KEYS_): \
+- !qtConfResolveLibs($${1}.builds.$${b}, $$eval($${1}.builds.$${b}), $$eval($${1}.libdirs), ): \
+- ret = false
+- return($$ret)
++ return(true)
+ }
+
+ # libs-var, in-paths, libs
+ defineTest(qtConfResolvePathLibs) {
+ ret = true
+- gcc: 2 = $$qtGccSysrootifiedPaths($$2)
+- for (libdir, 2) {
++ gcc: \
++ local_paths = $$qtGccSysrootifiedPaths($$2)
++ else: \
++ local_paths = $$2
++ for (libdir, local_paths) {
+ !exists($$libdir/.) {
+ qtLog("Library path $$val_escape(libdir) is invalid.")
+ ret = false
+@@ -667,8 +592,11 @@
+ # includes-var, in-paths, test-object-var
+ defineTest(qtConfResolvePathIncs) {
+ ret = true
+- gcc: 2 = $$qtGccSysrootifiedPaths($$2)
+- for (incdir, 2) {
++ gcc: \
++ local_paths = $$qtGccSysrootifiedPaths($$2)
++ else: \
++ local_paths = $$2
++ for (incdir, local_paths) {
+ !exists($$incdir/.) {
+ qtLog("Include path $$val_escape(incdir) is invalid.")
+ ret = false
+@@ -727,6 +655,7 @@
+ vars += $$eval(config.commandline.rev_assignments.$${iv})
+ defined(config.input.$${iv}, var) {
+ eval($${1}.builds.$${b} = $$eval(config.input.$${iv}))
++ export($${1}.builds.$${b})
+ $${1}.builds._KEYS_ *= $${b}
+ any = true
+ } else {
+@@ -741,11 +670,14 @@
+ export($${1}.builds._KEYS_)
+ # we also reset the generic libs, to avoid surprises.
+ $${1}.libs =
++ export($${1}.libs)
+ }
+
+ # direct libs. overwrites inline libs.
+- defined(config.input.$${input}.libs, var): \
++ defined(config.input.$${input}.libs, var) {
+ eval($${1}.libs = $$eval(config.input.$${input}.libs))
++ export($${1}.libs)
++ }
+
+ includes = $$eval(config.input.$${input}.incdir)
+
+@@ -754,6 +686,7 @@
+ !isEmpty(prefix) {
+ includes += $$prefix/include
+ $${1}.libs = -L$$prefix/lib $$eval($${1}.libs)
++ export($${1}.libs)
+ }
+
+ libdir = $$eval(config.input.$${input}.libdir)
+@@ -762,11 +695,9 @@
+ for (ld, libdir): \
+ libs += -L$$ld
+ $${1}.libs = $$libs $$eval($${1}.libs)
++ export($${1}.libs)
+ }
+
+- !qtConfResolveAllLibs($$1): \
+- return(false)
+-
+ !qtConfResolvePathIncs($${1}.includedir, $$includes, $$2): \
+ return(false)
+
diff --git a/depends/patches/qt/fix_mingw_cross_compile.patch b/depends/patches/qt/fix_mingw_cross_compile.patch
deleted file mode 100644
index 67f76f1d85..0000000000
--- a/depends/patches/qt/fix_mingw_cross_compile.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-commit 5a992a549adfe5a587bbcd6cd2b2cee47d236e27
-Author: fanquake <fanquake@gmail.com>
-Date: Fri Sep 4 08:13:44 2020 +0800
-
- Work around broken mingw cross-compilation
-
- See upstream issues:
- https://bugreports.qt.io/browse/QTBUG-63637
- https://bugreports.qt.io/browse/QTBUG-63659
- https://codereview.qt-project.org/q/8bebded9
-
- We should be able to drop this once we are building qt 5.10.1 or later.
-
- Added in #12971.
-
-diff --git a/qtbase/mkspecs/win32-g++/qmake.conf b/qtbase/mkspecs/win32-g++/qmake.conf
-index e071a0d1..ad229b10 100644
---- a/qtbase/mkspecs/win32-g++/qmake.conf
-+++ b/qtbase/mkspecs/win32-g++/qmake.conf
-@@ -87,3 +87,5 @@ QMAKE_NM = $${CROSS_COMPILE}nm -P
- include(../common/angle.conf)
-
- load(qt_config)
-+QMAKE_LINK_OBJECT_MAX = 10
-+QMAKE_LINK_OBJECT_SCRIPT = object_script
diff --git a/depends/patches/qt/fix_no_printer.patch b/depends/patches/qt/fix_no_printer.patch
index f868ca2577..1372356138 100644
--- a/depends/patches/qt/fix_no_printer.patch
+++ b/depends/patches/qt/fix_no_printer.patch
@@ -10,10 +10,10 @@
--- x/qtbase/src/plugins/plugins.pro
+++ y/qtbase/src/plugins/plugins.pro
-@@ -8,6 +8,3 @@ qtHaveModule(gui) {
- qtConfig(imageformatplugin): SUBDIRS *= imageformats
+@@ -9,6 +9,3 @@ qtHaveModule(gui) {
!android:qtConfig(library): SUBDIRS *= generic
}
+ qtHaveModule(widgets): SUBDIRS += styles
-
-!winrt:qtHaveModule(printsupport): \
- SUBDIRS += printsupport
diff --git a/depends/patches/qt/fix_powerpc_libpng.patch b/depends/patches/qt/fix_powerpc_libpng.patch
deleted file mode 100644
index d37b6c7776..0000000000
--- a/depends/patches/qt/fix_powerpc_libpng.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-commit 6f9feb773a43c5abfa3455da2e324180e789285b
-Author: fanquake <fanquake@gmail.com>
-Date: Tue Sep 15 21:44:31 2020 +0800
-
- Fix PowerPC build of libpng
-
- See https://bugreports.qt.io/browse/QTBUG-66388.
-
- Can be dropped when we are building qt 5.12.0 or later.
-
-diff --git a/qtbase/src/3rdparty/libpng/libpng.pro b/qtbase/src/3rdparty/libpng/libpng.pro
-index 577b61d8..a2f56669 100644
---- a/qtbase/src/3rdparty/libpng/libpng.pro
-+++ b/qtbase/src/3rdparty/libpng/libpng.pro
-@@ -10,7 +10,7 @@ MODULE_INCLUDEPATH = $$PWD
-
- load(qt_helper_lib)
-
--DEFINES += PNG_ARM_NEON_OPT=0
-+DEFINES += PNG_ARM_NEON_OPT=0 PNG_POWERPC_VSX_OPT=0
- SOURCES += \
- png.c \
- pngerror.c \
diff --git a/depends/patches/qt/fix_qpainter_non_determinism.patch b/depends/patches/qt/fix_qpainter_non_determinism.patch
index 3cfcc22f03..44c45187c5 100644
--- a/depends/patches/qt/fix_qpainter_non_determinism.patch
+++ b/depends/patches/qt/fix_qpainter_non_determinism.patch
@@ -22,7 +22,7 @@ diff --git a/qtbase/src/gui/painting/qpaintengine_raster.cpp b/qtbase/src/gui/pa
index 92ab6e8375..f018009e0b 100644
--- a/qtbase/src/gui/painting/qpaintengine_raster.cpp
+++ b/qtbase/src/gui/painting/qpaintengine_raster.cpp
-@@ -3971,22 +3971,23 @@ static const QSpan *qt_intersect_spans(const QClipData *clip, int *currentClip,
+@@ -4128,22 +4128,23 @@ static const QSpan *qt_intersect_spans(const QClipData *clip, int *currentClip,
const QSpan *clipEnd = clip->m_spans + clip->count;
while (available && spans < end ) {
@@ -51,7 +51,7 @@ index 92ab6e8375..f018009e0b 100644
int sx1 = spans->x;
int sx2 = sx1 + spans->len;
-@@ -4005,7 +4006,7 @@ static const QSpan *qt_intersect_spans(const QClipData *clip, int *currentClip,
+@@ -4162,7 +4163,7 @@ static const QSpan *qt_intersect_spans(const QClipData *clip, int *currentClip,
if (len) {
out->x = qMax(sx1, cx1);
out->len = qMin(sx2, cx2) - out->x;
diff --git a/depends/patches/qt/fix_qt_pkgconfig.patch b/depends/patches/qt/fix_qt_pkgconfig.patch
index 8c722ffb46..a5de2b4b9e 100644
--- a/depends/patches/qt/fix_qt_pkgconfig.patch
+++ b/depends/patches/qt/fix_qt_pkgconfig.patch
@@ -1,17 +1,17 @@
--- old/qtbase/mkspecs/features/qt_module.prf
+++ new/qtbase/mkspecs/features/qt_module.prf
-@@ -264,7 +264,7 @@
+@@ -269,7 +269,7 @@ load(qt_installs)
load(qt_targets)
# this builds on top of qt_common
--!internal_module:!lib_bundle:if(unix|mingw) {
+-!internal_module:if(unix|mingw) {
+if(unix|mingw):!if(darwin:debug_and_release:CONFIG(debug, debug|release)) {
CONFIG += create_pc
QMAKE_PKGCONFIG_DESTDIR = pkgconfig
host_build: \
-@@ -274,9 +274,9 @@
- QMAKE_PKGCONFIG_INCDIR = $$[QT_INSTALL_HEADERS/raw]
- QMAKE_PKGCONFIG_CFLAGS = -I${includedir}/$$MODULE_INCNAME
+@@ -284,9 +284,9 @@ load(qt_targets)
+ QMAKE_PKGCONFIG_CFLAGS = -D$$MODULE_DEFINE -I${includedir}/$$MODULE_INCNAME
+ }
QMAKE_PKGCONFIG_NAME = $$replace(TARGET, ^Qt, "Qt$$QT_MAJOR_VERSION ")
- QMAKE_PKGCONFIG_FILE = $$replace(TARGET, ^Qt, Qt$$QT_MAJOR_VERSION)
+ QMAKE_PKGCONFIG_FILE = $$replace(TARGET, ^Qt, Qt$$QT_MAJOR_VERSION)$$qtPlatformTargetSuffix()
@@ -20,4 +20,4 @@
+ QMAKE_PKGCONFIG_REQUIRES += $$replace(QT.$${i}.name, ^Qt, Qt$$section(QT.$${i}.VERSION, ., 0, 0))$$qtPlatformTargetSuffix()
isEmpty(QMAKE_PKGCONFIG_DESCRIPTION): \
QMAKE_PKGCONFIG_DESCRIPTION = $$replace(TARGET, ^Qt, "Qt ") module
- pclib_replace.match = $$lib_replace.match
+ !isEmpty(lib_replace0.match) {
diff --git a/depends/patches/qt/fix_rcc_determinism.patch b/depends/patches/qt/fix_rcc_determinism.patch
deleted file mode 100644
index c1b07fe23a..0000000000
--- a/depends/patches/qt/fix_rcc_determinism.patch
+++ /dev/null
@@ -1,15 +0,0 @@
---- old/qtbase/src/tools/rcc/rcc.cpp
-+++ new/qtbase/src/tools/rcc/rcc.cpp
-@@ -207,7 +207,11 @@ void RCCFileInfo::writeDataInfo(RCCResourceLibrary &lib)
- if (lib.formatVersion() >= 2) {
- // last modified time stamp
- const QDateTime lastModified = m_fileInfo.lastModified();
-- lib.writeNumber8(quint64(lastModified.isValid() ? lastModified.toMSecsSinceEpoch() : 0));
-+ quint64 lastmod = quint64(lastModified.isValid() ? lastModified.toMSecsSinceEpoch() : 0);
-+ static const quint64 sourceDate = 1000 * qgetenv("QT_RCC_SOURCE_DATE_OVERRIDE").toULongLong();
-+ if (sourceDate != 0)
-+ lastmod = sourceDate;
-+ lib.writeNumber8(lastmod);
- if (text || pass1)
- lib.writeChar('\n');
- }
diff --git a/depends/patches/qt/fix_riscv64_arch.patch b/depends/patches/qt/fix_riscv64_arch.patch
deleted file mode 100644
index e7f29f01f9..0000000000
--- a/depends/patches/qt/fix_riscv64_arch.patch
+++ /dev/null
@@ -1,14 +0,0 @@
-diff --git a/qtbase/src/3rdparty/double-conversion/include/double-conversion/utils.h b/qtbase/src/3rdparty/double-conversion/include/double-conversion/utils.h
-index 20bfd36..93729fa 100644
---- a/qtbase/src/3rdparty/double-conversion/include/double-conversion/utils.h
-+++ b/qtbase/src/3rdparty/double-conversion/include/double-conversion/utils.h
-@@ -65,7 +65,8 @@
- defined(__sparc__) || defined(__sparc) || defined(__s390__) || \
- defined(__SH4__) || defined(__alpha__) || \
- defined(_MIPS_ARCH_MIPS32R2) || \
-- defined(__AARCH64EL__)
-+ defined(__AARCH64EL__) || defined(__aarch64__) || \
-+ defined(__riscv)
- #define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
- #elif defined(_M_IX86) || defined(__i386__) || defined(__i386)
- #if defined(_WIN32)
diff --git a/depends/patches/qt/freetype_back_compat.patch b/depends/patches/qt/freetype_back_compat.patch
deleted file mode 100644
index 1ca55f1ce3..0000000000
--- a/depends/patches/qt/freetype_back_compat.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-commit 14bc77db61bf9d56f9b6c8b84aa02573605c19c6
-Author: fanquake <fanquake@gmail.com>
-Date: Tue Aug 18 15:15:08 2020 +0800
-
- Fix backwards compatibility with older Freetype versions at runtime
-
- A few years ago, libfreetype introduced FT_Get_Font_Format() as an alias
- for FT_Get_X11_Font_Format(), but FT_Get_X11_Font_Format() was kept for abi
- backwards-compatibility.
-
- Qt 5.9 introduced a call to FT_Get_Font_Format(). Replace it with FT_Get_X11_Font_Format()
- in order to remain compatible with older freetype, which is still used by e.g. Ubuntu Trusty.
-
- See #14348.
-
-diff --git a/qtbase/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp b/qtbase/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
-index 3f543755..8ecc1c8c 100644
---- a/qtbase/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
-+++ b/qtbase/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
-@@ -898,7 +898,7 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format,
- }
- }
- #if defined(FT_FONT_FORMATS_H)
-- const char *fmt = FT_Get_Font_Format(face);
-+ const char *fmt = FT_Get_X11_Font_Format(face);
- if (fmt && qstrncmp(fmt, "CFF", 4) == 0) {
- FT_Bool no_stem_darkening = true;
- FT_Error err = FT_Property_Get(qt_getFreetype(), "cff", "no-stem-darkening", &no_stem_darkening);
diff --git a/depends/patches/qt/no-xlib.patch b/depends/patches/qt/no-xlib.patch
index fe82c2c73c..f4a6f09ee4 100644
--- a/depends/patches/qt/no-xlib.patch
+++ b/depends/patches/qt/no-xlib.patch
@@ -22,15 +22,15 @@ index 7c62c2e2b3..c05c6c0a07 100644
#include <xcb/xfixes.h>
#include <xcb/xcb_image.h>
-@@ -384,6 +386,7 @@ void QXcbCursor::changeCursor(QCursor *cursor, QWindow *widget)
- w->setCursor(c, isBitmapCursor);
+@@ -391,6 +393,7 @@ void QXcbCursor::changeCursor(QCursor *cursor, QWindow *window)
+ xcb_flush(xcb_connection());
}
+#if QT_CONFIG(xcb_xlib) && QT_CONFIG(library)
static int cursorIdForShape(int cshape)
{
int cursorId = 0;
-@@ -437,6 +440,7 @@ static int cursorIdForShape(int cshape)
+@@ -444,6 +447,7 @@ static int cursorIdForShape(int cshape)
}
return cursorId;
}
@@ -38,7 +38,7 @@ index 7c62c2e2b3..c05c6c0a07 100644
xcb_cursor_t QXcbCursor::createNonStandardCursor(int cshape)
{
-@@ -558,7 +562,9 @@ static xcb_cursor_t loadCursor(void *dpy, int cshape)
+@@ -556,7 +560,9 @@ static xcb_cursor_t loadCursor(void *dpy, int cshape)
xcb_cursor_t QXcbCursor::createFontCursor(int cshape)
{
xcb_connection_t *conn = xcb_connection();
@@ -48,22 +48,23 @@ index 7c62c2e2b3..c05c6c0a07 100644
xcb_cursor_t cursor = XCB_NONE;
// Try Xcursor first
-@@ -589,6 +595,7 @@ xcb_cursor_t QXcbCursor::createFontCursor(int cshape)
+@@ -585,7 +591,7 @@ xcb_cursor_t QXcbCursor::createFontCursor(int cshape)
+
// Non-standard X11 cursors are created from bitmaps
cursor = createNonStandardCursor(cshape);
-
+-
+#if QT_CONFIG(xcb_xlib) && QT_CONFIG(library)
// Create a glpyh cursor if everything else failed
if (!cursor && cursorId) {
cursor = xcb_generate_id(conn);
-@@ -596,6 +603,7 @@ xcb_cursor_t QXcbCursor::createFontCursor(int cshape)
+@@ -593,6 +599,7 @@ xcb_cursor_t QXcbCursor::createFontCursor(int cshape)
cursorId, cursorId + 1,
0xFFFF, 0xFFFF, 0xFFFF, 0, 0, 0);
}
+#endif
if (cursor && cshape >= 0 && cshape < Qt::LastCursor && connection()->hasXFixes()) {
- const char *name = cursorNames[cshape];
+ const char *name = cursorNames[cshape].front();
--
2.22.0
diff --git a/depends/patches/qt/no_sdk_version_check.patch b/depends/patches/qt/no_sdk_version_check.patch
new file mode 100644
index 0000000000..b16635b572
--- /dev/null
+++ b/depends/patches/qt/no_sdk_version_check.patch
@@ -0,0 +1,20 @@
+commit f5eb142cd04be2bc4ca610ed3b5b7e8ce3520ee3
+Author: fanquake <fanquake@gmail.com>
+Date: Tue Jan 5 16:08:49 2021 +0800
+
+ Don't invoke macOS SDK version checking
+
+ This tries to use xcrun which is not available when cross-compiling.
+
+diff --git a/qtbase/mkspecs/features/mac/default_post.prf b/qtbase/mkspecs/features/mac/default_post.prf
+index 92a9112bca6..447e186eb26 100644
+--- a/qtbase/mkspecs/features/mac/default_post.prf
++++ b/qtbase/mkspecs/features/mac/default_post.prf
+@@ -8,7 +8,6 @@ contains(TEMPLATE, .*app) {
+ !macx-xcode:if(isEmpty(BUILDS)|build_pass) {
+ # Detect changes to the platform SDK
+ QMAKE_EXTRA_VARIABLES += QMAKE_MAC_SDK QMAKE_MAC_SDK_VERSION QMAKE_XCODE_DEVELOPER_PATH
+- QMAKE_EXTRA_INCLUDES += $$shell_quote($$PWD/sdk.mk)
+ }
+
+ # Detect incompatible SDK versions
diff --git a/depends/patches/qt/xkb-default.patch b/depends/patches/qt/xkb-default.patch
deleted file mode 100644
index 165abf3e2e..0000000000
--- a/depends/patches/qt/xkb-default.patch
+++ /dev/null
@@ -1,26 +0,0 @@
---- old/qtbase/src/gui/configure.pri 2018-06-06 17:28:10.000000000 -0400
-+++ new/qtbase/src/gui/configure.pri 2018-08-17 18:43:01.589384567 -0400
-@@ -43,18 +43,11 @@
- }
-
- defineTest(qtConfTest_xkbConfigRoot) {
-- qtConfTest_getPkgConfigVariable($${1}): return(true)
--
-- for (dir, $$list("/usr/share/X11/xkb", "/usr/local/share/X11/xkb")) {
-- exists($$dir) {
-- $${1}.value = $$dir
-- export($${1}.value)
-- $${1}.cache += value
-- export($${1}.cache)
-- return(true)
-- }
-- }
-- return(false)
-+ $${1}.value = "/usr/share/X11/xkb"
-+ export($${1}.value)
-+ $${1}.cache += value
-+ export($${1}.cache)
-+ return(true)
- }
-
- defineTest(qtConfTest_qpaDefaultPlatform) {
diff --git a/doc/developer-notes.md b/doc/developer-notes.md
index 8f2d7af089..0a78cdff20 100644
--- a/doc/developer-notes.md
+++ b/doc/developer-notes.md
@@ -595,11 +595,6 @@ Common misconceptions are clarified in those sections:
- *Rationale*: This avoids memory and resource leaks, and ensures exception safety.
-- Use `MakeUnique()` to construct objects owned by `unique_ptr`s.
-
- - *Rationale*: `MakeUnique` is concise and ensures exception safety in complex expressions.
- `MakeUnique` is a temporary project local implementation of `std::make_unique` (C++14).
-
C++ data structures
--------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index 56f561a172..8f37e055ff 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -240,7 +240,6 @@ BITCOIN_CORE_H = \
util/golombrice.h \
util/hasher.h \
util/macros.h \
- util/memory.h \
util/message.h \
util/moneystr.h \
util/rbf.h \
@@ -253,6 +252,7 @@ BITCOIN_CORE_H = \
util/system.h \
util/threadnames.h \
util/time.h \
+ util/tokenpipe.h \
util/trace.h \
util/translation.h \
util/ui_change_type.h \
@@ -584,6 +584,7 @@ libbitcoin_util_a_SOURCES = \
util/strencodings.cpp \
util/string.cpp \
util/time.cpp \
+ util/tokenpipe.cpp \
$(BITCOIN_CORE_H)
if USE_LIBEVENT
diff --git a/src/bench/coin_selection.cpp b/src/bench/coin_selection.cpp
index 3abfbfd784..376e70ffba 100644
--- a/src/bench/coin_selection.cpp
+++ b/src/bench/coin_selection.cpp
@@ -17,7 +17,7 @@ static void addCoin(const CAmount& nValue, const CWallet& wallet, std::vector<st
tx.nLockTime = nextLockTime++; // so all transactions get different hashes
tx.vout.resize(1);
tx.vout[0].nValue = nValue;
- wtxs.push_back(MakeUnique<CWalletTx>(&wallet, MakeTransactionRef(std::move(tx))));
+ wtxs.push_back(std::make_unique<CWalletTx>(&wallet, MakeTransactionRef(std::move(tx))));
}
// Simple benchmark for wallet coin selection. Note that it maybe be necessary
@@ -73,7 +73,7 @@ static void add_coin(const CAmount& nValue, int nInput, std::vector<OutputGroup>
CMutableTransaction tx;
tx.vout.resize(nInput + 1);
tx.vout[nInput].nValue = nValue;
- std::unique_ptr<CWalletTx> wtx = MakeUnique<CWalletTx>(&testWallet, MakeTransactionRef(std::move(tx)));
+ std::unique_ptr<CWalletTx> wtx = std::make_unique<CWalletTx>(&testWallet, MakeTransactionRef(std::move(tx)));
set.emplace_back();
set.back().Insert(COutput(wtx.get(), nInput, 0, true, true, true).GetInputCoin(), 0, true, 0, 0, false);
wtxn.emplace_back(std::move(wtx));
diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp
index b7bcb534ef..32f06aec2c 100644
--- a/src/bitcoind.cpp
+++ b/src/bitcoind.cpp
@@ -20,6 +20,7 @@
#include <util/strencodings.h>
#include <util/system.h>
#include <util/threadnames.h>
+#include <util/tokenpipe.h>
#include <util/translation.h>
#include <util/url.h>
@@ -28,6 +29,79 @@
const std::function<std::string(const char*)> G_TRANSLATION_FUN = nullptr;
UrlDecodeFn* const URL_DECODE = urlDecode;
+#if HAVE_DECL_FORK
+
+/** Custom implementation of daemon(). This implements the same order of operations as glibc.
+ * Opens a pipe to the child process to be able to wait for an event to occur.
+ *
+ * @returns 0 if successful, and in child process.
+ * >0 if successful, and in parent process.
+ * -1 in case of error (in parent process).
+ *
+ * In case of success, endpoint will be one end of a pipe from the child to parent process,
+ * which can be used with TokenWrite (in the child) or TokenRead (in the parent).
+ */
+int fork_daemon(bool nochdir, bool noclose, TokenPipeEnd& endpoint)
+{
+ // communication pipe with child process
+ std::optional<TokenPipe> umbilical = TokenPipe::Make();
+ if (!umbilical) {
+ return -1; // pipe or pipe2 failed.
+ }
+
+ int pid = fork();
+ if (pid < 0) {
+ return -1; // fork failed.
+ }
+ if (pid != 0) {
+ // Parent process gets read end, closes write end.
+ endpoint = umbilical->TakeReadEnd();
+ umbilical->TakeWriteEnd().Close();
+
+ int status = endpoint.TokenRead();
+ if (status != 0) { // Something went wrong while setting up child process.
+ endpoint.Close();
+ return -1;
+ }
+
+ return pid;
+ }
+ // Child process gets write end, closes read end.
+ endpoint = umbilical->TakeWriteEnd();
+ umbilical->TakeReadEnd().Close();
+
+#if HAVE_DECL_SETSID
+ if (setsid() < 0) {
+ exit(1); // setsid failed.
+ }
+#endif
+
+ if (!nochdir) {
+ if (chdir("/") != 0) {
+ exit(1); // chdir failed.
+ }
+ }
+ if (!noclose) {
+ // Open /dev/null, and clone it into STDIN, STDOUT and STDERR to detach
+ // from terminal.
+ int fd = open("/dev/null", O_RDWR);
+ if (fd >= 0) {
+ bool err = dup2(fd, STDIN_FILENO) < 0 || dup2(fd, STDOUT_FILENO) < 0 || dup2(fd, STDERR_FILENO) < 0;
+ // Don't close if fd<=2 to try to handle the case where the program was invoked without any file descriptors open.
+ if (fd > 2) close(fd);
+ if (err) {
+ exit(1); // dup2 failed.
+ }
+ } else {
+ exit(1); // open /dev/null failed.
+ }
+ }
+ endpoint.TokenWrite(0); // Success
+ return 0;
+}
+
+#endif
+
static bool AppInit(int argc, char* argv[])
{
NodeContext node;
@@ -59,6 +133,14 @@ static bool AppInit(int argc, char* argv[])
return true;
}
+#if HAVE_DECL_FORK
+ // Communication with parent after daemonizing. This is used for signalling in the following ways:
+ // - a boolean token is sent when the initialization process (all the Init* functions) have finished to indicate
+ // that the parent process can quit, and whether it was successful/unsuccessful.
+ // - an unexpected shutdown of the child process creates an unexpected end of stream at the parent
+ // end, which is interpreted as failure to start.
+ TokenPipeEnd daemon_ep;
+#endif
util::Ref context{node};
try
{
@@ -105,24 +187,34 @@ static bool AppInit(int argc, char* argv[])
// InitError will have been called with detailed error, which ends up on console
return false;
}
- if (args.GetBoolArg("-daemon", false)) {
-#if HAVE_DECL_DAEMON
-#if defined(MAC_OSX)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
+ if (args.GetBoolArg("-daemon", DEFAULT_DAEMON) || args.GetBoolArg("-daemonwait", DEFAULT_DAEMONWAIT)) {
+#if HAVE_DECL_FORK
tfm::format(std::cout, PACKAGE_NAME " starting\n");
// Daemonize
- if (daemon(1, 0)) { // don't chdir (1), do close FDs (0)
- return InitError(Untranslated(strprintf("daemon() failed: %s\n", strerror(errno))));
+ switch (fork_daemon(1, 0, daemon_ep)) { // don't chdir (1), do close FDs (0)
+ case 0: // Child: continue.
+ // If -daemonwait is not enabled, immediately send a success token the parent.
+ if (!args.GetBoolArg("-daemonwait", DEFAULT_DAEMONWAIT)) {
+ daemon_ep.TokenWrite(1);
+ daemon_ep.Close();
+ }
+ break;
+ case -1: // Error happened.
+ return InitError(Untranslated(strprintf("fork_daemon() failed: %s\n", strerror(errno))));
+ default: { // Parent: wait and exit.
+ int token = daemon_ep.TokenRead();
+ if (token) { // Success
+ exit(EXIT_SUCCESS);
+ } else { // fRet = false or token read error (premature exit).
+ tfm::format(std::cerr, "Error during initializaton - check debug.log for details\n");
+ exit(EXIT_FAILURE);
+ }
+ }
}
-#if defined(MAC_OSX)
-#pragma GCC diagnostic pop
-#endif
#else
return InitError(Untranslated("-daemon is not supported on this operating system\n"));
-#endif // HAVE_DECL_DAEMON
+#endif // HAVE_DECL_FORK
}
// Lock data directory after daemonization
if (!AppInitLockDataDirectory())
@@ -138,6 +230,13 @@ static bool AppInit(int argc, char* argv[])
PrintExceptionContinue(nullptr, "AppInit()");
}
+#if HAVE_DECL_FORK
+ if (daemon_ep.IsOpen()) {
+ // Signal initialization status to parent, then close pipe.
+ daemon_ep.TokenWrite(fRet);
+ daemon_ep.Close();
+ }
+#endif
if (fRet) {
WaitForShutdown();
}
diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp
index 2c517b58f8..1631176477 100644
--- a/src/chainparamsbase.cpp
+++ b/src/chainparamsbase.cpp
@@ -7,7 +7,6 @@
#include <tinyformat.h>
#include <util/system.h>
-#include <util/memory.h>
#include <assert.h>
@@ -44,13 +43,13 @@ const CBaseChainParams& BaseParams()
std::unique_ptr<CBaseChainParams> CreateBaseChainParams(const std::string& chain)
{
if (chain == CBaseChainParams::MAIN) {
- return MakeUnique<CBaseChainParams>("", 8332, 8334);
+ return std::make_unique<CBaseChainParams>("", 8332, 8334);
} else if (chain == CBaseChainParams::TESTNET) {
- return MakeUnique<CBaseChainParams>("testnet3", 18332, 18334);
+ return std::make_unique<CBaseChainParams>("testnet3", 18332, 18334);
} else if (chain == CBaseChainParams::SIGNET) {
- return MakeUnique<CBaseChainParams>("signet", 38332, 38334);
+ return std::make_unique<CBaseChainParams>("signet", 38332, 38334);
} else if (chain == CBaseChainParams::REGTEST) {
- return MakeUnique<CBaseChainParams>("regtest", 18443, 18445);
+ return std::make_unique<CBaseChainParams>("regtest", 18443, 18445);
}
throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain));
}
diff --git a/src/httprpc.cpp b/src/httprpc.cpp
index cb8b220895..867ddb090e 100644
--- a/src/httprpc.cpp
+++ b/src/httprpc.cpp
@@ -301,7 +301,7 @@ bool StartHTTPRPC(const util::Ref& context)
}
struct event_base* eventBase = EventBase();
assert(eventBase);
- httpRPCTimerInterface = MakeUnique<HTTPRPCTimerInterface>(eventBase);
+ httpRPCTimerInterface = std::make_unique<HTTPRPCTimerInterface>(eventBase);
RPCSetTimerInterface(httpRPCTimerInterface.get());
return true;
}
diff --git a/src/index/blockfilterindex.cpp b/src/index/blockfilterindex.cpp
index 4f61bbeabd..32271fb7ab 100644
--- a/src/index/blockfilterindex.cpp
+++ b/src/index/blockfilterindex.cpp
@@ -102,8 +102,8 @@ BlockFilterIndex::BlockFilterIndex(BlockFilterType filter_type,
fs::create_directories(path);
m_name = filter_name + " block filter index";
- m_db = MakeUnique<BaseIndex::DB>(path / "db", n_cache_size, f_memory, f_wipe);
- m_filter_fileseq = MakeUnique<FlatFileSeq>(std::move(path), "fltr", FLTR_FILE_CHUNK_SIZE);
+ m_db = std::make_unique<BaseIndex::DB>(path / "db", n_cache_size, f_memory, f_wipe);
+ m_filter_fileseq = std::make_unique<FlatFileSeq>(std::move(path), "fltr", FLTR_FILE_CHUNK_SIZE);
}
bool BlockFilterIndex::Init()
diff --git a/src/index/txindex.cpp b/src/index/txindex.cpp
index 6398b7edc8..f41985c344 100644
--- a/src/index/txindex.cpp
+++ b/src/index/txindex.cpp
@@ -192,7 +192,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<TxIndex::DB>(n_cache_size, f_memory, f_wipe))
+ : m_db(std::make_unique<TxIndex::DB>(n_cache_size, f_memory, f_wipe))
{}
TxIndex::~TxIndex() {}
diff --git a/src/init.cpp b/src/init.cpp
index 8aa80eacca..b91a94bc25 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -580,8 +580,9 @@ void SetupServerArgs(NodeContext& node)
argsman.AddArg("-rpcworkqueue=<n>", strprintf("Set the depth of the work queue to service RPC calls (default: %d)", DEFAULT_HTTP_WORKQUEUE), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::RPC);
argsman.AddArg("-server", "Accept command line and JSON-RPC commands", ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
-#if HAVE_DECL_DAEMON
- argsman.AddArg("-daemon", "Run in the background as a daemon and accept commands", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
+#if HAVE_DECL_FORK
+ argsman.AddArg("-daemon", strprintf("Run in the background as a daemon and accept commands (default: %d)", DEFAULT_DAEMON), ArgsManager::ALLOW_BOOL, OptionsCategory::OPTIONS);
+ argsman.AddArg("-daemonwait", strprintf("Wait for initialization to be finished before exiting. This implies -daemon (default: %d)", DEFAULT_DAEMONWAIT), ArgsManager::ALLOW_BOOL, OptionsCategory::OPTIONS);
#else
hidden_args.emplace_back("-daemon");
#endif
@@ -1349,7 +1350,7 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA
}
assert(!node.scheduler);
- node.scheduler = MakeUnique<CScheduler>();
+ node.scheduler = std::make_unique<CScheduler>();
// Start the lightweight task scheduler thread
node.scheduler->m_service_thread = std::thread([&] { TraceThread("scheduler", [&] { node.scheduler->serviceQueue(); }); });
@@ -1401,9 +1402,9 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA
const bool ignores_incoming_txs{args.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY)};
assert(!node.banman);
- node.banman = MakeUnique<BanMan>(GetDataDir() / "banlist.dat", &uiInterface, args.GetArg("-bantime", DEFAULT_MISBEHAVING_BANTIME));
+ node.banman = std::make_unique<BanMan>(GetDataDir() / "banlist.dat", &uiInterface, args.GetArg("-bantime", DEFAULT_MISBEHAVING_BANTIME));
assert(!node.connman);
- node.connman = MakeUnique<CConnman>(GetRand(std::numeric_limits<uint64_t>::max()), GetRand(std::numeric_limits<uint64_t>::max()), args.GetBoolArg("-networkactive", true));
+ node.connman = std::make_unique<CConnman>(GetRand(std::numeric_limits<uint64_t>::max()), GetRand(std::numeric_limits<uint64_t>::max()), args.GetBoolArg("-networkactive", true));
assert(!node.fee_estimator);
// Don't initialize fee estimation with old data if we don't relay transactions,
@@ -1799,7 +1800,7 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA
// ********************************************************* Step 8: start indexers
if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) {
- g_txindex = MakeUnique<TxIndex>(nTxIndexCache, false, fReindex);
+ g_txindex = std::make_unique<TxIndex>(nTxIndexCache, false, fReindex);
g_txindex->Start();
}
diff --git a/src/init.h b/src/init.h
index c04d966d06..34bca09dd1 100644
--- a/src/init.h
+++ b/src/init.h
@@ -9,6 +9,11 @@
#include <memory>
#include <string>
+//! Default value for -daemon option
+static constexpr bool DEFAULT_DAEMON = false;
+//! Default value for -daemonwait option
+static constexpr bool DEFAULT_DAEMONWAIT = false;
+
class ArgsManager;
struct NodeContext;
namespace interfaces {
diff --git a/src/interfaces/chain.h b/src/interfaces/chain.h
index 1a49518d69..ebc5466173 100644
--- a/src/interfaces/chain.h
+++ b/src/interfaces/chain.h
@@ -159,6 +159,9 @@ public:
//! Check if transaction is RBF opt in.
virtual RBFTransactionState isRBFOptIn(const CTransaction& tx) = 0;
+ //! Check if transaction is in mempool.
+ virtual bool isInMempool(const uint256& txid) = 0;
+
//! Check if transaction has descendants in mempool.
virtual bool hasDescendantsInMempool(const uint256& txid) = 0;
diff --git a/src/interfaces/handler.cpp b/src/interfaces/handler.cpp
index 4134a4527f..c6bbbed445 100644
--- a/src/interfaces/handler.cpp
+++ b/src/interfaces/handler.cpp
@@ -4,7 +4,6 @@
#include <interfaces/handler.h>
-#include <util/memory.h>
#include <boost/signals2/connection.hpp>
#include <utility>
@@ -35,12 +34,12 @@ public:
std::unique_ptr<Handler> MakeHandler(boost::signals2::connection connection)
{
- return MakeUnique<HandlerImpl>(std::move(connection));
+ return std::make_unique<HandlerImpl>(std::move(connection));
}
std::unique_ptr<Handler> MakeHandler(std::function<void()> cleanup)
{
- return MakeUnique<CleanupHandler>(std::move(cleanup));
+ return std::make_unique<CleanupHandler>(std::move(cleanup));
}
} // namespace interfaces
diff --git a/src/miner.cpp b/src/miner.cpp
index 076d43c951..fbaef0f224 100644
--- a/src/miner.cpp
+++ b/src/miner.cpp
@@ -39,13 +39,13 @@ int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParam
return nNewTime - nOldTime;
}
-void RegenerateCommitments(CBlock& block)
+void RegenerateCommitments(CBlock& block, BlockManager& blockman)
{
CMutableTransaction tx{*block.vtx.at(0)};
tx.vout.erase(tx.vout.begin() + GetWitnessCommitmentIndex(block));
block.vtx.at(0) = MakeTransactionRef(tx);
- GenerateCoinbaseCommitment(block, WITH_LOCK(cs_main, return g_chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock)), Params().GetConsensus());
+ GenerateCoinbaseCommitment(block, WITH_LOCK(::cs_main, assert(std::addressof(g_chainman.m_blockman) == std::addressof(blockman)); return blockman.LookupBlockIndex(block.hashPrevBlock)), Params().GetConsensus());
block.hashMerkleRoot = BlockMerkleRoot(block);
}
@@ -99,7 +99,7 @@ void BlockAssembler::resetBlock()
Optional<int64_t> BlockAssembler::m_last_block_num_txs{nullopt};
Optional<int64_t> BlockAssembler::m_last_block_weight{nullopt};
-std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn)
+std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(CChainState& chainstate, const CScript& scriptPubKeyIn)
{
int64_t nTimeStart = GetTimeMicros();
@@ -117,7 +117,8 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
pblocktemplate->vTxSigOpsCost.push_back(-1); // updated at end
LOCK2(cs_main, m_mempool.cs);
- CBlockIndex* pindexPrev = ::ChainActive().Tip();
+ assert(std::addressof(*::ChainActive().Tip()) == std::addressof(*chainstate.m_chain.Tip()));
+ CBlockIndex* pindexPrev = chainstate.m_chain.Tip();
assert(pindexPrev != nullptr);
nHeight = pindexPrev->nHeight + 1;
@@ -176,7 +177,8 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
pblocktemplate->vTxSigOpsCost[0] = WITNESS_SCALE_FACTOR * GetLegacySigOpCount(*pblock->vtx[0]);
BlockValidationState state;
- if (!TestBlockValidity(state, chainparams, ::ChainstateActive(), *pblock, pindexPrev, false, false)) {
+ assert(std::addressof(::ChainstateActive()) == std::addressof(chainstate));
+ if (!TestBlockValidity(state, chainparams, chainstate, *pblock, pindexPrev, false, false)) {
throw std::runtime_error(strprintf("%s: TestBlockValidity failed: %s", __func__, state.ToString()));
}
int64_t nTime2 = GetTimeMicros();
diff --git a/src/miner.h b/src/miner.h
index 9a2b7063f4..a67fec6dd8 100644
--- a/src/miner.h
+++ b/src/miner.h
@@ -158,7 +158,7 @@ public:
explicit BlockAssembler(const CTxMemPool& mempool, const CChainParams& params, const Options& options);
/** Construct a new block template with coinbase to scriptPubKeyIn */
- std::unique_ptr<CBlockTemplate> CreateNewBlock(const CScript& scriptPubKeyIn);
+ std::unique_ptr<CBlockTemplate> CreateNewBlock(CChainState& chainstate, const CScript& scriptPubKeyIn);
static Optional<int64_t> m_last_block_num_txs;
static Optional<int64_t> m_last_block_weight;
@@ -202,6 +202,6 @@ void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned
int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev);
/** Update an old GenerateCoinbaseCommitment from CreateNewBlock after the block txs have changed */
-void RegenerateCommitments(CBlock& block);
+void RegenerateCommitments(CBlock& block, BlockManager& blockman);
#endif // BITCOIN_MINER_H
diff --git a/src/net.cpp b/src/net.cpp
index cf7d3e50ba..1e4a6a9aa7 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -2466,11 +2466,11 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
if (semOutbound == nullptr) {
// initialize semaphore
- semOutbound = MakeUnique<CSemaphore>(std::min(m_max_outbound, nMaxConnections));
+ semOutbound = std::make_unique<CSemaphore>(std::min(m_max_outbound, nMaxConnections));
}
if (semAddnode == nullptr) {
// initialize semaphore
- semAddnode = MakeUnique<CSemaphore>(nMaxAddnode);
+ semAddnode = std::make_unique<CSemaphore>(nMaxAddnode);
}
//
@@ -2906,11 +2906,11 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, SOCKET hSocketIn, const
hSocket = hSocketIn;
addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;
if (conn_type_in != ConnectionType::BLOCK_RELAY) {
- m_tx_relay = MakeUnique<TxRelay>();
+ m_tx_relay = std::make_unique<TxRelay>();
}
if (RelayAddrsWithConn()) {
- m_addr_known = MakeUnique<CRollingBloomFilter>(5000, 0.001);
+ m_addr_known = std::make_unique<CRollingBloomFilter>(5000, 0.001);
}
for (const std::string &msg : getAllNetMessageTypes())
@@ -2923,8 +2923,8 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, SOCKET hSocketIn, const
LogPrint(BCLog::NET, "Added connection peer=%d\n", id);
}
- m_deserializer = MakeUnique<V1TransportDeserializer>(V1TransportDeserializer(Params(), GetId(), SER_NETWORK, INIT_PROTO_VERSION));
- m_serializer = MakeUnique<V1TransportSerializer>(V1TransportSerializer());
+ m_deserializer = std::make_unique<V1TransportDeserializer>(V1TransportDeserializer(Params(), GetId(), SER_NETWORK, INIT_PROTO_VERSION));
+ m_serializer = std::make_unique<V1TransportSerializer>(V1TransportSerializer());
}
CNode::~CNode()
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index d19e11f7b1..c569acd3cb 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -472,6 +472,24 @@ private:
std::vector<std::pair<uint256, CTransactionRef>> vExtraTxnForCompact GUARDED_BY(g_cs_orphans);
/** Offset into vExtraTxnForCompact to insert the next tx */
size_t vExtraTxnForCompactIt GUARDED_BY(g_cs_orphans) = 0;
+
+ void ProcessBlockAvailability(NodeId nodeid) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+ void UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+ bool CanDirectFetch(const Consensus::Params &consensusParams) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+ bool BlockRequestAllowed(const CBlockIndex* pindex, const Consensus::Params& consensusParams) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+ bool AlreadyHaveBlock(const uint256& block_hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+ void ProcessGetBlockData(CNode& pfrom, Peer& peer, const CChainParams& chainparams, const CInv& inv, CConnman& connman);
+ bool PrepareBlockFilterRequest(CNode& peer, const CChainParams& chain_params,
+ BlockFilterType filter_type, uint32_t start_height,
+ const uint256& stop_hash, uint32_t max_height_diff,
+ const CBlockIndex*& stop_index,
+ BlockFilterIndex*& filter_index);
+ void ProcessGetCFilters(CNode& peer, CDataStream& vRecv, const CChainParams& chain_params,
+ CConnman& connman);
+ void ProcessGetCFHeaders(CNode& peer, CDataStream& vRecv, const CChainParams& chain_params,
+ CConnman& connman);
+ void ProcessGetCFCheckPt(CNode& peer, CDataStream& vRecv, const CChainParams& chain_params,
+ CConnman& connman);
};
} // namespace
@@ -488,20 +506,18 @@ namespace {
* and we're no longer holding the node's locks.
*/
struct CNodeState {
- //! The peer's address
- const CService address;
//! The best known block we know this peer has announced.
- const CBlockIndex *pindexBestKnownBlock;
+ const CBlockIndex* pindexBestKnownBlock{nullptr};
//! The hash of the last unknown block this peer has announced.
- uint256 hashLastUnknownBlock;
+ uint256 hashLastUnknownBlock{};
//! The last full block we both have.
- const CBlockIndex *pindexLastCommonBlock;
+ const CBlockIndex* pindexLastCommonBlock{nullptr};
//! The best header we have sent our peer.
- const CBlockIndex *pindexBestHeaderSent;
+ const CBlockIndex* pindexBestHeaderSent{nullptr};
//! Length of current-streak of unconnecting headers announcements
- int nUnconnectingHeaders;
+ int nUnconnectingHeaders{0};
//! Whether we've started headers synchronization with this peer.
- bool fSyncStarted;
+ bool fSyncStarted{false};
//! When to potentially disconnect peer for stalling headers download
std::chrono::microseconds m_headers_sync_timeout{0us};
//! Since when we're stalling block download progress (in microseconds), or 0.
@@ -509,29 +525,29 @@ struct CNodeState {
std::list<QueuedBlock> vBlocksInFlight;
//! When the first entry in vBlocksInFlight started downloading. Don't care when vBlocksInFlight is empty.
std::chrono::microseconds m_downloading_since{0us};
- int nBlocksInFlight;
- int nBlocksInFlightValidHeaders;
+ int nBlocksInFlight{0};
+ int nBlocksInFlightValidHeaders{0};
//! Whether we consider this a preferred download peer.
- bool fPreferredDownload;
+ bool fPreferredDownload{false};
//! Whether this peer wants invs or headers (when possible) for block announcements.
- bool fPreferHeaders;
+ bool fPreferHeaders{false};
//! Whether this peer wants invs or cmpctblocks (when possible) for block announcements.
- bool fPreferHeaderAndIDs;
+ bool fPreferHeaderAndIDs{false};
/**
* Whether this peer will send us cmpctblocks if we request them.
* This is not used to gate request logic, as we really only care about fSupportsDesiredCmpctVersion,
* but is used as a flag to "lock in" the version of compact blocks (fWantsCmpctWitness) we send.
*/
- bool fProvidesHeaderAndIDs;
+ bool fProvidesHeaderAndIDs{false};
//! Whether this peer can give us witnesses
- bool fHaveWitness;
+ bool fHaveWitness{false};
//! Whether this peer wants witnesses in cmpctblocks/blocktxns
- bool fWantsCmpctWitness;
+ bool fWantsCmpctWitness{false};
/**
* If we've announced NODE_WITNESS to this peer: whether the peer sends witnesses in cmpctblocks/blocktxns,
* otherwise: whether this peer sends non-witnesses in cmpctblocks/blocktxns.
*/
- bool fSupportsDesiredCmpctVersion;
+ bool fSupportsDesiredCmpctVersion{false};
/** State used to enforce CHAIN_SYNC_TIMEOUT and EXTRA_PEER_CHECK_INTERVAL logic.
*
@@ -541,7 +557,7 @@ struct CNodeState {
* - its connection type is IsBlockOnlyConn() == false
* - it gave us a valid connecting header
* - we haven't reached MAX_OUTBOUND_PEERS_TO_PROTECT_FROM_DISCONNECT yet
- * - it has a better chain than we have
+ * - its chain tip has at least as much work as ours
*
* CHAIN_SYNC_TIMEOUT: if a peer's best known block has less work than our tip,
* set a timeout CHAIN_SYNC_TIMEOUT seconds in the future:
@@ -568,13 +584,13 @@ struct CNodeState {
bool m_protect;
};
- ChainSyncTimeoutState m_chain_sync;
+ ChainSyncTimeoutState m_chain_sync{0, nullptr, false, false};
//! Time of last new block announcement
- int64_t m_last_block_announcement;
+ int64_t m_last_block_announcement{0};
//! Whether this peer is an inbound connection
- bool m_is_inbound;
+ const bool m_is_inbound;
//! A rolling bloom filter of all announced tx CInvs to this peer.
CRollingBloomFilter m_recently_announced_invs = CRollingBloomFilter{INVENTORY_MAX_RECENT_RELAY, 0.000001};
@@ -582,26 +598,9 @@ struct CNodeState {
//! Whether this peer relays txs via wtxid
bool m_wtxid_relay{false};
- CNodeState(CAddress addrIn, bool is_inbound)
- : address(addrIn), m_is_inbound(is_inbound)
+ CNodeState(bool is_inbound)
+ : m_is_inbound(is_inbound)
{
- pindexBestKnownBlock = nullptr;
- hashLastUnknownBlock.SetNull();
- pindexLastCommonBlock = nullptr;
- pindexBestHeaderSent = nullptr;
- nUnconnectingHeaders = 0;
- fSyncStarted = false;
- nBlocksInFlight = 0;
- nBlocksInFlightValidHeaders = 0;
- fPreferredDownload = false;
- fPreferHeaders = false;
- fPreferHeaderAndIDs = false;
- fProvidesHeaderAndIDs = false;
- fHaveWitness = false;
- fWantsCmpctWitness = false;
- fSupportsDesiredCmpctVersion = false;
- m_chain_sync = { 0, nullptr, false, false };
- m_last_block_announcement = 0;
m_recently_announced_invs.reset();
}
};
@@ -684,41 +683,6 @@ bool PeerManagerImpl::MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, co
return true;
}
-/** Check whether the last unknown block a peer advertised is not yet known. */
-static void ProcessBlockAvailability(NodeId nodeid) EXCLUSIVE_LOCKS_REQUIRED(cs_main) {
- CNodeState *state = State(nodeid);
- assert(state != nullptr);
-
- if (!state->hashLastUnknownBlock.IsNull()) {
- const CBlockIndex* pindex = g_chainman.m_blockman.LookupBlockIndex(state->hashLastUnknownBlock);
- if (pindex && pindex->nChainWork > 0) {
- if (state->pindexBestKnownBlock == nullptr || pindex->nChainWork >= state->pindexBestKnownBlock->nChainWork) {
- state->pindexBestKnownBlock = pindex;
- }
- state->hashLastUnknownBlock.SetNull();
- }
- }
-}
-
-/** Update tracking information about which blocks a peer is assumed to have. */
-static void UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main) {
- CNodeState *state = State(nodeid);
- assert(state != nullptr);
-
- ProcessBlockAvailability(nodeid);
-
- const CBlockIndex* pindex = g_chainman.m_blockman.LookupBlockIndex(hash);
- if (pindex && pindex->nChainWork > 0) {
- // An actually better block was announced.
- if (state->pindexBestKnownBlock == nullptr || pindex->nChainWork >= state->pindexBestKnownBlock->nChainWork) {
- state->pindexBestKnownBlock = pindex;
- }
- } else {
- // An unknown block was announced; just assume that the latest one is the best one.
- state->hashLastUnknownBlock = hash;
- }
-}
-
void PeerManagerImpl::MaybeSetPeerAsAnnouncingHeaderAndIDs(NodeId nodeid)
{
AssertLockHeld(cs_main);
@@ -768,9 +732,9 @@ bool PeerManagerImpl::TipMayBeStale()
return m_last_tip_update < GetTime() - consensusParams.nPowTargetSpacing * 3 && mapBlocksInFlight.empty();
}
-static bool CanDirectFetch(const Consensus::Params &consensusParams) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
+bool PeerManagerImpl::CanDirectFetch(const Consensus::Params &consensusParams)
{
- return ::ChainActive().Tip()->GetBlockTime() > GetAdjustedTime() - consensusParams.nPowTargetSpacing * 20;
+ return m_chainman.ActiveChain().Tip()->GetBlockTime() > GetAdjustedTime() - consensusParams.nPowTargetSpacing * 20;
}
static bool PeerHasHeader(CNodeState *state, const CBlockIndex *pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
@@ -782,6 +746,41 @@ static bool PeerHasHeader(CNodeState *state, const CBlockIndex *pindex) EXCLUSIV
return false;
}
+/** Check whether the last unknown block a peer advertised is not yet known. */
+void PeerManagerImpl::ProcessBlockAvailability(NodeId nodeid) {
+ CNodeState *state = State(nodeid);
+ assert(state != nullptr);
+
+ if (!state->hashLastUnknownBlock.IsNull()) {
+ const CBlockIndex* pindex = m_chainman.m_blockman.LookupBlockIndex(state->hashLastUnknownBlock);
+ if (pindex && pindex->nChainWork > 0) {
+ if (state->pindexBestKnownBlock == nullptr || pindex->nChainWork >= state->pindexBestKnownBlock->nChainWork) {
+ state->pindexBestKnownBlock = pindex;
+ }
+ state->hashLastUnknownBlock.SetNull();
+ }
+ }
+}
+
+/** Update tracking information about which blocks a peer is assumed to have. */
+void PeerManagerImpl::UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) {
+ CNodeState *state = State(nodeid);
+ assert(state != nullptr);
+
+ ProcessBlockAvailability(nodeid);
+
+ const CBlockIndex* pindex = m_chainman.m_blockman.LookupBlockIndex(hash);
+ if (pindex && pindex->nChainWork > 0) {
+ // An actually better block was announced.
+ if (state->pindexBestKnownBlock == nullptr || pindex->nChainWork >= state->pindexBestKnownBlock->nChainWork) {
+ state->pindexBestKnownBlock = pindex;
+ }
+ } else {
+ // An unknown block was announced; just assume that the latest one is the best one.
+ state->hashLastUnknownBlock = hash;
+ }
+}
+
void PeerManagerImpl::FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector<const CBlockIndex*>& vBlocks, NodeId& nodeStaller)
{
if (count == 0)
@@ -794,7 +793,7 @@ void PeerManagerImpl::FindNextBlocksToDownload(NodeId nodeid, unsigned int count
// Make sure pindexBestKnownBlock is up to date, we'll need it.
ProcessBlockAvailability(nodeid);
- if (state->pindexBestKnownBlock == nullptr || state->pindexBestKnownBlock->nChainWork < ::ChainActive().Tip()->nChainWork || state->pindexBestKnownBlock->nChainWork < nMinimumChainWork) {
+ if (state->pindexBestKnownBlock == nullptr || state->pindexBestKnownBlock->nChainWork < m_chainman.ActiveChain().Tip()->nChainWork || state->pindexBestKnownBlock->nChainWork < nMinimumChainWork) {
// This peer has nothing interesting.
return;
}
@@ -802,7 +801,7 @@ void PeerManagerImpl::FindNextBlocksToDownload(NodeId nodeid, unsigned int count
if (state->pindexLastCommonBlock == nullptr) {
// Bootstrap quickly by guessing a parent of our best tip is the forking point.
// Guessing wrong in either direction is not a problem.
- state->pindexLastCommonBlock = ::ChainActive()[std::min(state->pindexBestKnownBlock->nHeight, ::ChainActive().Height())];
+ state->pindexLastCommonBlock = m_chainman.ActiveChain()[std::min(state->pindexBestKnownBlock->nHeight, m_chainman.ActiveChain().Height())];
}
// If the peer reorganized, our previous pindexLastCommonBlock may not be an ancestor
@@ -845,7 +844,7 @@ void PeerManagerImpl::FindNextBlocksToDownload(NodeId nodeid, unsigned int count
// We wouldn't download this block or its descendants from this peer.
return;
}
- if (pindex->nStatus & BLOCK_HAVE_DATA || ::ChainActive().Contains(pindex)) {
+ if (pindex->nStatus & BLOCK_HAVE_DATA || m_chainman.ActiveChain().Contains(pindex)) {
if (pindex->HaveTxsDownloaded())
state->pindexLastCommonBlock = pindex;
} else if (mapBlocksInFlight.count(pindex->GetBlockHash()) == 0) {
@@ -937,12 +936,10 @@ void UpdateLastBlockAnnounceTime(NodeId node, int64_t time_in_seconds)
void PeerManagerImpl::InitializeNode(CNode *pnode)
{
- CAddress addr = pnode->addr;
- std::string addrName = pnode->GetAddrName();
NodeId nodeid = pnode->GetId();
{
LOCK(cs_main);
- mapNodeState.emplace_hint(mapNodeState.end(), std::piecewise_construct, std::forward_as_tuple(nodeid), std::forward_as_tuple(addr, pnode->IsInboundConn()));
+ mapNodeState.emplace_hint(mapNodeState.end(), std::piecewise_construct, std::forward_as_tuple(nodeid), std::forward_as_tuple(pnode->IsInboundConn()));
assert(m_txrequest.Count(nodeid) == 0);
}
{
@@ -1200,10 +1197,10 @@ bool PeerManagerImpl::MaybePunishNodeForTx(NodeId nodeid, const TxValidationStat
// active chain if they are no more than a month older (both in time, and in
// best equivalent proof of work) than the best header chain we know about and
// we fully-validated them at some point.
-static bool BlockRequestAllowed(const CBlockIndex* pindex, const Consensus::Params& consensusParams) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
+bool PeerManagerImpl::BlockRequestAllowed(const CBlockIndex* pindex, const Consensus::Params& consensusParams)
{
AssertLockHeld(cs_main);
- if (::ChainActive().Contains(pindex)) return true;
+ if (m_chainman.ActiveChain().Contains(pindex)) return true;
return pindex->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != nullptr) &&
(pindexBestHeader->GetBlockTime() - pindex->GetBlockTime() < STALE_RELAY_AGE_LIMIT) &&
(GetBlockProofEquivalentTime(*pindexBestHeader, *pindex, *pindexBestHeader, consensusParams) < STALE_RELAY_AGE_LIMIT);
@@ -1227,6 +1224,7 @@ PeerManagerImpl::PeerManagerImpl(const CChainParams& chainparams, CConnman& conn
m_stale_tip_check_time(0),
m_ignore_incoming_txs(ignore_incoming_txs)
{
+ assert(std::addressof(g_chainman) == std::addressof(m_chainman));
// Initialize global variables that cannot be constructed at startup.
recentRejects.reset(new CRollingBloomFilter(120000, 0.000001));
@@ -1352,7 +1350,7 @@ void PeerManagerImpl::NewPoWValidBlock(const CBlockIndex *pindex, const std::sha
/**
* Update our best height and announce any block hashes which weren't previously
- * in ::ChainActive() to our peers.
+ * in m_chainman.ActiveChain() to our peers.
*/
void PeerManagerImpl::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload)
{
@@ -1414,7 +1412,7 @@ void PeerManagerImpl::BlockChecked(const CBlock& block, const BlockValidationSta
// the tip yet so we have no way to check this directly here. Instead we
// just check that there are currently no other blocks in flight.
else if (state.IsValid() &&
- !::ChainstateActive().IsInitialBlockDownload() &&
+ !m_chainman.ActiveChainstate().IsInitialBlockDownload() &&
mapBlocksInFlight.count(hash) == mapBlocksInFlight.size()) {
if (it != mapBlockSource.end()) {
MaybeSetPeerAsAnnouncingHeaderAndIDs(it->second.first);
@@ -1433,12 +1431,12 @@ void PeerManagerImpl::BlockChecked(const CBlock& block, const BlockValidationSta
bool PeerManagerImpl::AlreadyHaveTx(const GenTxid& gtxid)
{
assert(recentRejects);
- if (::ChainActive().Tip()->GetBlockHash() != hashRecentRejectsChainTip) {
+ if (m_chainman.ActiveChain().Tip()->GetBlockHash() != hashRecentRejectsChainTip) {
// If the chain tip has changed previously rejected transactions
// might be now valid, e.g. due to a nLockTime'd tx becoming valid,
// or a double-spend. Reset the rejects filter and give those
// txs a second chance.
- hashRecentRejectsChainTip = ::ChainActive().Tip()->GetBlockHash();
+ hashRecentRejectsChainTip = m_chainman.ActiveChain().Tip()->GetBlockHash();
recentRejects->reset();
}
@@ -1454,9 +1452,9 @@ bool PeerManagerImpl::AlreadyHaveTx(const GenTxid& gtxid)
return recentRejects->contains(hash) || m_mempool.exists(gtxid);
}
-bool static AlreadyHaveBlock(const uint256& block_hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
+bool PeerManagerImpl::AlreadyHaveBlock(const uint256& block_hash)
{
- return g_chainman.m_blockman.LookupBlockIndex(block_hash) != nullptr;
+ return m_chainman.m_blockman.LookupBlockIndex(block_hash) != nullptr;
}
void PeerManagerImpl::SendPings()
@@ -1535,7 +1533,7 @@ static void RelayAddress(const CNode& originator,
connman.ForEachNodeThen(std::move(sortfunc), std::move(pushfunc));
}
-void static ProcessGetBlockData(CNode& pfrom, Peer& peer, const CChainParams& chainparams, const CInv& inv, CConnman& connman)
+void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CChainParams& chainparams, const CInv& inv, CConnman& connman)
{
bool send = false;
std::shared_ptr<const CBlock> a_recent_block;
@@ -1552,7 +1550,7 @@ void static ProcessGetBlockData(CNode& pfrom, Peer& peer, const CChainParams& ch
bool need_activate_chain = false;
{
LOCK(cs_main);
- const CBlockIndex* pindex = g_chainman.m_blockman.LookupBlockIndex(inv.hash);
+ const CBlockIndex* pindex = m_chainman.m_blockman.LookupBlockIndex(inv.hash);
if (pindex) {
if (pindex->HaveTxsDownloaded() && !pindex->IsValid(BLOCK_VALID_SCRIPTS) &&
pindex->IsValid(BLOCK_VALID_TREE)) {
@@ -1567,13 +1565,13 @@ void static ProcessGetBlockData(CNode& pfrom, Peer& peer, const CChainParams& ch
} // release cs_main before calling ActivateBestChain
if (need_activate_chain) {
BlockValidationState state;
- if (!::ChainstateActive().ActivateBestChain(state, chainparams, a_recent_block)) {
+ if (!m_chainman.ActiveChainstate().ActivateBestChain(state, chainparams, a_recent_block)) {
LogPrint(BCLog::NET, "failed to activate chain (%s)\n", state.ToString());
}
}
LOCK(cs_main);
- const CBlockIndex* pindex = g_chainman.m_blockman.LookupBlockIndex(inv.hash);
+ const CBlockIndex* pindex = m_chainman.m_blockman.LookupBlockIndex(inv.hash);
if (pindex) {
send = BlockRequestAllowed(pindex, consensusParams);
if (!send) {
@@ -1595,7 +1593,7 @@ void static ProcessGetBlockData(CNode& pfrom, Peer& peer, const CChainParams& ch
}
// Avoid leaking prune-height by never sending blocks below the NODE_NETWORK_LIMITED threshold
if (send && !pfrom.HasPermission(PF_NOBAN) && (
- (((pfrom.GetLocalServices() & NODE_NETWORK_LIMITED) == NODE_NETWORK_LIMITED) && ((pfrom.GetLocalServices() & NODE_NETWORK) != NODE_NETWORK) && (::ChainActive().Tip()->nHeight - pindex->nHeight > (int)NODE_NETWORK_LIMITED_MIN_BLOCKS + 2 /* add two blocks buffer extension for possible races */) )
+ (((pfrom.GetLocalServices() & NODE_NETWORK_LIMITED) == NODE_NETWORK_LIMITED) && ((pfrom.GetLocalServices() & NODE_NETWORK) != NODE_NETWORK) && (m_chainman.ActiveChain().Tip()->nHeight - pindex->nHeight > (int)NODE_NETWORK_LIMITED_MIN_BLOCKS + 2 /* add two blocks buffer extension for possible races */) )
)) {
LogPrint(BCLog::NET, "Ignore block request below NODE_NETWORK_LIMITED threshold from peer=%d\n", pfrom.GetId());
@@ -1662,7 +1660,7 @@ void static ProcessGetBlockData(CNode& pfrom, Peer& peer, const CChainParams& ch
// instead we respond with the full, non-compact block.
bool fPeerWantsWitness = State(pfrom.GetId())->fWantsCmpctWitness;
int nSendFlags = fPeerWantsWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS;
- if (CanDirectFetch(consensusParams) && pindex->nHeight >= ::ChainActive().Height() - MAX_CMPCTBLOCK_DEPTH) {
+ if (CanDirectFetch(consensusParams) && pindex->nHeight >= m_chainman.ActiveChain().Height() - MAX_CMPCTBLOCK_DEPTH) {
if ((fPeerWantsWitness || !fWitnessesPresentInARecentCompactBlock) && a_recent_compact_block && a_recent_compact_block->header.GetHash() == pindex->GetBlockHash()) {
connman.PushMessage(&pfrom, msgMaker.Make(nSendFlags, NetMsgType::CMPCTBLOCK, *a_recent_compact_block));
} else {
@@ -1683,7 +1681,7 @@ void static ProcessGetBlockData(CNode& pfrom, Peer& peer, const CChainParams& ch
// and we want it right after the last block so they don't
// wait for other stuff first.
std::vector<CInv> vInv;
- vInv.push_back(CInv(MSG_BLOCK, ::ChainActive().Tip()->GetBlockHash()));
+ vInv.push_back(CInv(MSG_BLOCK, m_chainman.ActiveChain().Tip()->GetBlockHash()));
connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::INV, vInv));
peer.m_continuation_block.SetNull();
}
@@ -1862,9 +1860,9 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
// don't connect before giving DoS points
// - Once a headers message is received that is valid and does connect,
// nUnconnectingHeaders gets reset back to 0.
- if (!g_chainman.m_blockman.LookupBlockIndex(headers[0].hashPrevBlock) && nCount < MAX_BLOCKS_TO_ANNOUNCE) {
+ if (!m_chainman.m_blockman.LookupBlockIndex(headers[0].hashPrevBlock) && nCount < MAX_BLOCKS_TO_ANNOUNCE) {
nodestate->nUnconnectingHeaders++;
- m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::GETHEADERS, ::ChainActive().GetLocator(pindexBestHeader), uint256()));
+ m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::GETHEADERS, m_chainman.ActiveChain().GetLocator(pindexBestHeader), uint256()));
LogPrint(BCLog::NET, "received header %s: missing prev block %s, sending getheaders (%d) to end (peer=%d, nUnconnectingHeaders=%d)\n",
headers[0].GetHash().ToString(),
headers[0].hashPrevBlock.ToString(),
@@ -1892,7 +1890,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
// If we don't have the last header, then they'll have given us
// something new (if these headers are valid).
- if (!g_chainman.m_blockman.LookupBlockIndex(hashLastBlock)) {
+ if (!m_chainman.m_blockman.LookupBlockIndex(hashLastBlock)) {
received_new_header = true;
}
}
@@ -1920,27 +1918,27 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
// because it is set in UpdateBlockAvailability. Some nullptr checks
// are still present, however, as belt-and-suspenders.
- if (received_new_header && pindexLast->nChainWork > ::ChainActive().Tip()->nChainWork) {
+ if (received_new_header && pindexLast->nChainWork > m_chainman.ActiveChain().Tip()->nChainWork) {
nodestate->m_last_block_announcement = GetTime();
}
if (nCount == MAX_HEADERS_RESULTS) {
// Headers message had its maximum size; the peer may have more headers.
- // TODO: optimize: if pindexLast is an ancestor of ::ChainActive().Tip or pindexBestHeader, continue
+ // TODO: optimize: if pindexLast is an ancestor of m_chainman.ActiveChain().Tip or pindexBestHeader, continue
// from there instead.
LogPrint(BCLog::NET, "more getheaders (%d) to end to peer=%d (startheight:%d)\n",
pindexLast->nHeight, pfrom.GetId(), peer.m_starting_height);
- m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::GETHEADERS, ::ChainActive().GetLocator(pindexLast), uint256()));
+ m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::GETHEADERS, m_chainman.ActiveChain().GetLocator(pindexLast), uint256()));
}
bool fCanDirectFetch = CanDirectFetch(m_chainparams.GetConsensus());
// If this set of headers is valid and ends in a block with at least as
// much work as our tip, download as much as possible.
- if (fCanDirectFetch && pindexLast->IsValid(BLOCK_VALID_TREE) && ::ChainActive().Tip()->nChainWork <= pindexLast->nChainWork) {
+ if (fCanDirectFetch && pindexLast->IsValid(BLOCK_VALID_TREE) && m_chainman.ActiveChain().Tip()->nChainWork <= pindexLast->nChainWork) {
std::vector<const CBlockIndex*> vToFetch;
const CBlockIndex *pindexWalk = pindexLast;
// Calculate all the blocks we'd need to switch to pindexLast, up to a limit.
- while (pindexWalk && !::ChainActive().Contains(pindexWalk) && vToFetch.size() <= MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
+ while (pindexWalk && !m_chainman.ActiveChain().Contains(pindexWalk) && vToFetch.size() <= MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
if (!(pindexWalk->nStatus & BLOCK_HAVE_DATA) &&
!mapBlocksInFlight.count(pindexWalk->GetBlockHash()) &&
(!IsWitnessEnabled(pindexWalk->pprev, m_chainparams.GetConsensus()) || State(pfrom.GetId())->fHaveWitness)) {
@@ -1953,7 +1951,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
// very large reorg at a time we think we're close to caught up to
// the main chain -- this shouldn't really happen. Bail out on the
// direct fetch and rely on parallel download instead.
- if (!::ChainActive().Contains(pindexWalk)) {
+ if (!m_chainman.ActiveChain().Contains(pindexWalk)) {
LogPrint(BCLog::NET, "Large reorg, won't direct fetch to %s (%d)\n",
pindexLast->GetBlockHash().ToString(),
pindexLast->nHeight);
@@ -1986,7 +1984,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
}
// If we're in IBD, we want outbound peers that will serve us a useful
// chain. Disconnect peers that are on chains with insufficient work.
- if (::ChainstateActive().IsInitialBlockDownload() && nCount != MAX_HEADERS_RESULTS) {
+ if (m_chainman.ActiveChainstate().IsInitialBlockDownload() && nCount != MAX_HEADERS_RESULTS) {
// When nCount < MAX_HEADERS_RESULTS, we know we have no more
// headers to fetch from this peer.
if (nodestate->pindexBestKnownBlock && nodestate->pindexBestKnownBlock->nChainWork < nMinimumChainWork) {
@@ -1994,7 +1992,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
// us sync -- disconnect if it is an outbound disconnection
// candidate.
// Note: We compare their tip to nMinimumChainWork (rather than
- // ::ChainActive().Tip()) because we won't start block download
+ // m_chainman.ActiveChain().Tip()) because we won't start block download
// until we have a headers chain that has at least
// nMinimumChainWork, even if a peer has a chain past our tip,
// as an anti-DoS measure.
@@ -2011,7 +2009,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
// thus always subject to eviction under the bad/lagging chain logic.
// See ChainSyncTimeoutState.
if (!pfrom.fDisconnect && pfrom.IsFullOutboundConn() && nodestate->pindexBestKnownBlock != nullptr) {
- if (m_outbound_peers_with_protect_from_disconnect < MAX_OUTBOUND_PEERS_TO_PROTECT_FROM_DISCONNECT && nodestate->pindexBestKnownBlock->nChainWork >= ::ChainActive().Tip()->nChainWork && !nodestate->m_chain_sync.m_protect) {
+ if (m_outbound_peers_with_protect_from_disconnect < MAX_OUTBOUND_PEERS_TO_PROTECT_FROM_DISCONNECT && nodestate->pindexBestKnownBlock->nChainWork >= m_chainman.ActiveChain().Tip()->nChainWork && !nodestate->m_chain_sync.m_protect) {
LogPrint(BCLog::NET, "Protecting outbound peer=%d from eviction\n", pfrom.GetId());
nodestate->m_chain_sync.m_protect = true;
++m_outbound_peers_with_protect_from_disconnect;
@@ -2042,7 +2040,7 @@ void PeerManagerImpl::ProcessOrphanTx(std::set<uint256>& orphan_work_set)
const auto [porphanTx, from_peer] = m_orphanage.GetTx(orphanHash);
if (porphanTx == nullptr) continue;
- const MempoolAcceptResult result = AcceptToMemoryPool(::ChainstateActive(), m_mempool, porphanTx, false /* bypass_limits */);
+ const MempoolAcceptResult result = AcceptToMemoryPool(m_chainman.ActiveChainstate(), m_mempool, porphanTx, false /* bypass_limits */);
const TxValidationState& state = result.m_state;
if (result.m_result_type == MempoolAcceptResult::ResultType::VALID) {
@@ -2118,7 +2116,7 @@ void PeerManagerImpl::ProcessOrphanTx(std::set<uint256>& orphan_work_set)
* @param[out] filter_index The filter index, if the request can be serviced.
* @return True if the request can be serviced.
*/
-static bool PrepareBlockFilterRequest(CNode& peer, const CChainParams& chain_params,
+bool PeerManagerImpl::PrepareBlockFilterRequest(CNode& peer, const CChainParams& chain_params,
BlockFilterType filter_type, uint32_t start_height,
const uint256& stop_hash, uint32_t max_height_diff,
const CBlockIndex*& stop_index,
@@ -2136,7 +2134,7 @@ static bool PrepareBlockFilterRequest(CNode& peer, const CChainParams& chain_par
{
LOCK(cs_main);
- stop_index = g_chainman.m_blockman.LookupBlockIndex(stop_hash);
+ stop_index = m_chainman.m_blockman.LookupBlockIndex(stop_hash);
// Check that the stop block exists and the peer would be allowed to fetch it.
if (!stop_index || !BlockRequestAllowed(stop_index, chain_params.GetConsensus())) {
@@ -2181,7 +2179,7 @@ static bool PrepareBlockFilterRequest(CNode& peer, const CChainParams& chain_par
* @param[in] chain_params Chain parameters
* @param[in] connman Pointer to the connection manager
*/
-static void ProcessGetCFilters(CNode& peer, CDataStream& vRecv, const CChainParams& chain_params,
+void PeerManagerImpl::ProcessGetCFilters(CNode& peer, CDataStream& vRecv, const CChainParams& chain_params,
CConnman& connman)
{
uint8_t filter_type_ser;
@@ -2223,7 +2221,7 @@ static void ProcessGetCFilters(CNode& peer, CDataStream& vRecv, const CChainPara
* @param[in] chain_params Chain parameters
* @param[in] connman Pointer to the connection manager
*/
-static void ProcessGetCFHeaders(CNode& peer, CDataStream& vRecv, const CChainParams& chain_params,
+void PeerManagerImpl::ProcessGetCFHeaders(CNode& peer, CDataStream& vRecv, const CChainParams& chain_params,
CConnman& connman)
{
uint8_t filter_type_ser;
@@ -2278,7 +2276,7 @@ static void ProcessGetCFHeaders(CNode& peer, CDataStream& vRecv, const CChainPar
* @param[in] chain_params Chain parameters
* @param[in] connman Pointer to the connection manager
*/
-static void ProcessGetCFCheckPt(CNode& peer, CDataStream& vRecv, const CChainParams& chain_params,
+void PeerManagerImpl::ProcessGetCFCheckPt(CNode& peer, CDataStream& vRecv, const CChainParams& chain_params,
CConnman& connman)
{
uint8_t filter_type_ser;
@@ -2461,7 +2459,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
//
// We skip this for block-relay-only peers to avoid potentially leaking
// information about our block-relay-only connections via address relay.
- if (fListen && !::ChainstateActive().IsInitialBlockDownload())
+ if (fListen && !m_chainman.ActiveChainstate().IsInitialBlockDownload())
{
CAddress addr = GetLocalAddress(&pfrom.addr, pfrom.GetLocalServices());
FastRandomContext insecure_rand;
@@ -2778,7 +2776,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
}
if (best_block != nullptr) {
- m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::GETHEADERS, ::ChainActive().GetLocator(pindexBestHeader), *best_block));
+ m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::GETHEADERS, m_chainman.ActiveChain().GetLocator(pindexBestHeader), *best_block));
LogPrint(BCLog::NET, "getheaders (%d) %s to peer=%d\n", pindexBestHeader->nHeight, best_block->ToString(), pfrom.GetId());
}
@@ -2834,7 +2832,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
a_recent_block = most_recent_block;
}
BlockValidationState state;
- if (!::ChainstateActive().ActivateBestChain(state, m_chainparams, a_recent_block)) {
+ if (!m_chainman.ActiveChainstate().ActivateBestChain(state, m_chainparams, a_recent_block)) {
LogPrint(BCLog::NET, "failed to activate chain (%s)\n", state.ToString());
}
}
@@ -2842,14 +2840,14 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
LOCK(cs_main);
// Find the last block the caller has in the main chain
- const CBlockIndex* pindex = g_chainman.m_blockman.FindForkInGlobalIndex(::ChainActive(), locator);
+ const CBlockIndex* pindex = m_chainman.m_blockman.FindForkInGlobalIndex(m_chainman.ActiveChain(), locator);
// Send the rest of the chain
if (pindex)
- pindex = ::ChainActive().Next(pindex);
+ pindex = m_chainman.ActiveChain().Next(pindex);
int nLimit = 500;
LogPrint(BCLog::NET, "getblocks %d to %s limit %d from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.IsNull() ? "end" : hashStop.ToString(), nLimit, pfrom.GetId());
- for (; pindex; pindex = ::ChainActive().Next(pindex))
+ for (; pindex; pindex = m_chainman.ActiveChain().Next(pindex))
{
if (pindex->GetBlockHash() == hashStop)
{
@@ -2859,7 +2857,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
// If pruning, don't inv blocks unless we have on disk and are likely to still have
// for some reasonable time window (1 hour) that block relay might require.
const int nPrunedBlocksLikelyToHave = MIN_BLOCKS_TO_KEEP - 3600 / m_chainparams.GetConsensus().nPowTargetSpacing;
- if (fPruneMode && (!(pindex->nStatus & BLOCK_HAVE_DATA) || pindex->nHeight <= ::ChainActive().Tip()->nHeight - nPrunedBlocksLikelyToHave))
+ if (fPruneMode && (!(pindex->nStatus & BLOCK_HAVE_DATA) || pindex->nHeight <= m_chainman.ActiveChain().Tip()->nHeight - nPrunedBlocksLikelyToHave))
{
LogPrint(BCLog::NET, " getblocks stopping, pruned or too old block at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
break;
@@ -2895,13 +2893,13 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
{
LOCK(cs_main);
- const CBlockIndex* pindex = g_chainman.m_blockman.LookupBlockIndex(req.blockhash);
+ const CBlockIndex* pindex = m_chainman.m_blockman.LookupBlockIndex(req.blockhash);
if (!pindex || !(pindex->nStatus & BLOCK_HAVE_DATA)) {
LogPrint(BCLog::NET, "Peer %d sent us a getblocktxn for a block we don't have\n", pfrom.GetId());
return;
}
- if (pindex->nHeight >= ::ChainActive().Height() - MAX_BLOCKTXN_DEPTH) {
+ if (pindex->nHeight >= m_chainman.ActiveChain().Height() - MAX_BLOCKTXN_DEPTH) {
CBlock block;
bool ret = ReadBlockFromDisk(block, pindex, m_chainparams.GetConsensus());
assert(ret);
@@ -2939,7 +2937,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
}
LOCK(cs_main);
- if (::ChainstateActive().IsInitialBlockDownload() && !pfrom.HasPermission(PF_DOWNLOAD)) {
+ if (m_chainman.ActiveChainstate().IsInitialBlockDownload() && !pfrom.HasPermission(PF_DOWNLOAD)) {
LogPrint(BCLog::NET, "Ignoring getheaders from peer=%d because node is in initial block download\n", pfrom.GetId());
return;
}
@@ -2949,7 +2947,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
if (locator.IsNull())
{
// If locator is null, return the hashStop block
- pindex = g_chainman.m_blockman.LookupBlockIndex(hashStop);
+ pindex = m_chainman.m_blockman.LookupBlockIndex(hashStop);
if (!pindex) {
return;
}
@@ -2962,23 +2960,23 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
else
{
// Find the last block the caller has in the main chain
- pindex = g_chainman.m_blockman.FindForkInGlobalIndex(::ChainActive(), locator);
+ pindex = m_chainman.m_blockman.FindForkInGlobalIndex(m_chainman.ActiveChain(), locator);
if (pindex)
- pindex = ::ChainActive().Next(pindex);
+ pindex = m_chainman.ActiveChain().Next(pindex);
}
// we must use CBlocks, as CBlockHeaders won't include the 0x00 nTx count at the end
std::vector<CBlock> vHeaders;
int nLimit = MAX_HEADERS_RESULTS;
LogPrint(BCLog::NET, "getheaders %d to %s from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.IsNull() ? "end" : hashStop.ToString(), pfrom.GetId());
- for (; pindex; pindex = ::ChainActive().Next(pindex))
+ for (; pindex; pindex = m_chainman.ActiveChain().Next(pindex))
{
vHeaders.push_back(pindex->GetBlockHeader());
if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
break;
}
- // pindex can be nullptr either if we sent ::ChainActive().Tip() OR
- // if our peer has ::ChainActive().Tip() (and thus we are sending an empty
+ // pindex can be nullptr either if we sent m_chainman.ActiveChain().Tip() OR
+ // if our peer has m_chainman.ActiveChain().Tip() (and thus we are sending an empty
// headers message). In both cases it's safe to update
// pindexBestHeaderSent to be our tip.
//
@@ -2989,7 +2987,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
// without the new block. By resetting the BestHeaderSent, we ensure we
// will re-announce the new block via headers (or compact blocks again)
// in the SendMessages logic.
- nodestate->pindexBestHeaderSent = pindex ? pindex : ::ChainActive().Tip();
+ nodestate->pindexBestHeaderSent = pindex ? pindex : m_chainman.ActiveChain().Tip();
m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::HEADERS, vHeaders));
return;
}
@@ -3057,7 +3055,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
return;
}
- const MempoolAcceptResult result = AcceptToMemoryPool(::ChainstateActive(), m_mempool, ptx, false /* bypass_limits */);
+ const MempoolAcceptResult result = AcceptToMemoryPool(m_chainman.ActiveChainstate(), m_mempool, ptx, false /* bypass_limits */);
const TxValidationState& state = result.m_state;
if (result.m_result_type == MempoolAcceptResult::ResultType::VALID) {
@@ -3222,14 +3220,14 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
{
LOCK(cs_main);
- if (!g_chainman.m_blockman.LookupBlockIndex(cmpctblock.header.hashPrevBlock)) {
+ if (!m_chainman.m_blockman.LookupBlockIndex(cmpctblock.header.hashPrevBlock)) {
// Doesn't connect (or is genesis), instead of DoSing in AcceptBlockHeader, request deeper headers
- if (!::ChainstateActive().IsInitialBlockDownload())
- m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::GETHEADERS, ::ChainActive().GetLocator(pindexBestHeader), uint256()));
+ if (!m_chainman.ActiveChainstate().IsInitialBlockDownload())
+ m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::GETHEADERS, m_chainman.ActiveChain().GetLocator(pindexBestHeader), uint256()));
return;
}
- if (!g_chainman.m_blockman.LookupBlockIndex(cmpctblock.header.GetHash())) {
+ if (!m_chainman.m_blockman.LookupBlockIndex(cmpctblock.header.GetHash())) {
received_new_header = true;
}
}
@@ -3269,7 +3267,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
// If this was a new header with more work than our tip, update the
// peer's last block announcement time
- if (received_new_header && pindex->nChainWork > ::ChainActive().Tip()->nChainWork) {
+ if (received_new_header && pindex->nChainWork > m_chainman.ActiveChain().Tip()->nChainWork) {
nodestate->m_last_block_announcement = GetTime();
}
@@ -3279,7 +3277,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
if (pindex->nStatus & BLOCK_HAVE_DATA) // Nothing to do here
return;
- if (pindex->nChainWork <= ::ChainActive().Tip()->nChainWork || // We know something better
+ if (pindex->nChainWork <= m_chainman.ActiveChain().Tip()->nChainWork || // We know something better
pindex->nTx != 0) { // We had this block at some point, but pruned it
if (fAlreadyInFlight) {
// We requested this block for some reason, but our mempool will probably be useless
@@ -3303,7 +3301,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
// We want to be a bit conservative just to be extra careful about DoS
// possibilities in compact block processing...
- if (pindex->nHeight <= ::ChainActive().Height() + 2) {
+ if (pindex->nHeight <= m_chainman.ActiveChain().Height() + 2) {
if ((!fAlreadyInFlight && nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) ||
(fAlreadyInFlight && blockInFlightIt->second.first == pfrom.GetId())) {
std::list<QueuedBlock>::iterator* queuedBlockIt = nullptr;
@@ -3951,7 +3949,7 @@ void PeerManagerImpl::ConsiderEviction(CNode& pto, int64_t time_in_seconds)
// their chain has more work than ours, we should sync to it,
// unless it's invalid, in which case we should find that out and
// disconnect from them elsewhere).
- if (state.pindexBestKnownBlock != nullptr && state.pindexBestKnownBlock->nChainWork >= ::ChainActive().Tip()->nChainWork) {
+ if (state.pindexBestKnownBlock != nullptr && state.pindexBestKnownBlock->nChainWork >= m_chainman.ActiveChain().Tip()->nChainWork) {
if (state.m_chain_sync.m_timeout != 0) {
state.m_chain_sync.m_timeout = 0;
state.m_chain_sync.m_work_header = nullptr;
@@ -3963,7 +3961,7 @@ void PeerManagerImpl::ConsiderEviction(CNode& pto, int64_t time_in_seconds)
// where we checked against our tip.
// Either way, set a new timeout based on current tip.
state.m_chain_sync.m_timeout = time_in_seconds + CHAIN_SYNC_TIMEOUT;
- state.m_chain_sync.m_work_header = ::ChainActive().Tip();
+ state.m_chain_sync.m_work_header = m_chainman.ActiveChain().Tip();
state.m_chain_sync.m_sent_getheaders = false;
} else if (state.m_chain_sync.m_timeout > 0 && time_in_seconds > state.m_chain_sync.m_timeout) {
// No evidence yet that our peer has synced to a chain with work equal to that
@@ -3976,7 +3974,7 @@ void PeerManagerImpl::ConsiderEviction(CNode& pto, int64_t time_in_seconds)
} else {
assert(state.m_chain_sync.m_work_header);
LogPrint(BCLog::NET, "sending getheaders to outbound peer=%d to verify chain work (current best known block:%s, benchmark blockhash: %s)\n", pto.GetId(), state.pindexBestKnownBlock != nullptr ? state.pindexBestKnownBlock->GetBlockHash().ToString() : "<none>", state.m_chain_sync.m_work_header->GetBlockHash().ToString());
- m_connman.PushMessage(&pto, msgMaker.Make(NetMsgType::GETHEADERS, ::ChainActive().GetLocator(state.m_chain_sync.m_work_header->pprev), uint256()));
+ m_connman.PushMessage(&pto, msgMaker.Make(NetMsgType::GETHEADERS, m_chainman.ActiveChain().GetLocator(state.m_chain_sync.m_work_header->pprev), uint256()));
state.m_chain_sync.m_sent_getheaders = true;
constexpr int64_t HEADERS_RESPONSE_TIME = 120; // 2 minutes
// Bump the timeout to allow a response, which could clear the timeout
@@ -4213,7 +4211,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
auto current_time = GetTime<std::chrono::microseconds>();
if (fListen && pto->RelayAddrsWithConn() &&
- !::ChainstateActive().IsInitialBlockDownload() &&
+ !m_chainman.ActiveChainstate().IsInitialBlockDownload() &&
pto->m_next_local_addr_send < current_time) {
// If we've sent before, clear the bloom filter for the peer, so that our
// self-announcement will actually go out.
@@ -4274,7 +4272,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
// Start block sync
if (pindexBestHeader == nullptr)
- pindexBestHeader = ::ChainActive().Tip();
+ pindexBestHeader = m_chainman.ActiveChain().Tip();
bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->fClient && !pto->IsAddrFetchConn()); // Download if this is a nice peer, or we have no nice peers and this one might do.
if (!state.fSyncStarted && !pto->fClient && !fImporting && !fReindex) {
// Only actively request headers from a single peer, unless we're close to today.
@@ -4299,7 +4297,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
if (pindexStart->pprev)
pindexStart = pindexStart->pprev;
LogPrint(BCLog::NET, "initial getheaders (%d) to peer=%d (startheight:%d)\n", pindexStart->nHeight, pto->GetId(), peer->m_starting_height);
- m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::GETHEADERS, ::ChainActive().GetLocator(pindexStart), uint256()));
+ m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::GETHEADERS, m_chainman.ActiveChain().GetLocator(pindexStart), uint256()));
}
}
@@ -4326,11 +4324,11 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
bool fFoundStartingHeader = false;
// Try to find first header that our peer doesn't have, and
// then send all headers past that one. If we come across any
- // headers that aren't on ::ChainActive(), give up.
+ // headers that aren't on m_chainman.ActiveChain(), give up.
for (const uint256& hash : peer->m_blocks_for_headers_relay) {
- const CBlockIndex* pindex = g_chainman.m_blockman.LookupBlockIndex(hash);
+ const CBlockIndex* pindex = m_chainman.m_blockman.LookupBlockIndex(hash);
assert(pindex);
- if (::ChainActive()[pindex->nHeight] != pindex) {
+ if (m_chainman.ActiveChain()[pindex->nHeight] != pindex) {
// Bail out if we reorged away from this block
fRevertToInv = true;
break;
@@ -4420,15 +4418,15 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
// in the past.
if (!peer->m_blocks_for_headers_relay.empty()) {
const uint256& hashToAnnounce = peer->m_blocks_for_headers_relay.back();
- const CBlockIndex* pindex = g_chainman.m_blockman.LookupBlockIndex(hashToAnnounce);
+ const CBlockIndex* pindex = m_chainman.m_blockman.LookupBlockIndex(hashToAnnounce);
assert(pindex);
// Warn if we're announcing a block that is not on the main chain.
// This should be very rare and could be optimized out.
// Just log for now.
- if (::ChainActive()[pindex->nHeight] != pindex) {
+ if (m_chainman.ActiveChain()[pindex->nHeight] != pindex) {
LogPrint(BCLog::NET, "Announcing block %s not on main chain (tip=%s)\n",
- hashToAnnounce.ToString(), ::ChainActive().Tip()->GetBlockHash().ToString());
+ hashToAnnounce.ToString(), m_chainman.ActiveChain().Tip()->GetBlockHash().ToString());
}
// If the peer's chain has this block, don't inv it back.
@@ -4658,7 +4656,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
// Message: getdata (blocks)
//
std::vector<CInv> vGetData;
- if (!pto->fClient && ((fFetch && !pto->m_limited_node) || !::ChainstateActive().IsInitialBlockDownload()) && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
+ if (!pto->fClient && ((fFetch && !pto->m_limited_node) || !m_chainman.ActiveChainstate().IsInitialBlockDownload()) && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
std::vector<const CBlockIndex*> vToDownload;
NodeId staller = -1;
FindNextBlocksToDownload(pto->GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller);
@@ -4747,4 +4745,3 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
} // release cs_main
return true;
}
-
diff --git a/src/node/coin.cpp b/src/node/coin.cpp
index f4f86cdbe9..263dcff657 100644
--- a/src/node/coin.cpp
+++ b/src/node/coin.cpp
@@ -12,7 +12,8 @@ void FindCoins(const NodeContext& node, std::map<COutPoint, Coin>& coins)
{
assert(node.mempool);
LOCK2(cs_main, node.mempool->cs);
- CCoinsViewCache& chain_view = ::ChainstateActive().CoinsTip();
+ assert(std::addressof(::ChainstateActive()) == std::addressof(node.chainman->ActiveChainstate()));
+ CCoinsViewCache& chain_view = node.chainman->ActiveChainstate().CoinsTip();
CCoinsViewMemPool mempool_view(&chain_view, *node.mempool);
for (auto& coin : coins) {
if (!mempool_view.GetCoin(coin.first, coin.second)) {
diff --git a/src/node/coinstats.cpp b/src/node/coinstats.cpp
index 06fcc33725..88bdba5953 100644
--- a/src/node/coinstats.cpp
+++ b/src/node/coinstats.cpp
@@ -83,7 +83,7 @@ static void ApplyStats(CCoinsStats& stats, T& hash_obj, const uint256& hash, con
//! Calculate statistics about the unspent transaction output set
template <typename T>
-static bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats, T hash_obj, const std::function<void()>& interruption_point)
+static bool GetUTXOStats(CCoinsView* view, BlockManager& blockman, CCoinsStats& stats, T hash_obj, const std::function<void()>& interruption_point)
{
stats = CCoinsStats();
std::unique_ptr<CCoinsViewCursor> pcursor(view->Cursor());
@@ -92,7 +92,8 @@ static bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats, T hash_obj, const
stats.hashBlock = pcursor->GetBestBlock();
{
LOCK(cs_main);
- stats.nHeight = g_chainman.m_blockman.LookupBlockIndex(stats.hashBlock)->nHeight;
+ assert(std::addressof(g_chainman.m_blockman) == std::addressof(blockman));
+ stats.nHeight = blockman.LookupBlockIndex(stats.hashBlock)->nHeight;
}
PrepareHash(hash_obj, stats);
@@ -126,19 +127,19 @@ static bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats, T hash_obj, const
return true;
}
-bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats, CoinStatsHashType hash_type, const std::function<void()>& interruption_point)
+bool GetUTXOStats(CCoinsView* view, BlockManager& blockman, CCoinsStats& stats, CoinStatsHashType hash_type, const std::function<void()>& interruption_point)
{
switch (hash_type) {
case(CoinStatsHashType::HASH_SERIALIZED): {
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
- return GetUTXOStats(view, stats, ss, interruption_point);
+ return GetUTXOStats(view, blockman, stats, ss, interruption_point);
}
case(CoinStatsHashType::MUHASH): {
MuHash3072 muhash;
- return GetUTXOStats(view, stats, muhash, interruption_point);
+ return GetUTXOStats(view, blockman, stats, muhash, interruption_point);
}
case(CoinStatsHashType::NONE): {
- return GetUTXOStats(view, stats, nullptr, interruption_point);
+ return GetUTXOStats(view, blockman, stats, nullptr, interruption_point);
}
} // no default case, so the compiler can warn about missing cases
assert(false);
diff --git a/src/node/coinstats.h b/src/node/coinstats.h
index f02b95235f..83f228aa7e 100644
--- a/src/node/coinstats.h
+++ b/src/node/coinstats.h
@@ -8,6 +8,7 @@
#include <amount.h>
#include <uint256.h>
+#include <validation.h>
#include <cstdint>
#include <functional>
@@ -36,6 +37,6 @@ struct CCoinsStats
};
//! Calculate statistics about the unspent transaction output set
-bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats, const CoinStatsHashType hash_type, const std::function<void()>& interruption_point = {});
+bool GetUTXOStats(CCoinsView* view, BlockManager& blockman, CCoinsStats& stats, const CoinStatsHashType hash_type, const std::function<void()>& interruption_point = {});
#endif // BITCOIN_NODE_COINSTATS_H
diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp
index acd6d7847e..9406ef07c5 100644
--- a/src/node/interfaces.cpp
+++ b/src/node/interfaces.cpp
@@ -182,18 +182,21 @@ public:
int getNumBlocks() override
{
LOCK(::cs_main);
- return ::ChainActive().Height();
+ assert(std::addressof(::ChainActive()) == std::addressof(m_context->chainman->ActiveChain()));
+ return m_context->chainman->ActiveChain().Height();
}
uint256 getBestBlockHash() override
{
- const CBlockIndex* tip = WITH_LOCK(::cs_main, return ::ChainActive().Tip());
+ assert(std::addressof(::ChainActive()) == std::addressof(m_context->chainman->ActiveChain()));
+ const CBlockIndex* tip = WITH_LOCK(::cs_main, return m_context->chainman->ActiveChain().Tip());
return tip ? tip->GetBlockHash() : Params().GenesisBlock().GetHash();
}
int64_t getLastBlockTime() override
{
LOCK(::cs_main);
- if (::ChainActive().Tip()) {
- return ::ChainActive().Tip()->GetBlockTime();
+ assert(std::addressof(::ChainActive()) == std::addressof(m_context->chainman->ActiveChain()));
+ if (m_context->chainman->ActiveChain().Tip()) {
+ return m_context->chainman->ActiveChain().Tip()->GetBlockTime();
}
return Params().GenesisBlock().GetBlockTime(); // Genesis block's time of current network
}
@@ -202,11 +205,15 @@ public:
const CBlockIndex* tip;
{
LOCK(::cs_main);
- tip = ::ChainActive().Tip();
+ assert(std::addressof(::ChainActive()) == std::addressof(m_context->chainman->ActiveChain()));
+ tip = m_context->chainman->ActiveChain().Tip();
}
return GuessVerificationProgress(Params().TxData(), tip);
}
- bool isInitialBlockDownload() override { return ::ChainstateActive().IsInitialBlockDownload(); }
+ bool isInitialBlockDownload() override {
+ assert(std::addressof(::ChainstateActive()) == std::addressof(m_context->chainman->ActiveChainstate()));
+ return m_context->chainman->ActiveChainstate().IsInitialBlockDownload();
+ }
bool getReindex() override { return ::fReindex; }
bool getImporting() override { return ::fImporting; }
void setNetworkActive(bool active) override
@@ -231,7 +238,8 @@ public:
bool getUnspentOutput(const COutPoint& output, Coin& coin) override
{
LOCK(::cs_main);
- return ::ChainstateActive().CoinsTip().GetCoin(output, coin);
+ assert(std::addressof(::ChainstateActive()) == std::addressof(m_context->chainman->ActiveChainstate()));
+ return m_context->chainman->ActiveChainstate().CoinsTip().GetCoin(output, coin);
}
WalletClient& walletClient() override
{
@@ -441,13 +449,15 @@ public:
bool checkFinalTx(const CTransaction& tx) override
{
LOCK(cs_main);
- return CheckFinalTx(::ChainActive().Tip(), tx);
+ assert(std::addressof(::ChainActive()) == std::addressof(m_node.chainman->ActiveChain()));
+ return CheckFinalTx(m_node.chainman->ActiveChain().Tip(), tx);
}
Optional<int> findLocatorFork(const CBlockLocator& locator) override
{
LOCK(cs_main);
const CChain& active = Assert(m_node.chainman)->ActiveChain();
- if (CBlockIndex* fork = g_chainman.m_blockman.FindForkInGlobalIndex(active, locator)) {
+ assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
+ if (CBlockIndex* fork = m_node.chainman->m_blockman.FindForkInGlobalIndex(active, locator)) {
return fork->nHeight;
}
return nullopt;
@@ -456,7 +466,8 @@ public:
{
WAIT_LOCK(cs_main, lock);
const CChain& active = Assert(m_node.chainman)->ActiveChain();
- return FillBlock(g_chainman.m_blockman.LookupBlockIndex(hash), block, lock, active);
+ assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
+ return FillBlock(m_node.chainman->m_blockman.LookupBlockIndex(hash), block, lock, active);
}
bool findFirstBlockWithTimeAndHeight(int64_t min_time, int min_height, const FoundBlock& block) override
{
@@ -468,7 +479,8 @@ public:
{
WAIT_LOCK(cs_main, lock);
const CChain& active = Assert(m_node.chainman)->ActiveChain();
- if (const CBlockIndex* block = g_chainman.m_blockman.LookupBlockIndex(block_hash)) {
+ assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
+ if (const CBlockIndex* block = m_node.chainman->m_blockman.LookupBlockIndex(block_hash)) {
if (const CBlockIndex* ancestor = block->GetAncestor(ancestor_height)) {
return FillBlock(ancestor, ancestor_out, lock, active);
}
@@ -479,8 +491,10 @@ public:
{
WAIT_LOCK(cs_main, lock);
const CChain& active = Assert(m_node.chainman)->ActiveChain();
- const CBlockIndex* block = g_chainman.m_blockman.LookupBlockIndex(block_hash);
- const CBlockIndex* ancestor = g_chainman.m_blockman.LookupBlockIndex(ancestor_hash);
+ assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
+ const CBlockIndex* block = m_node.chainman->m_blockman.LookupBlockIndex(block_hash);
+ assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
+ const CBlockIndex* ancestor = m_node.chainman->m_blockman.LookupBlockIndex(ancestor_hash);
if (block && ancestor && block->GetAncestor(ancestor->nHeight) != ancestor) ancestor = nullptr;
return FillBlock(ancestor, ancestor_out, lock, active);
}
@@ -488,8 +502,10 @@ public:
{
WAIT_LOCK(cs_main, lock);
const CChain& active = Assert(m_node.chainman)->ActiveChain();
- const CBlockIndex* block1 = g_chainman.m_blockman.LookupBlockIndex(block_hash1);
- const CBlockIndex* block2 = g_chainman.m_blockman.LookupBlockIndex(block_hash2);
+ assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
+ const CBlockIndex* block1 = m_node.chainman->m_blockman.LookupBlockIndex(block_hash1);
+ assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
+ const CBlockIndex* block2 = m_node.chainman->m_blockman.LookupBlockIndex(block_hash2);
const CBlockIndex* ancestor = block1 && block2 ? LastCommonAncestor(block1, block2) : nullptr;
// Using & instead of && below to avoid short circuiting and leaving
// output uninitialized.
@@ -499,7 +515,8 @@ public:
double guessVerificationProgress(const uint256& block_hash) override
{
LOCK(cs_main);
- return GuessVerificationProgress(Params().TxData(), g_chainman.m_blockman.LookupBlockIndex(block_hash));
+ assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
+ return GuessVerificationProgress(Params().TxData(), m_node.chainman->m_blockman.LookupBlockIndex(block_hash));
}
bool hasBlocks(const uint256& block_hash, int min_height, Optional<int> max_height) override
{
@@ -511,7 +528,8 @@ public:
// used to limit the range, and passing min_height that's too low or
// max_height that's too high will not crash or change the result.
LOCK(::cs_main);
- if (CBlockIndex* block = g_chainman.m_blockman.LookupBlockIndex(block_hash)) {
+ assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
+ if (CBlockIndex* block = m_node.chainman->m_blockman.LookupBlockIndex(block_hash)) {
if (max_height && block->nHeight >= *max_height) block = block->GetAncestor(*max_height);
for (; block->nStatus & BLOCK_HAVE_DATA; block = block->pprev) {
// Check pprev to not segfault if min_height is too low
@@ -526,6 +544,12 @@ public:
LOCK(m_node.mempool->cs);
return IsRBFOptIn(tx, *m_node.mempool);
}
+ bool isInMempool(const uint256& txid) override
+ {
+ if (!m_node.mempool) return false;
+ LOCK(m_node.mempool->cs);
+ return m_node.mempool->exists(txid);
+ }
bool hasDescendantsInMempool(const uint256& txid) override
{
if (!m_node.mempool) return false;
@@ -595,7 +619,10 @@ public:
return ::fHavePruned;
}
bool isReadyToBroadcast() override { return !::fImporting && !::fReindex && !isInitialBlockDownload(); }
- bool isInitialBlockDownload() override { return ::ChainstateActive().IsInitialBlockDownload(); }
+ bool isInitialBlockDownload() override {
+ assert(std::addressof(::ChainstateActive()) == std::addressof(m_node.chainman->ActiveChainstate()));
+ return m_node.chainman->ActiveChainstate().IsInitialBlockDownload();
+ }
bool shutdownRequested() override { return ShutdownRequested(); }
int64_t getAdjustedTime() override { return GetAdjustedTime(); }
void initMessage(const std::string& message) override { ::uiInterface.InitMessage(message); }
@@ -607,7 +634,7 @@ public:
}
std::unique_ptr<Handler> handleNotifications(std::shared_ptr<Notifications> notifications) override
{
- return MakeUnique<NotificationsHandlerImpl>(std::move(notifications));
+ return std::make_unique<NotificationsHandlerImpl>(std::move(notifications));
}
void waitForNotificationsIfTipChanged(const uint256& old_tip) override
{
@@ -620,7 +647,7 @@ public:
}
std::unique_ptr<Handler> handleRpc(const CRPCCommand& command) override
{
- return MakeUnique<RpcHandlerImpl>(command);
+ return std::make_unique<RpcHandlerImpl>(command);
}
bool rpcEnableDeprecated(const std::string& method) override { return IsDeprecatedRPCEnabled(method); }
void rpcRunLater(const std::string& name, std::function<void()> fn, int64_t seconds) override
@@ -663,6 +690,6 @@ public:
} // namespace node
namespace interfaces {
-std::unique_ptr<Node> MakeNode(NodeContext* context) { return MakeUnique<node::NodeImpl>(context); }
-std::unique_ptr<Chain> MakeChain(NodeContext& context) { return MakeUnique<node::ChainImpl>(context); }
+std::unique_ptr<Node> MakeNode(NodeContext* context) { return std::make_unique<node::NodeImpl>(context); }
+std::unique_ptr<Chain> MakeChain(NodeContext& context) { return std::make_unique<node::ChainImpl>(context); }
} // namespace interfaces
diff --git a/src/node/transaction.cpp b/src/node/transaction.cpp
index 3b3fab7b6b..97763f4fa2 100644
--- a/src/node/transaction.cpp
+++ b/src/node/transaction.cpp
@@ -39,9 +39,10 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t
{ // cs_main scope
LOCK(cs_main);
+ assert(std::addressof(::ChainstateActive()) == std::addressof(node.chainman->ActiveChainstate()));
// If the transaction is already confirmed in the chain, don't do anything
// and return early.
- CCoinsViewCache &view = ::ChainstateActive().CoinsTip();
+ CCoinsViewCache &view = node.chainman->ActiveChainstate().CoinsTip();
for (size_t o = 0; o < tx->vout.size(); o++) {
const Coin& existingCoin = view.AccessCoin(COutPoint(hashTx, o));
// IsSpent doesn't mean the coin is spent, it means the output doesn't exist.
@@ -53,7 +54,7 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t
if (max_tx_fee > 0) {
// First, call ATMP with test_accept and check the fee. If ATMP
// fails here, return error immediately.
- const MempoolAcceptResult result = AcceptToMemoryPool(::ChainstateActive(), *node.mempool, tx, false /* bypass_limits */,
+ const MempoolAcceptResult result = AcceptToMemoryPool(node.chainman->ActiveChainstate(), *node.mempool, tx, false /* bypass_limits */,
true /* test_accept */);
if (result.m_result_type != MempoolAcceptResult::ResultType::VALID) {
return HandleATMPError(result.m_state, err_string);
@@ -62,7 +63,7 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t
}
}
// Try to submit the transaction to the mempool.
- const MempoolAcceptResult result = AcceptToMemoryPool(::ChainstateActive(), *node.mempool, tx, false /* bypass_limits */,
+ const MempoolAcceptResult result = AcceptToMemoryPool(node.chainman->ActiveChainstate(), *node.mempool, tx, false /* bypass_limits */,
false /* test_accept */);
if (result.m_result_type != MempoolAcceptResult::ResultType::VALID) {
return HandleATMPError(result.m_state, err_string);
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index ef2f56c2c0..f25b415820 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -62,6 +62,7 @@ Q_IMPORT_PLUGIN(QXcbIntegrationPlugin);
Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);
#elif defined(QT_QPA_PLATFORM_COCOA)
Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin);
+Q_IMPORT_PLUGIN(QMacStylePlugin);
#endif
#endif
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index 89d6deb70d..32890ed0fe 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -683,13 +683,13 @@ QString formatDurationStr(int secs)
int seconds = secs % 60;
if (days)
- strList.append(QString(QObject::tr("%1 d")).arg(days));
+ strList.append(QObject::tr("%1 d").arg(days));
if (hours)
- strList.append(QString(QObject::tr("%1 h")).arg(hours));
+ strList.append(QObject::tr("%1 h").arg(hours));
if (mins)
- strList.append(QString(QObject::tr("%1 m")).arg(mins));
+ strList.append(QObject::tr("%1 m").arg(mins));
if (seconds || (!days && !hours && !mins))
- strList.append(QString(QObject::tr("%1 s")).arg(seconds));
+ strList.append(QObject::tr("%1 s").arg(seconds));
return strList.join(" ");
}
@@ -712,12 +712,12 @@ QString formatPingTime(std::chrono::microseconds ping_time)
{
return (ping_time == std::chrono::microseconds::max() || ping_time == 0us) ?
QObject::tr("N/A") :
- QString(QObject::tr("%1 ms")).arg(QString::number((int)(count_microseconds(ping_time) / 1000), 10));
+ QObject::tr("%1 ms").arg(QString::number((int)(count_microseconds(ping_time) / 1000), 10));
}
QString formatTimeOffset(int64_t nTimeOffset)
{
- return QString(QObject::tr("%1 s")).arg(QString::number((int)nTimeOffset, 10));
+ return QObject::tr("%1 s").arg(QString::number((int)nTimeOffset, 10));
}
QString formatNiceTimeOffset(qint64 secs)
@@ -760,13 +760,13 @@ QString formatNiceTimeOffset(qint64 secs)
QString formatBytes(uint64_t bytes)
{
if(bytes < 1024)
- return QString(QObject::tr("%1 B")).arg(bytes);
+ return QObject::tr("%1 B").arg(bytes);
if(bytes < 1024 * 1024)
- return QString(QObject::tr("%1 KB")).arg(bytes / 1024);
+ return QObject::tr("%1 KB").arg(bytes / 1024);
if(bytes < 1024 * 1024 * 1024)
- return QString(QObject::tr("%1 MB")).arg(bytes / 1024 / 1024);
+ return QObject::tr("%1 MB").arg(bytes / 1024 / 1024);
- return QString(QObject::tr("%1 GB")).arg(bytes / 1024 / 1024 / 1024);
+ return QObject::tr("%1 GB").arg(bytes / 1024 / 1024 / 1024);
}
qreal calculateIdealFontSize(int width, const QString& text, QFont font, qreal minPointSize, qreal font_size) {
diff --git a/src/qt/psbtoperationsdialog.cpp b/src/qt/psbtoperationsdialog.cpp
index 55ab6046cf..d1f8d56100 100644
--- a/src/qt/psbtoperationsdialog.cpp
+++ b/src/qt/psbtoperationsdialog.cpp
@@ -145,7 +145,7 @@ void PSBTOperationsDialog::saveTransaction() {
if (filename.isEmpty()) {
return;
}
- std::ofstream out(filename.toLocal8Bit().data());
+ std::ofstream out(filename.toLocal8Bit().data(), std::ofstream::out | std::ofstream::binary);
out << ssTx.str();
out.close();
showStatus(tr("PSBT saved to disk."), StatusLevel::INFO);
diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp
index 0da12c84fd..61cb89d75a 100644
--- a/src/qt/receivecoinsdialog.cpp
+++ b/src/qt/receivecoinsdialog.cpp
@@ -81,7 +81,6 @@ ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *_platformStyle, QWid
tableView->horizontalHeader()->setMinimumSectionSize(MINIMUM_COLUMN_WIDTH);
tableView->horizontalHeader()->setStretchLastSection(true);
}
- tableView->horizontalHeader()->setSortIndicator(RecentRequestsTableModel::Date, Qt::DescendingOrder);
}
void ReceiveCoinsDialog::setModel(WalletModel *_model)
@@ -96,6 +95,8 @@ void ReceiveCoinsDialog::setModel(WalletModel *_model)
QTableView* tableView = ui->recentRequestsView;
tableView->setModel(_model->getRecentRequestsTableModel());
+ tableView->sortByColumn(RecentRequestsTableModel::Date, Qt::DescendingOrder);
+
connect(tableView->selectionModel(),
&QItemSelectionModel::selectionChanged, this,
&ReceiveCoinsDialog::recentRequestsView_selectionChanged);
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index 611f3584c3..e401f46696 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -266,7 +266,7 @@ bool SendCoinsDialog::PrepareSendText(QString& question_string, QString& informa
}
// prepare transaction for getting txFee earlier
- m_current_transaction = MakeUnique<WalletModelTransaction>(recipients);
+ m_current_transaction = std::make_unique<WalletModelTransaction>(recipients);
WalletModel::SendCoinsReturn prepareStatus;
updateCoinControlState(*m_coin_control);
@@ -434,7 +434,7 @@ void SendCoinsDialog::on_sendButton_clicked()
if (filename.isEmpty()) {
return;
}
- std::ofstream out(filename.toLocal8Bit().data());
+ std::ofstream out(filename.toLocal8Bit().data(), std::ofstream::out | std::ofstream::binary);
out << ssTx.str();
out.close();
Q_EMIT message(tr("PSBT saved"), "PSBT saved to disk", CClientUIInterface::MSG_INFORMATION);
diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp
index e1ec7b6ed0..f99a3e286d 100644
--- a/src/qt/transactionview.cpp
+++ b/src/qt/transactionview.cpp
@@ -160,7 +160,6 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa
transactionView->horizontalHeader()->setMinimumSectionSize(MINIMUM_COLUMN_WIDTH);
transactionView->horizontalHeader()->setStretchLastSection(true);
}
- transactionView->horizontalHeader()->setSortIndicator(TransactionTableModel::Date, Qt::DescendingOrder);
// Actions
abandonAction = new QAction(tr("Abandon transaction"), this);
@@ -236,6 +235,7 @@ void TransactionView::setModel(WalletModel *_model)
transactionProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
transactionProxyModel->setSortRole(Qt::EditRole);
transactionView->setModel(transactionProxyModel);
+ transactionView->sortByColumn(TransactionTableModel::Date, Qt::DescendingOrder);
if (_model->getOptionsModel())
{
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index ab0c0b8385..b90dc9bf42 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -1073,9 +1073,9 @@ static RPCHelpMan gettxoutsetinfo()
const CoinStatsHashType hash_type{request.params[0].isNull() ? CoinStatsHashType::HASH_SERIALIZED : ParseHashType(request.params[0].get_str())};
- CCoinsView* coins_view = WITH_LOCK(cs_main, return &ChainstateActive().CoinsDB());
+ CCoinsView* coins_view = WITH_LOCK(::cs_main, return &::ChainstateActive().CoinsDB());
NodeContext& node = EnsureNodeContext(request.context);
- if (GetUTXOStats(coins_view, stats, hash_type, node.rpc_interruption_point)) {
+ if (GetUTXOStats(coins_view, WITH_LOCK(::cs_main, return std::ref(g_chainman.m_blockman)), stats, hash_type, node.rpc_interruption_point)) {
ret.pushKV("height", (int64_t)stats.nHeight);
ret.pushKV("bestblock", stats.hashBlock.GetHex());
ret.pushKV("transactions", (int64_t)stats.nTransactions);
@@ -1100,30 +1100,29 @@ static RPCHelpMan gettxoutsetinfo()
static RPCHelpMan gettxout()
{
return RPCHelpMan{"gettxout",
- "\nReturns details about an unspent transaction output.\n",
- {
- {"txid", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction id"},
- {"n", RPCArg::Type::NUM, RPCArg::Optional::NO, "vout number"},
- {"include_mempool", RPCArg::Type::BOOL, /* default */ "true", "Whether to include the mempool. Note that an unspent output that is spent in the mempool won't appear."},
- },
- RPCResult{
- RPCResult::Type::OBJ, "", "",
- {
- {RPCResult::Type::STR_HEX, "bestblock", "The hash of the block at the tip of the chain"},
- {RPCResult::Type::NUM, "confirmations", "The number of confirmations"},
- {RPCResult::Type::STR_AMOUNT, "value", "The transaction value in " + CURRENCY_UNIT},
- {RPCResult::Type::OBJ, "scriptPubKey", "",
- {
- {RPCResult::Type::STR_HEX, "asm", ""},
- {RPCResult::Type::STR_HEX, "hex", ""},
- {RPCResult::Type::NUM, "reqSigs", "Number of required signatures"},
- {RPCResult::Type::STR_HEX, "type", "The type, eg pubkeyhash"},
- {RPCResult::Type::ARR, "addresses", "array of bitcoin addresses",
- {{RPCResult::Type::STR, "address", "bitcoin address"}}},
- }},
- {RPCResult::Type::BOOL, "coinbase", "Coinbase or not"},
- }},
- RPCExamples{
+ "\nReturns details about an unspent transaction output.\n",
+ {
+ {"txid", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction id"},
+ {"n", RPCArg::Type::NUM, RPCArg::Optional::NO, "vout number"},
+ {"include_mempool", RPCArg::Type::BOOL, /* default */ "true", "Whether to include the mempool. Note that an unspent output that is spent in the mempool won't appear."},
+ },
+ {
+ RPCResult{"If the UTXO was not found", RPCResult::Type::NONE, "", ""},
+ RPCResult{"Otherwise", RPCResult::Type::OBJ, "", "", {
+ {RPCResult::Type::STR_HEX, "bestblock", "The hash of the block at the tip of the chain"},
+ {RPCResult::Type::NUM, "confirmations", "The number of confirmations"},
+ {RPCResult::Type::STR_AMOUNT, "value", "The transaction value in " + CURRENCY_UNIT},
+ {RPCResult::Type::OBJ, "scriptPubKey", "", {
+ {RPCResult::Type::STR_HEX, "asm", ""},
+ {RPCResult::Type::STR_HEX, "hex", ""},
+ {RPCResult::Type::NUM, "reqSigs", "Number of required signatures"},
+ {RPCResult::Type::STR_HEX, "type", "The type, eg pubkeyhash"},
+ {RPCResult::Type::ARR, "addresses", "array of bitcoin addresses", {{RPCResult::Type::STR, "address", "bitcoin address"}}},
+ }},
+ {RPCResult::Type::BOOL, "coinbase", "Coinbase or not"},
+ }},
+ },
+ RPCExamples{
"\nGet unspent transactions\n"
+ HelpExampleCli("listunspent", "") +
"\nView the details\n"
@@ -2137,59 +2136,63 @@ public:
static RPCHelpMan scantxoutset()
{
return RPCHelpMan{"scantxoutset",
- "\nEXPERIMENTAL warning: this call may be removed or changed in future releases.\n"
- "\nScans the unspent transaction output set for entries that match certain output descriptors.\n"
- "Examples of output descriptors are:\n"
- " addr(<address>) Outputs whose scriptPubKey corresponds to the specified address (does not include P2PK)\n"
- " raw(<hex script>) Outputs whose scriptPubKey equals the specified hex scripts\n"
- " combo(<pubkey>) P2PK, P2PKH, P2WPKH, and P2SH-P2WPKH outputs for the given pubkey\n"
- " pkh(<pubkey>) P2PKH outputs for the given pubkey\n"
- " sh(multi(<n>,<pubkey>,<pubkey>,...)) P2SH-multisig outputs for the given threshold and pubkeys\n"
- "\nIn the above, <pubkey> either refers to a fixed public key in hexadecimal notation, or to an xpub/xprv optionally followed by one\n"
- "or more path elements separated by \"/\", and optionally ending in \"/*\" (unhardened), or \"/*'\" or \"/*h\" (hardened) to specify all\n"
- "unhardened or hardened child keys.\n"
- "In the latter case, a range needs to be specified by below if different from 1000.\n"
- "For more information on output descriptors, see the documentation in the doc/descriptors.md file.\n",
+ "\nScans the unspent transaction output set for entries that match certain output descriptors.\n"
+ "Examples of output descriptors are:\n"
+ " addr(<address>) Outputs whose scriptPubKey corresponds to the specified address (does not include P2PK)\n"
+ " raw(<hex script>) Outputs whose scriptPubKey equals the specified hex scripts\n"
+ " combo(<pubkey>) P2PK, P2PKH, P2WPKH, and P2SH-P2WPKH outputs for the given pubkey\n"
+ " pkh(<pubkey>) P2PKH outputs for the given pubkey\n"
+ " sh(multi(<n>,<pubkey>,<pubkey>,...)) P2SH-multisig outputs for the given threshold and pubkeys\n"
+ "\nIn the above, <pubkey> either refers to a fixed public key in hexadecimal notation, or to an xpub/xprv optionally followed by one\n"
+ "or more path elements separated by \"/\", and optionally ending in \"/*\" (unhardened), or \"/*'\" or \"/*h\" (hardened) to specify all\n"
+ "unhardened or hardened child keys.\n"
+ "In the latter case, a range needs to be specified by below if different from 1000.\n"
+ "For more information on output descriptors, see the documentation in the doc/descriptors.md file.\n",
+ {
+ {"action", RPCArg::Type::STR, RPCArg::Optional::NO, "The action to execute\n"
+ "\"start\" for starting a scan\n"
+ "\"abort\" for aborting the current scan (returns true when abort was successful)\n"
+ "\"status\" for progress report (in %) of the current scan"},
+ {"scanobjects", RPCArg::Type::ARR, RPCArg::Optional::OMITTED, "Array of scan objects. Required for \"start\" action\n"
+ "Every scan object is either a string descriptor or an object:",
+ {
+ {"descriptor", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "An output descriptor"},
+ {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "An object with output descriptor and metadata",
{
- {"action", RPCArg::Type::STR, RPCArg::Optional::NO, "The action to execute\n"
- " \"start\" for starting a scan\n"
- " \"abort\" for aborting the current scan (returns true when abort was successful)\n"
- " \"status\" for progress report (in %) of the current scan"},
- {"scanobjects", RPCArg::Type::ARR, RPCArg::Optional::OMITTED, "Array of scan objects. Required for \"start\" action\n"
- " Every scan object is either a string descriptor or an object:",
- {
- {"descriptor", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "An output descriptor"},
- {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "An object with output descriptor and metadata",
- {
- {"desc", RPCArg::Type::STR, RPCArg::Optional::NO, "An output descriptor"},
- {"range", RPCArg::Type::RANGE, /* default */ "1000", "The range of HD chain indexes to explore (either end or [begin,end])"},
- },
- },
- },
+ {"desc", RPCArg::Type::STR, RPCArg::Optional::NO, "An output descriptor"},
+ {"range", RPCArg::Type::RANGE, /* default */ "1000", "The range of HD chain indexes to explore (either end or [begin,end])"},
+ }},
+ },
"[scanobjects,...]"},
- },
- RPCResult{
- RPCResult::Type::OBJ, "", "",
+ },
+ {
+ RPCResult{"When action=='abort'", RPCResult::Type::BOOL, "", ""},
+ RPCResult{"When action=='status' and no scan is in progress", RPCResult::Type::NONE, "", ""},
+ RPCResult{"When action=='status' and scan is in progress", RPCResult::Type::OBJ, "", "",
+ {
+ {RPCResult::Type::NUM, "progress", "The scan progress"},
+ }},
+ RPCResult{"When action=='start'", RPCResult::Type::OBJ, "", "", {
+ {RPCResult::Type::BOOL, "success", "Whether the scan was completed"},
+ {RPCResult::Type::NUM, "txouts", "The number of unspent transaction outputs scanned"},
+ {RPCResult::Type::NUM, "height", "The current block height (index)"},
+ {RPCResult::Type::STR_HEX, "bestblock", "The hash of the block at the tip of the chain"},
+ {RPCResult::Type::ARR, "unspents", "",
+ {
+ {RPCResult::Type::OBJ, "", "",
{
- {RPCResult::Type::BOOL, "success", "Whether the scan was completed"},
- {RPCResult::Type::NUM, "txouts", "The number of unspent transaction outputs scanned"},
- {RPCResult::Type::NUM, "height", "The current block height (index)"},
- {RPCResult::Type::STR_HEX, "bestblock", "The hash of the block at the tip of the chain"},
- {RPCResult::Type::ARR, "unspents", "",
- {
- {RPCResult::Type::OBJ, "", "",
- {
- {RPCResult::Type::STR_HEX, "txid", "The transaction id"},
- {RPCResult::Type::NUM, "vout", "The vout value"},
- {RPCResult::Type::STR_HEX, "scriptPubKey", "The script key"},
- {RPCResult::Type::STR, "desc", "A specialized descriptor for the matched scriptPubKey"},
- {RPCResult::Type::STR_AMOUNT, "amount", "The total amount in " + CURRENCY_UNIT + " of the unspent output"},
- {RPCResult::Type::NUM, "height", "Height of the unspent transaction output"},
- }},
- }},
- {RPCResult::Type::STR_AMOUNT, "total_amount", "The total amount of all found unspent outputs in " + CURRENCY_UNIT},
+ {RPCResult::Type::STR_HEX, "txid", "The transaction id"},
+ {RPCResult::Type::NUM, "vout", "The vout value"},
+ {RPCResult::Type::STR_HEX, "scriptPubKey", "The script key"},
+ {RPCResult::Type::STR, "desc", "A specialized descriptor for the matched scriptPubKey"},
+ {RPCResult::Type::STR_AMOUNT, "amount", "The total amount in " + CURRENCY_UNIT + " of the unspent output"},
+ {RPCResult::Type::NUM, "height", "Height of the unspent transaction output"},
}},
- RPCExamples{""},
+ }},
+ {RPCResult::Type::STR_AMOUNT, "total_amount", "The total amount of all found unspent outputs in " + CURRENCY_UNIT},
+ }},
+ },
+ RPCExamples{""},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR});
@@ -2444,7 +2447,7 @@ UniValue CreateUTXOSnapshot(NodeContext& node, CChainState& chainstate, CAutoFil
chainstate.ForceFlushStateToDisk();
- if (!GetUTXOStats(&chainstate.CoinsDB(), stats, CoinStatsHashType::NONE, node.rpc_interruption_point)) {
+ if (!GetUTXOStats(&chainstate.CoinsDB(), chainstate.m_blockman, stats, CoinStatsHashType::NONE, node.rpc_interruption_point)) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set");
}
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
index f29f556517..fd780ba782 100644
--- a/src/rpc/mining.cpp
+++ b/src/rpc/mining.cpp
@@ -150,7 +150,7 @@ static UniValue generateBlocks(ChainstateManager& chainman, const CTxMemPool& me
UniValue blockHashes(UniValue::VARR);
while (nHeight < nHeightEnd && !ShutdownRequested())
{
- std::unique_ptr<CBlockTemplate> pblocktemplate(BlockAssembler(mempool, Params()).CreateNewBlock(coinbase_script));
+ std::unique_ptr<CBlockTemplate> pblocktemplate(BlockAssembler(mempool, Params()).CreateNewBlock(::ChainstateActive(), coinbase_script));
if (!pblocktemplate.get())
throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block");
CBlock *pblock = &pblocktemplate->block;
@@ -358,7 +358,7 @@ static RPCHelpMan generateblock()
LOCK(cs_main);
CTxMemPool empty_mempool;
- std::unique_ptr<CBlockTemplate> blocktemplate(BlockAssembler(empty_mempool, chainparams).CreateNewBlock(coinbase_script));
+ std::unique_ptr<CBlockTemplate> blocktemplate(BlockAssembler(empty_mempool, chainparams).CreateNewBlock(::ChainstateActive(), coinbase_script));
if (!blocktemplate) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block");
}
@@ -369,7 +369,7 @@ static RPCHelpMan generateblock()
// Add transactions
block.vtx.insert(block.vtx.end(), txs.begin(), txs.end());
- RegenerateCommitments(block);
+ RegenerateCommitments(block, WITH_LOCK(::cs_main, return std::ref(g_chainman.m_blockman)));
{
LOCK(cs_main);
@@ -505,83 +505,84 @@ static std::string gbt_vb_name(const Consensus::DeploymentPos pos) {
static RPCHelpMan getblocktemplate()
{
return RPCHelpMan{"getblocktemplate",
- "\nIf the request parameters include a 'mode' key, that is used to explicitly select between the default 'template' request or a 'proposal'.\n"
- "It returns data needed to construct a block to work on.\n"
- "For full specification, see BIPs 22, 23, 9, and 145:\n"
- " https://github.com/bitcoin/bips/blob/master/bip-0022.mediawiki\n"
- " https://github.com/bitcoin/bips/blob/master/bip-0023.mediawiki\n"
- " https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki#getblocktemplate_changes\n"
- " https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki\n",
+ "\nIf the request parameters include a 'mode' key, that is used to explicitly select between the default 'template' request or a 'proposal'.\n"
+ "It returns data needed to construct a block to work on.\n"
+ "For full specification, see BIPs 22, 23, 9, and 145:\n"
+ " https://github.com/bitcoin/bips/blob/master/bip-0022.mediawiki\n"
+ " https://github.com/bitcoin/bips/blob/master/bip-0023.mediawiki\n"
+ " https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki#getblocktemplate_changes\n"
+ " https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki\n",
+ {
+ {"template_request", RPCArg::Type::OBJ, "{}", "Format of the template",
+ {
+ {"mode", RPCArg::Type::STR, /* treat as named arg */ RPCArg::Optional::OMITTED_NAMED_ARG, "This must be set to \"template\", \"proposal\" (see BIP 23), or omitted"},
+ {"capabilities", RPCArg::Type::ARR, /* treat as named arg */ RPCArg::Optional::OMITTED_NAMED_ARG, "A list of strings",
{
- {"template_request", RPCArg::Type::OBJ, "{}", "Format of the template",
- {
- {"mode", RPCArg::Type::STR, /* treat as named arg */ RPCArg::Optional::OMITTED_NAMED_ARG, "This must be set to \"template\", \"proposal\" (see BIP 23), or omitted"},
- {"capabilities", RPCArg::Type::ARR, /* treat as named arg */ RPCArg::Optional::OMITTED_NAMED_ARG, "A list of strings",
- {
- {"str", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "client side supported feature, 'longpoll', 'coinbasevalue', 'proposal', 'serverlist', 'workid'"},
- },
- },
- {"rules", RPCArg::Type::ARR, RPCArg::Optional::NO, "A list of strings",
- {
- {"segwit", RPCArg::Type::STR, RPCArg::Optional::NO, "(literal) indicates client side segwit support"},
- {"str", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "other client side supported softfork deployment"},
- },
- },
- },
+ {"str", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "client side supported feature, 'longpoll', 'coinbasevalue', 'proposal', 'serverlist', 'workid'"},
+ }},
+ {"rules", RPCArg::Type::ARR, RPCArg::Optional::NO, "A list of strings",
+ {
+ {"segwit", RPCArg::Type::STR, RPCArg::Optional::NO, "(literal) indicates client side segwit support"},
+ {"str", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "other client side supported softfork deployment"},
+ }},
+ },
"\"template_request\""},
- },
- RPCResult{
- RPCResult::Type::OBJ, "", "",
+ },
+ {
+ RPCResult{"If the proposal was accepted with mode=='proposal'", RPCResult::Type::NONE, "", ""},
+ RPCResult{"If the proposal was not accepted with mode=='proposal'", RPCResult::Type::STR, "", "According to BIP22"},
+ RPCResult{"Otherwise", RPCResult::Type::OBJ, "", "",
+ {
+ {RPCResult::Type::NUM, "version", "The preferred block version"},
+ {RPCResult::Type::ARR, "rules", "specific block rules that are to be enforced",
+ {
+ {RPCResult::Type::STR, "", "name of a rule the client must understand to some extent; see BIP 9 for format"},
+ }},
+ {RPCResult::Type::OBJ_DYN, "vbavailable", "set of pending, supported versionbit (BIP 9) softfork deployments",
+ {
+ {RPCResult::Type::NUM, "rulename", "identifies the bit number as indicating acceptance and readiness for the named softfork rule"},
+ }},
+ {RPCResult::Type::NUM, "vbrequired", "bit mask of versionbits the server requires set in submissions"},
+ {RPCResult::Type::STR, "previousblockhash", "The hash of current highest block"},
+ {RPCResult::Type::ARR, "transactions", "contents of non-coinbase transactions that should be included in the next block",
+ {
+ {RPCResult::Type::OBJ, "", "",
{
- {RPCResult::Type::NUM, "version", "The preferred block version"},
- {RPCResult::Type::ARR, "rules", "specific block rules that are to be enforced",
- {
- {RPCResult::Type::STR, "", "name of a rule the client must understand to some extent; see BIP 9 for format"},
- }},
- {RPCResult::Type::OBJ_DYN, "vbavailable", "set of pending, supported versionbit (BIP 9) softfork deployments",
- {
- {RPCResult::Type::NUM, "rulename", "identifies the bit number as indicating acceptance and readiness for the named softfork rule"},
- }},
- {RPCResult::Type::NUM, "vbrequired", "bit mask of versionbits the server requires set in submissions"},
- {RPCResult::Type::STR, "previousblockhash", "The hash of current highest block"},
- {RPCResult::Type::ARR, "transactions", "contents of non-coinbase transactions that should be included in the next block",
- {
- {RPCResult::Type::OBJ, "", "",
- {
- {RPCResult::Type::STR_HEX, "data", "transaction data encoded in hexadecimal (byte-for-byte)"},
- {RPCResult::Type::STR_HEX, "txid", "transaction id encoded in little-endian hexadecimal"},
- {RPCResult::Type::STR_HEX, "hash", "hash encoded in little-endian hexadecimal (including witness data)"},
- {RPCResult::Type::ARR, "depends", "array of numbers",
- {
- {RPCResult::Type::NUM, "", "transactions before this one (by 1-based index in 'transactions' list) that must be present in the final block if this one is"},
- }},
- {RPCResult::Type::NUM, "fee", "difference in value between transaction inputs and outputs (in satoshis); for coinbase transactions, this is a negative Number of the total collected block fees (ie, not including the block subsidy); if key is not present, fee is unknown and clients MUST NOT assume there isn't one"},
- {RPCResult::Type::NUM, "sigops", "total SigOps cost, as counted for purposes of block limits; if key is not present, sigop cost is unknown and clients MUST NOT assume it is zero"},
- {RPCResult::Type::NUM, "weight", "total transaction weight, as counted for purposes of block limits"},
- }},
- }},
- {RPCResult::Type::OBJ_DYN, "coinbaseaux", "data that should be included in the coinbase's scriptSig content",
+ {RPCResult::Type::STR_HEX, "data", "transaction data encoded in hexadecimal (byte-for-byte)"},
+ {RPCResult::Type::STR_HEX, "txid", "transaction id encoded in little-endian hexadecimal"},
+ {RPCResult::Type::STR_HEX, "hash", "hash encoded in little-endian hexadecimal (including witness data)"},
+ {RPCResult::Type::ARR, "depends", "array of numbers",
{
- {RPCResult::Type::STR_HEX, "key", "values must be in the coinbase (keys may be ignored)"},
+ {RPCResult::Type::NUM, "", "transactions before this one (by 1-based index in 'transactions' list) that must be present in the final block if this one is"},
}},
- {RPCResult::Type::NUM, "coinbasevalue", "maximum allowable input to coinbase transaction, including the generation award and transaction fees (in satoshis)"},
- {RPCResult::Type::STR, "longpollid", "an id to include with a request to longpoll on an update to this template"},
- {RPCResult::Type::STR, "target", "The hash target"},
- {RPCResult::Type::NUM_TIME, "mintime", "The minimum timestamp appropriate for the next block time, expressed in " + UNIX_EPOCH_TIME},
- {RPCResult::Type::ARR, "mutable", "list of ways the block template may be changed",
- {
- {RPCResult::Type::STR, "value", "A way the block template may be changed, e.g. 'time', 'transactions', 'prevblock'"},
- }},
- {RPCResult::Type::STR_HEX, "noncerange", "A range of valid nonces"},
- {RPCResult::Type::NUM, "sigoplimit", "limit of sigops in blocks"},
- {RPCResult::Type::NUM, "sizelimit", "limit of block size"},
- {RPCResult::Type::NUM, "weightlimit", "limit of block weight"},
- {RPCResult::Type::NUM_TIME, "curtime", "current timestamp in " + UNIX_EPOCH_TIME},
- {RPCResult::Type::STR, "bits", "compressed target of next block"},
- {RPCResult::Type::NUM, "height", "The height of the next block"},
- {RPCResult::Type::STR, "default_witness_commitment", /* optional */ true, "a valid witness commitment for the unmodified block template"}
+ {RPCResult::Type::NUM, "fee", "difference in value between transaction inputs and outputs (in satoshis); for coinbase transactions, this is a negative Number of the total collected block fees (ie, not including the block subsidy); if key is not present, fee is unknown and clients MUST NOT assume there isn't one"},
+ {RPCResult::Type::NUM, "sigops", "total SigOps cost, as counted for purposes of block limits; if key is not present, sigop cost is unknown and clients MUST NOT assume it is zero"},
+ {RPCResult::Type::NUM, "weight", "total transaction weight, as counted for purposes of block limits"},
}},
- RPCExamples{
+ }},
+ {RPCResult::Type::OBJ_DYN, "coinbaseaux", "data that should be included in the coinbase's scriptSig content",
+ {
+ {RPCResult::Type::STR_HEX, "key", "values must be in the coinbase (keys may be ignored)"},
+ }},
+ {RPCResult::Type::NUM, "coinbasevalue", "maximum allowable input to coinbase transaction, including the generation award and transaction fees (in satoshis)"},
+ {RPCResult::Type::STR, "longpollid", "an id to include with a request to longpoll on an update to this template"},
+ {RPCResult::Type::STR, "target", "The hash target"},
+ {RPCResult::Type::NUM_TIME, "mintime", "The minimum timestamp appropriate for the next block time, expressed in " + UNIX_EPOCH_TIME},
+ {RPCResult::Type::ARR, "mutable", "list of ways the block template may be changed",
+ {
+ {RPCResult::Type::STR, "value", "A way the block template may be changed, e.g. 'time', 'transactions', 'prevblock'"},
+ }},
+ {RPCResult::Type::STR_HEX, "noncerange", "A range of valid nonces"},
+ {RPCResult::Type::NUM, "sigoplimit", "limit of sigops in blocks"},
+ {RPCResult::Type::NUM, "sizelimit", "limit of block size"},
+ {RPCResult::Type::NUM, "weightlimit", "limit of block weight"},
+ {RPCResult::Type::NUM_TIME, "curtime", "current timestamp in " + UNIX_EPOCH_TIME},
+ {RPCResult::Type::STR, "bits", "compressed target of next block"},
+ {RPCResult::Type::NUM, "height", "The height of the next block"},
+ {RPCResult::Type::STR, "default_witness_commitment", /* optional */ true, "a valid witness commitment for the unmodified block template"},
+ }},
+ },
+ RPCExamples{
HelpExampleCli("getblocktemplate", "'{\"rules\": [\"segwit\"]}'")
+ HelpExampleRpc("getblocktemplate", "{\"rules\": [\"segwit\"]}")
},
@@ -747,7 +748,7 @@ static RPCHelpMan getblocktemplate()
// Create new block
CScript scriptDummy = CScript() << OP_TRUE;
- pblocktemplate = BlockAssembler(mempool, Params()).CreateNewBlock(scriptDummy);
+ pblocktemplate = BlockAssembler(mempool, Params()).CreateNewBlock(::ChainstateActive(), scriptDummy);
if (!pblocktemplate)
throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
@@ -940,14 +941,17 @@ static RPCHelpMan submitblock()
{
// We allow 2 arguments for compliance with BIP22. Argument 2 is ignored.
return RPCHelpMan{"submitblock",
- "\nAttempts to submit new block to network.\n"
- "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n",
- {
- {"hexdata", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hex-encoded block data to submit"},
- {"dummy", RPCArg::Type::STR, /* default */ "ignored", "dummy value, for compatibility with BIP22. This value is ignored."},
- },
- RPCResult{RPCResult::Type::NONE, "", "Returns JSON Null when valid, a string according to BIP22 otherwise"},
- RPCExamples{
+ "\nAttempts to submit new block to network.\n"
+ "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n",
+ {
+ {"hexdata", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hex-encoded block data to submit"},
+ {"dummy", RPCArg::Type::STR, /* default */ "ignored", "dummy value, for compatibility with BIP22. This value is ignored."},
+ },
+ {
+ RPCResult{"If the block was accepted", RPCResult::Type::NONE, "", ""},
+ RPCResult{"Otherwise", RPCResult::Type::STR, "", "According to BIP22"},
+ },
+ RPCExamples{
HelpExampleCli("submitblock", "\"mydata\"")
+ HelpExampleRpc("submitblock", "\"mydata\"")
},
diff --git a/src/rpc/request.h b/src/rpc/request.h
index de3a4ae840..27d06f3c92 100644
--- a/src/rpc/request.h
+++ b/src/rpc/request.h
@@ -34,19 +34,19 @@ public:
UniValue id;
std::string strMethod;
UniValue params;
- bool fHelp;
+ enum Mode { EXECUTE, GET_HELP, GET_ARGS } mode = EXECUTE;
std::string URI;
std::string authUser;
std::string peerAddr;
const util::Ref& context;
- explicit JSONRPCRequest(const util::Ref& context) : id(NullUniValue), params(NullUniValue), fHelp(false), context(context) {}
+ explicit JSONRPCRequest(const util::Ref& context) : id(NullUniValue), params(NullUniValue), context(context) {}
//! Initializes request information from another request object and the
//! given context. The implementation should be updated if any members are
//! added or removed above.
JSONRPCRequest(const JSONRPCRequest& other, const util::Ref& context)
- : id(other.id), strMethod(other.strMethod), params(other.params), fHelp(other.fHelp), URI(other.URI),
+ : id(other.id), strMethod(other.strMethod), params(other.params), mode(other.mode), URI(other.URI),
authUser(other.authUser), peerAddr(other.peerAddr), context(context)
{
}
diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp
index 9a9b3713f3..39938f4eb9 100644
--- a/src/rpc/server.cpp
+++ b/src/rpc/server.cpp
@@ -88,7 +88,7 @@ std::string CRPCTable::help(const std::string& strCommand, const JSONRPCRequest&
sort(vCommands.begin(), vCommands.end());
JSONRPCRequest jreq(helpreq);
- jreq.fHelp = true;
+ jreq.mode = JSONRPCRequest::GET_HELP;
jreq.params = UniValue();
for (const std::pair<std::string, const CRPCCommand*>& command : vCommands)
@@ -149,7 +149,7 @@ static RPCHelpMan help()
}
if (strCommand == "dump_all_command_conversions") {
// Used for testing only, undocumented
- return tableRPC.dumpArgMap();
+ return tableRPC.dumpArgMap(jsonRequest);
}
return tableRPC.help(strCommand, jsonRequest);
@@ -437,6 +437,16 @@ static inline JSONRPCRequest transformNamedArguments(const JSONRPCRequest& in, c
return out;
}
+static bool ExecuteCommands(const std::vector<const CRPCCommand*>& commands, const JSONRPCRequest& request, UniValue& result)
+{
+ for (const auto& command : commands) {
+ if (ExecuteCommand(*command, request, result, &command == &commands.back())) {
+ return true;
+ }
+ }
+ return false;
+}
+
UniValue CRPCTable::execute(const JSONRPCRequest &request) const
{
// Return immediately if in warmup
@@ -450,10 +460,8 @@ UniValue CRPCTable::execute(const JSONRPCRequest &request) const
auto it = mapCommands.find(request.strMethod);
if (it != mapCommands.end()) {
UniValue result;
- for (const auto& command : it->second) {
- if (ExecuteCommand(*command, request, result, &command == &it->second.back())) {
- return result;
- }
+ if (ExecuteCommands(it->second, request, result)) {
+ return result;
}
}
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found");
@@ -484,13 +492,18 @@ std::vector<std::string> CRPCTable::listCommands() const
return commandList;
}
-UniValue CRPCTable::dumpArgMap() const
+UniValue CRPCTable::dumpArgMap(const JSONRPCRequest& args_request) const
{
+ JSONRPCRequest request(args_request);
+ request.mode = JSONRPCRequest::GET_ARGS;
+
UniValue ret{UniValue::VARR};
for (const auto& cmd : mapCommands) {
- for (const auto& c : cmd.second) {
- const auto help = RpcMethodFnType(c->unique_id)();
- help.AppendArgMap(ret);
+ UniValue result;
+ if (ExecuteCommands(cmd.second, request, result)) {
+ for (const auto& values : result.getValues()) {
+ ret.push_back(values);
+ }
}
}
return ret;
diff --git a/src/rpc/server.h b/src/rpc/server.h
index fe5a791e1e..03967020c2 100644
--- a/src/rpc/server.h
+++ b/src/rpc/server.h
@@ -148,7 +148,7 @@ public:
/**
* Return all named arguments that need to be converted by the client from string to another JSON type
*/
- UniValue dumpArgMap() const;
+ UniValue dumpArgMap(const JSONRPCRequest& request) const;
/**
* Appends a CRPCCommand to the dispatch table.
diff --git a/src/rpc/util.cpp b/src/rpc/util.cpp
index e890c0108a..44e58cb75f 100644
--- a/src/rpc/util.cpp
+++ b/src/rpc/util.cpp
@@ -459,6 +459,21 @@ std::string RPCExamples::ToDescriptionString() const
return m_examples.empty() ? m_examples : "\nExamples:\n" + m_examples;
}
+UniValue RPCHelpMan::HandleRequest(const JSONRPCRequest& request)
+{
+ if (request.mode == JSONRPCRequest::GET_ARGS) {
+ return GetArgMap();
+ }
+ /*
+ * Check if the given request is valid according to this command or if
+ * the user is asking for help information, and throw help when appropriate.
+ */
+ if (request.mode == JSONRPCRequest::GET_HELP || !IsValidNumArgs(request.params.size())) {
+ throw std::runtime_error(ToString());
+ }
+ return m_fun(*this, request);
+}
+
bool RPCHelpMan::IsValidNumArgs(size_t num_args) const
{
size_t num_required_args = 0;
@@ -532,8 +547,9 @@ std::string RPCHelpMan::ToString() const
return ret;
}
-void RPCHelpMan::AppendArgMap(UniValue& arr) const
+UniValue RPCHelpMan::GetArgMap() const
{
+ UniValue arr{UniValue::VARR};
for (int i{0}; i < int(m_args.size()); ++i) {
const auto& arg = m_args.at(i);
std::vector<std::string> arg_names;
@@ -548,6 +564,7 @@ void RPCHelpMan::AppendArgMap(UniValue& arr) const
arr.push_back(map);
}
}
+ return arr;
}
std::string RPCArg::GetFirstName() const
diff --git a/src/rpc/util.h b/src/rpc/util.h
index c54ce85f60..94c2d2d626 100644
--- a/src/rpc/util.h
+++ b/src/rpc/util.h
@@ -333,26 +333,12 @@ public:
using RPCMethodImpl = std::function<UniValue(const RPCHelpMan&, const JSONRPCRequest&)>;
RPCHelpMan(std::string name, std::string description, std::vector<RPCArg> args, RPCResults results, RPCExamples examples, RPCMethodImpl fun);
+ UniValue HandleRequest(const JSONRPCRequest& request);
std::string ToString() const;
- /** Append the named args that need to be converted from string to another JSON type */
- void AppendArgMap(UniValue& arr) const;
- UniValue HandleRequest(const JSONRPCRequest& request)
- {
- Check(request);
- return m_fun(*this, request);
- }
+ /** Return the named args that need to be converted from string to another JSON type */
+ UniValue GetArgMap() const;
/** If the supplied number of args is neither too small nor too high */
bool IsValidNumArgs(size_t num_args) const;
- /**
- * Check if the given request is valid according to this command or if
- * the user is asking for help information, and throw help when appropriate.
- */
- inline void Check(const JSONRPCRequest& request) const {
- if (request.fHelp || !IsValidNumArgs(request.params.size())) {
- throw std::runtime_error(ToString());
- }
- }
-
std::vector<std::string> GetArgNames() const;
const std::string m_name;
diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp
index 6ab01882ac..889cb4f06e 100644
--- a/src/script/descriptor.cpp
+++ b/src/script/descriptor.cpp
@@ -853,7 +853,7 @@ std::unique_ptr<PubkeyProvider> ParsePubkeyInner(uint32_t key_exp_index, const S
CPubKey pubkey(data);
if (pubkey.IsFullyValid()) {
if (permit_uncompressed || pubkey.IsCompressed()) {
- return MakeUnique<ConstPubkeyProvider>(key_exp_index, pubkey);
+ return std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey);
} else {
error = "Uncompressed keys are not allowed";
return nullptr;
@@ -867,7 +867,7 @@ std::unique_ptr<PubkeyProvider> ParsePubkeyInner(uint32_t key_exp_index, const S
if (permit_uncompressed || key.IsCompressed()) {
CPubKey pubkey = key.GetPubKey();
out.keys.emplace(pubkey.GetID(), key);
- return MakeUnique<ConstPubkeyProvider>(key_exp_index, pubkey);
+ return std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey);
} else {
error = "Uncompressed keys are not allowed";
return nullptr;
@@ -894,7 +894,7 @@ std::unique_ptr<PubkeyProvider> ParsePubkeyInner(uint32_t key_exp_index, const S
extpubkey = extkey.Neuter();
out.keys.emplace(extpubkey.pubkey.GetID(), extkey.key);
}
- return MakeUnique<BIP32PubkeyProvider>(key_exp_index, extpubkey, std::move(path), type);
+ return std::make_unique<BIP32PubkeyProvider>(key_exp_index, extpubkey, std::move(path), type);
}
/** Parse a public key including origin information (if enabled). */
@@ -931,7 +931,7 @@ std::unique_ptr<PubkeyProvider> ParsePubkey(uint32_t key_exp_index, const Span<c
if (!ParseKeyPath(slash_split, info.path, error)) return nullptr;
auto provider = ParsePubkeyInner(key_exp_index, origin_split[1], permit_uncompressed, out, error);
if (!provider) return nullptr;
- return MakeUnique<OriginPubkeyProvider>(key_exp_index, std::move(info), std::move(provider));
+ return std::make_unique<OriginPubkeyProvider>(key_exp_index, std::move(info), std::move(provider));
}
/** Parse a script in a particular context. */
@@ -944,17 +944,17 @@ std::unique_ptr<DescriptorImpl> ParseScript(uint32_t key_exp_index, Span<const c
if (Func("pk", expr)) {
auto pubkey = ParsePubkey(key_exp_index, expr, ctx != ParseScriptContext::P2WSH, out, error);
if (!pubkey) return nullptr;
- return MakeUnique<PKDescriptor>(std::move(pubkey));
+ return std::make_unique<PKDescriptor>(std::move(pubkey));
}
if (Func("pkh", expr)) {
auto pubkey = ParsePubkey(key_exp_index, expr, ctx != ParseScriptContext::P2WSH, out, error);
if (!pubkey) return nullptr;
- return MakeUnique<PKHDescriptor>(std::move(pubkey));
+ return std::make_unique<PKHDescriptor>(std::move(pubkey));
}
if (ctx == ParseScriptContext::TOP && Func("combo", expr)) {
auto pubkey = ParsePubkey(key_exp_index, expr, true, out, error);
if (!pubkey) return nullptr;
- return MakeUnique<ComboDescriptor>(std::move(pubkey));
+ return std::make_unique<ComboDescriptor>(std::move(pubkey));
} else if (ctx != ParseScriptContext::TOP && Func("combo", expr)) {
error = "Cannot have combo in non-top level";
return nullptr;
@@ -1002,12 +1002,12 @@ std::unique_ptr<DescriptorImpl> ParseScript(uint32_t key_exp_index, Span<const c
return nullptr;
}
}
- return MakeUnique<MultisigDescriptor>(thres, std::move(providers), sorted_multi);
+ return std::make_unique<MultisigDescriptor>(thres, std::move(providers), sorted_multi);
}
if (ctx != ParseScriptContext::P2WSH && Func("wpkh", expr)) {
auto pubkey = ParsePubkey(key_exp_index, expr, false, out, error);
if (!pubkey) return nullptr;
- return MakeUnique<WPKHDescriptor>(std::move(pubkey));
+ return std::make_unique<WPKHDescriptor>(std::move(pubkey));
} else if (ctx == ParseScriptContext::P2WSH && Func("wpkh", expr)) {
error = "Cannot have wpkh within wsh";
return nullptr;
@@ -1015,7 +1015,7 @@ std::unique_ptr<DescriptorImpl> ParseScript(uint32_t key_exp_index, Span<const c
if (ctx == ParseScriptContext::TOP && Func("sh", expr)) {
auto desc = ParseScript(key_exp_index, expr, ParseScriptContext::P2SH, out, error);
if (!desc || expr.size()) return nullptr;
- return MakeUnique<SHDescriptor>(std::move(desc));
+ return std::make_unique<SHDescriptor>(std::move(desc));
} else if (ctx != ParseScriptContext::TOP && Func("sh", expr)) {
error = "Cannot have sh in non-top level";
return nullptr;
@@ -1023,7 +1023,7 @@ std::unique_ptr<DescriptorImpl> ParseScript(uint32_t key_exp_index, Span<const c
if (ctx != ParseScriptContext::P2WSH && Func("wsh", expr)) {
auto desc = ParseScript(key_exp_index, expr, ParseScriptContext::P2WSH, out, error);
if (!desc || expr.size()) return nullptr;
- return MakeUnique<WSHDescriptor>(std::move(desc));
+ return std::make_unique<WSHDescriptor>(std::move(desc));
} else if (ctx == ParseScriptContext::P2WSH && Func("wsh", expr)) {
error = "Cannot have wsh within wsh";
return nullptr;
@@ -1034,7 +1034,7 @@ std::unique_ptr<DescriptorImpl> ParseScript(uint32_t key_exp_index, Span<const c
error = "Address is not valid";
return nullptr;
}
- return MakeUnique<AddressDescriptor>(std::move(dest));
+ return std::make_unique<AddressDescriptor>(std::move(dest));
}
if (ctx == ParseScriptContext::TOP && Func("raw", expr)) {
std::string str(expr.begin(), expr.end());
@@ -1043,7 +1043,7 @@ std::unique_ptr<DescriptorImpl> ParseScript(uint32_t key_exp_index, Span<const c
return nullptr;
}
auto bytes = ParseHex(str);
- return MakeUnique<RawDescriptor>(CScript(bytes.begin(), bytes.end()));
+ return std::make_unique<RawDescriptor>(CScript(bytes.begin(), bytes.end()));
}
if (ctx == ParseScriptContext::P2SH) {
error = "A function is needed within P2SH";
@@ -1058,10 +1058,10 @@ std::unique_ptr<DescriptorImpl> ParseScript(uint32_t key_exp_index, Span<const c
std::unique_ptr<PubkeyProvider> InferPubkey(const CPubKey& pubkey, ParseScriptContext, const SigningProvider& provider)
{
- std::unique_ptr<PubkeyProvider> key_provider = MakeUnique<ConstPubkeyProvider>(0, pubkey);
+ std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey);
KeyOriginInfo info;
if (provider.GetKeyOrigin(pubkey.GetID(), info)) {
- return MakeUnique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider));
+ return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider));
}
return key_provider;
}
@@ -1074,7 +1074,7 @@ std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptCo
if (txntype == TxoutType::PUBKEY) {
CPubKey pubkey(data[0].begin(), data[0].end());
if (pubkey.IsValid()) {
- return MakeUnique<PKDescriptor>(InferPubkey(pubkey, ctx, provider));
+ return std::make_unique<PKDescriptor>(InferPubkey(pubkey, ctx, provider));
}
}
if (txntype == TxoutType::PUBKEYHASH) {
@@ -1082,7 +1082,7 @@ std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptCo
CKeyID keyid(hash);
CPubKey pubkey;
if (provider.GetPubKey(keyid, pubkey)) {
- return MakeUnique<PKHDescriptor>(InferPubkey(pubkey, ctx, provider));
+ return std::make_unique<PKHDescriptor>(InferPubkey(pubkey, ctx, provider));
}
}
if (txntype == TxoutType::WITNESS_V0_KEYHASH && ctx != ParseScriptContext::P2WSH) {
@@ -1090,7 +1090,7 @@ std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptCo
CKeyID keyid(hash);
CPubKey pubkey;
if (provider.GetPubKey(keyid, pubkey)) {
- return MakeUnique<WPKHDescriptor>(InferPubkey(pubkey, ctx, provider));
+ return std::make_unique<WPKHDescriptor>(InferPubkey(pubkey, ctx, provider));
}
}
if (txntype == TxoutType::MULTISIG) {
@@ -1099,7 +1099,7 @@ std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptCo
CPubKey pubkey(data[i].begin(), data[i].end());
providers.push_back(InferPubkey(pubkey, ctx, provider));
}
- return MakeUnique<MultisigDescriptor>((int)data[0][0], std::move(providers));
+ return std::make_unique<MultisigDescriptor>((int)data[0][0], std::move(providers));
}
if (txntype == TxoutType::SCRIPTHASH && ctx == ParseScriptContext::TOP) {
uint160 hash(data[0]);
@@ -1107,7 +1107,7 @@ std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptCo
CScript subscript;
if (provider.GetCScript(scriptid, subscript)) {
auto sub = InferScript(subscript, ParseScriptContext::P2SH, provider);
- if (sub) return MakeUnique<SHDescriptor>(std::move(sub));
+ if (sub) return std::make_unique<SHDescriptor>(std::move(sub));
}
}
if (txntype == TxoutType::WITNESS_V0_SCRIPTHASH && ctx != ParseScriptContext::P2WSH) {
@@ -1116,18 +1116,18 @@ std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptCo
CScript subscript;
if (provider.GetCScript(scriptid, subscript)) {
auto sub = InferScript(subscript, ParseScriptContext::P2WSH, provider);
- if (sub) return MakeUnique<WSHDescriptor>(std::move(sub));
+ if (sub) return std::make_unique<WSHDescriptor>(std::move(sub));
}
}
CTxDestination dest;
if (ExtractDestination(script, dest)) {
if (GetScriptForDestination(dest) == script) {
- return MakeUnique<AddressDescriptor>(std::move(dest));
+ return std::make_unique<AddressDescriptor>(std::move(dest));
}
}
- return MakeUnique<RawDescriptor>(script);
+ return std::make_unique<RawDescriptor>(script);
}
diff --git a/src/shutdown.cpp b/src/shutdown.cpp
index 6a73e0b2d8..2fc195e2d1 100644
--- a/src/shutdown.cpp
+++ b/src/shutdown.cpp
@@ -5,16 +5,15 @@
#include <shutdown.h>
+#include <logging.h>
+#include <util/tokenpipe.h>
+
#include <config/bitcoin-config.h>
#include <assert.h>
#include <atomic>
#ifdef WIN32
#include <condition_variable>
-#else
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
#endif
static std::atomic<bool> fRequestShutdown(false);
@@ -24,25 +23,18 @@ std::mutex g_shutdown_mutex;
std::condition_variable g_shutdown_cv;
#else
/** On UNIX-like operating systems use the self-pipe trick.
- * Index 0 will be the read end of the pipe, index 1 the write end.
*/
-static int g_shutdown_pipe[2] = {-1, -1};
+static TokenPipeEnd g_shutdown_r;
+static TokenPipeEnd g_shutdown_w;
#endif
bool InitShutdownState()
{
#ifndef WIN32
-#if HAVE_O_CLOEXEC && HAVE_DECL_PIPE2
- // If we can, make sure that the file descriptors are closed on exec()
- // to prevent interference.
- if (pipe2(g_shutdown_pipe, O_CLOEXEC) != 0) {
- return false;
- }
-#else
- if (pipe(g_shutdown_pipe) != 0) {
- return false;
- }
-#endif
+ std::optional<TokenPipe> pipe = TokenPipe::Make();
+ if (!pipe) return false;
+ g_shutdown_r = pipe->TakeReadEnd();
+ g_shutdown_w = pipe->TakeWriteEnd();
#endif
return true;
}
@@ -59,17 +51,10 @@ void StartShutdown()
// case of a reentrant signal.
if (!fRequestShutdown.exchange(true)) {
// Write an arbitrary byte to the write end of the shutdown pipe.
- const char token = 'x';
- while (true) {
- int result = write(g_shutdown_pipe[1], &token, 1);
- if (result < 0) {
- // Failure. It's possible that the write was interrupted by another signal.
- // Other errors are unexpected here.
- assert(errno == EINTR);
- } else {
- assert(result == 1);
- break;
- }
+ int res = g_shutdown_w.TokenWrite('x');
+ if (res != 0) {
+ LogPrintf("Sending shutdown token failed\n");
+ assert(0);
}
}
#endif
@@ -96,17 +81,10 @@ void WaitForShutdown()
std::unique_lock<std::mutex> lk(g_shutdown_mutex);
g_shutdown_cv.wait(lk, [] { return fRequestShutdown.load(); });
#else
- char token;
- while (true) {
- int result = read(g_shutdown_pipe[0], &token, 1);
- if (result < 0) {
- // Failure. Check if the read was interrupted by a signal.
- // Other errors are unexpected here.
- assert(errno == EINTR);
- } else {
- assert(result == 1);
- break;
- }
+ int res = g_shutdown_r.TokenRead();
+ if (res != 'x') {
+ LogPrintf("Reading shutdown token failed\n");
+ assert(0);
}
#endif
}
diff --git a/src/test/allocator_tests.cpp b/src/test/allocator_tests.cpp
index d33d668a04..b523173a45 100644
--- a/src/test/allocator_tests.cpp
+++ b/src/test/allocator_tests.cpp
@@ -2,7 +2,6 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <util/memory.h>
#include <util/system.h>
#include <test/util/setup_common.h>
@@ -163,7 +162,7 @@ private:
BOOST_AUTO_TEST_CASE(lockedpool_tests_mock)
{
// Test over three virtual arenas, of which one will succeed being locked
- std::unique_ptr<LockedPageAllocator> x = MakeUnique<TestLockedPageAllocator>(3, 1);
+ std::unique_ptr<LockedPageAllocator> x = std::make_unique<TestLockedPageAllocator>(3, 1);
LockedPool pool(std::move(x));
BOOST_CHECK(pool.stats().total == 0);
BOOST_CHECK(pool.stats().locked == 0);
diff --git a/src/test/blockfilter_index_tests.cpp b/src/test/blockfilter_index_tests.cpp
index 633a95ce96..04da10715f 100644
--- a/src/test/blockfilter_index_tests.cpp
+++ b/src/test/blockfilter_index_tests.cpp
@@ -62,7 +62,7 @@ CBlock BuildChainTestingSetup::CreateBlock(const CBlockIndex* prev,
const CScript& scriptPubKey)
{
const CChainParams& chainparams = Params();
- std::unique_ptr<CBlockTemplate> pblocktemplate = BlockAssembler(*m_node.mempool, chainparams).CreateNewBlock(scriptPubKey);
+ std::unique_ptr<CBlockTemplate> pblocktemplate = BlockAssembler(*m_node.mempool, chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey);
CBlock& block = pblocktemplate->block;
block.hashPrevBlock = prev->GetBlockHash();
block.nTime = prev->nTime + 1;
diff --git a/src/test/checkqueue_tests.cpp b/src/test/checkqueue_tests.cpp
index 21921375b3..64c6d7f634 100644
--- a/src/test/checkqueue_tests.cpp
+++ b/src/test/checkqueue_tests.cpp
@@ -5,7 +5,6 @@
#include <checkqueue.h>
#include <sync.h>
#include <test/util/setup_common.h>
-#include <util/memory.h>
#include <util/system.h>
#include <util/time.h>
@@ -146,7 +145,7 @@ typedef CCheckQueue<FrozenCleanupCheck> FrozenCleanup_Queue;
*/
static void Correct_Queue_range(std::vector<size_t> range)
{
- auto small_queue = MakeUnique<Correct_Queue>(QUEUE_BATCH_SIZE);
+ auto small_queue = std::make_unique<Correct_Queue>(QUEUE_BATCH_SIZE);
small_queue->StartWorkerThreads(SCRIPT_CHECK_THREADS);
// Make vChecks here to save on malloc (this test can be slow...)
std::vector<FakeCheckCheckCompletion> vChecks;
@@ -206,7 +205,7 @@ BOOST_AUTO_TEST_CASE(test_CheckQueue_Correct_Random)
/** Test that failing checks are caught */
BOOST_AUTO_TEST_CASE(test_CheckQueue_Catches_Failure)
{
- auto fail_queue = MakeUnique<Failing_Queue>(QUEUE_BATCH_SIZE);
+ auto fail_queue = std::make_unique<Failing_Queue>(QUEUE_BATCH_SIZE);
fail_queue->StartWorkerThreads(SCRIPT_CHECK_THREADS);
for (size_t i = 0; i < 1001; ++i) {
@@ -234,7 +233,7 @@ BOOST_AUTO_TEST_CASE(test_CheckQueue_Catches_Failure)
// future blocks, ie, the bad state is cleared.
BOOST_AUTO_TEST_CASE(test_CheckQueue_Recovers_From_Failure)
{
- auto fail_queue = MakeUnique<Failing_Queue>(QUEUE_BATCH_SIZE);
+ auto fail_queue = std::make_unique<Failing_Queue>(QUEUE_BATCH_SIZE);
fail_queue->StartWorkerThreads(SCRIPT_CHECK_THREADS);
for (auto times = 0; times < 10; ++times) {
@@ -258,7 +257,7 @@ BOOST_AUTO_TEST_CASE(test_CheckQueue_Recovers_From_Failure)
// more than once as well
BOOST_AUTO_TEST_CASE(test_CheckQueue_UniqueCheck)
{
- auto queue = MakeUnique<Unique_Queue>(QUEUE_BATCH_SIZE);
+ auto queue = std::make_unique<Unique_Queue>(QUEUE_BATCH_SIZE);
queue->StartWorkerThreads(SCRIPT_CHECK_THREADS);
size_t COUNT = 100000;
@@ -293,7 +292,7 @@ BOOST_AUTO_TEST_CASE(test_CheckQueue_UniqueCheck)
// time could leave the data hanging across a sequence of blocks.
BOOST_AUTO_TEST_CASE(test_CheckQueue_Memory)
{
- auto queue = MakeUnique<Memory_Queue>(QUEUE_BATCH_SIZE);
+ auto queue = std::make_unique<Memory_Queue>(QUEUE_BATCH_SIZE);
queue->StartWorkerThreads(SCRIPT_CHECK_THREADS);
for (size_t i = 0; i < 1000; ++i) {
size_t total = i;
@@ -320,7 +319,7 @@ BOOST_AUTO_TEST_CASE(test_CheckQueue_Memory)
// have been destructed
BOOST_AUTO_TEST_CASE(test_CheckQueue_FrozenCleanup)
{
- auto queue = MakeUnique<FrozenCleanup_Queue>(QUEUE_BATCH_SIZE);
+ auto queue = std::make_unique<FrozenCleanup_Queue>(QUEUE_BATCH_SIZE);
bool fails = false;
queue->StartWorkerThreads(SCRIPT_CHECK_THREADS);
std::thread t0([&]() {
@@ -360,7 +359,7 @@ BOOST_AUTO_TEST_CASE(test_CheckQueue_FrozenCleanup)
/** Test that CCheckQueueControl is threadsafe */
BOOST_AUTO_TEST_CASE(test_CheckQueueControl_Locks)
{
- auto queue = MakeUnique<Standard_Queue>(QUEUE_BATCH_SIZE);
+ auto queue = std::make_unique<Standard_Queue>(QUEUE_BATCH_SIZE);
{
std::vector<std::thread> tg;
std::atomic<int> nThreads {0};
diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp
index 3d802cbeb3..a6080ad3dd 100644
--- a/src/test/dbwrapper_tests.cpp
+++ b/src/test/dbwrapper_tests.cpp
@@ -5,7 +5,6 @@
#include <dbwrapper.h>
#include <test/util/setup_common.h>
#include <uint256.h>
-#include <util/memory.h>
#include <memory>
@@ -207,7 +206,7 @@ BOOST_AUTO_TEST_CASE(existing_data_no_obfuscate)
create_directories(ph);
// Set up a non-obfuscated wrapper to write some initial data.
- std::unique_ptr<CDBWrapper> dbw = MakeUnique<CDBWrapper>(ph, (1 << 10), false, false, false);
+ std::unique_ptr<CDBWrapper> dbw = std::make_unique<CDBWrapper>(ph, (1 << 10), false, false, false);
char key = 'k';
uint256 in = InsecureRand256();
uint256 res;
@@ -248,7 +247,7 @@ BOOST_AUTO_TEST_CASE(existing_data_reindex)
create_directories(ph);
// Set up a non-obfuscated wrapper to write some initial data.
- std::unique_ptr<CDBWrapper> dbw = MakeUnique<CDBWrapper>(ph, (1 << 10), false, false, false);
+ std::unique_ptr<CDBWrapper> dbw = std::make_unique<CDBWrapper>(ph, (1 << 10), false, false, false);
char key = 'k';
uint256 in = InsecureRand256();
uint256 res;
diff --git a/src/test/denialofservice_tests.cpp b/src/test/denialofservice_tests.cpp
index 5906913b58..e75982bc6f 100644
--- a/src/test/denialofservice_tests.cpp
+++ b/src/test/denialofservice_tests.cpp
@@ -15,7 +15,6 @@
#include <script/standard.h>
#include <serialize.h>
#include <txorphanage.h>
-#include <util/memory.h>
#include <util/string.h>
#include <util/system.h>
#include <util/time.h>
@@ -68,7 +67,7 @@ BOOST_FIXTURE_TEST_SUITE(denialofservice_tests, TestingSetup)
BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction)
{
const CChainParams& chainparams = Params();
- auto connman = MakeUnique<CConnman>(0x1337, 0x1337);
+ auto connman = std::make_unique<CConnman>(0x1337, 0x1337);
auto peerLogic = PeerManager::make(chainparams, *connman, nullptr, *m_node.scheduler,
*m_node.chainman, *m_node.mempool, false);
@@ -138,7 +137,7 @@ static void AddRandomOutboundPeer(std::vector<CNode *> &vNodes, PeerManager &pee
BOOST_AUTO_TEST_CASE(stale_tip_peer_management)
{
const CChainParams& chainparams = Params();
- auto connman = MakeUnique<CConnmanTest>(0x1337, 0x1337);
+ auto connman = std::make_unique<CConnmanTest>(0x1337, 0x1337);
auto peerLogic = PeerManager::make(chainparams, *connman, nullptr, *m_node.scheduler,
*m_node.chainman, *m_node.mempool, false);
@@ -211,8 +210,8 @@ BOOST_AUTO_TEST_CASE(stale_tip_peer_management)
BOOST_AUTO_TEST_CASE(peer_discouragement)
{
const CChainParams& chainparams = Params();
- auto banman = MakeUnique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME);
- auto connman = MakeUnique<CConnman>(0x1337, 0x1337);
+ auto banman = std::make_unique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME);
+ auto connman = std::make_unique<CConnman>(0x1337, 0x1337);
auto peerLogic = PeerManager::make(chainparams, *connman, banman.get(), *m_node.scheduler,
*m_node.chainman, *m_node.mempool, false);
@@ -258,8 +257,8 @@ BOOST_AUTO_TEST_CASE(peer_discouragement)
BOOST_AUTO_TEST_CASE(DoS_bantime)
{
const CChainParams& chainparams = Params();
- auto banman = MakeUnique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME);
- auto connman = MakeUnique<CConnman>(0x1337, 0x1337);
+ auto banman = std::make_unique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME);
+ auto connman = std::make_unique<CConnman>(0x1337, 0x1337);
auto peerLogic = PeerManager::make(chainparams, *connman, banman.get(), *m_node.scheduler,
*m_node.chainman, *m_node.mempool, false);
diff --git a/src/test/fuzz/FuzzedDataProvider.h b/src/test/fuzz/FuzzedDataProvider.h
index 744a9d78ce..6cbfc39bc2 100644
--- a/src/test/fuzz/FuzzedDataProvider.h
+++ b/src/test/fuzz/FuzzedDataProvider.h
@@ -20,6 +20,7 @@
#include <cstdint>
#include <cstring>
#include <initializer_list>
+#include <limits>
#include <string>
#include <type_traits>
#include <utility>
diff --git a/src/test/fuzz/coins_view.cpp b/src/test/fuzz/coins_view.cpp
index 328a31f1dc..d951bda20f 100644
--- a/src/test/fuzz/coins_view.cpp
+++ b/src/test/fuzz/coins_view.cpp
@@ -264,7 +264,7 @@ FUZZ_TARGET_INIT(coins_view, initialize_coins_view)
CCoinsStats stats;
bool expected_code_path = false;
try {
- (void)GetUTXOStats(&coins_view_cache, stats, CoinStatsHashType::HASH_SERIALIZED);
+ (void)GetUTXOStats(&coins_view_cache, WITH_LOCK(::cs_main, return std::ref(g_chainman.m_blockman)), stats, CoinStatsHashType::HASH_SERIALIZED);
} catch (const std::logic_error&) {
expected_code_path = true;
}
diff --git a/src/test/fuzz/descriptor_parse.cpp b/src/test/fuzz/descriptor_parse.cpp
index 0d1921f285..ffe4855662 100644
--- a/src/test/fuzz/descriptor_parse.cpp
+++ b/src/test/fuzz/descriptor_parse.cpp
@@ -6,7 +6,6 @@
#include <pubkey.h>
#include <script/descriptor.h>
#include <test/fuzz/fuzz.h>
-#include <util/memory.h>
void initialize_descriptor_parse()
{
diff --git a/src/test/fuzz/eval_script.cpp b/src/test/fuzz/eval_script.cpp
index 635288fc36..77ed798923 100644
--- a/src/test/fuzz/eval_script.cpp
+++ b/src/test/fuzz/eval_script.cpp
@@ -6,7 +6,6 @@
#include <script/interpreter.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
-#include <util/memory.h>
#include <limits>
diff --git a/src/test/fuzz/key.cpp b/src/test/fuzz/key.cpp
index aa8f826e4a..32077b1fe2 100644
--- a/src/test/fuzz/key.cpp
+++ b/src/test/fuzz/key.cpp
@@ -17,7 +17,6 @@
#include <script/standard.h>
#include <streams.h>
#include <test/fuzz/fuzz.h>
-#include <util/memory.h>
#include <util/strencodings.h>
#include <cassert>
diff --git a/src/test/fuzz/parse_univalue.cpp b/src/test/fuzz/parse_univalue.cpp
index afe382ba21..3fffaac8d0 100644
--- a/src/test/fuzz/parse_univalue.cpp
+++ b/src/test/fuzz/parse_univalue.cpp
@@ -7,7 +7,6 @@
#include <rpc/client.h>
#include <rpc/util.h>
#include <test/fuzz/fuzz.h>
-#include <util/memory.h>
#include <limits>
#include <string>
diff --git a/src/test/fuzz/process_message.cpp b/src/test/fuzz/process_message.cpp
index 0289d49ccc..04fc6da9b1 100644
--- a/src/test/fuzz/process_message.cpp
+++ b/src/test/fuzz/process_message.cpp
@@ -19,7 +19,6 @@
#include <test/util/setup_common.h>
#include <test/util/validation.h>
#include <txorphanage.h>
-#include <util/memory.h>
#include <validationinterface.h>
#include <version.h>
diff --git a/src/test/fuzz/process_messages.cpp b/src/test/fuzz/process_messages.cpp
index 617a71ea60..ee402dba38 100644
--- a/src/test/fuzz/process_messages.cpp
+++ b/src/test/fuzz/process_messages.cpp
@@ -14,7 +14,6 @@
#include <test/util/setup_common.h>
#include <test/util/validation.h>
#include <txorphanage.h>
-#include <util/memory.h>
#include <validation.h>
#include <validationinterface.h>
diff --git a/src/test/fuzz/psbt.cpp b/src/test/fuzz/psbt.cpp
index 0b4588c4ce..eb2754054a 100644
--- a/src/test/fuzz/psbt.cpp
+++ b/src/test/fuzz/psbt.cpp
@@ -10,7 +10,6 @@
#include <pubkey.h>
#include <script/script.h>
#include <streams.h>
-#include <util/memory.h>
#include <version.h>
#include <cstdint>
diff --git a/src/test/fuzz/script.cpp b/src/test/fuzz/script.cpp
index 193862e847..8219a04e49 100644
--- a/src/test/fuzz/script.cpp
+++ b/src/test/fuzz/script.cpp
@@ -20,7 +20,6 @@
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <univalue.h>
-#include <util/memory.h>
#include <algorithm>
#include <cassert>
diff --git a/src/test/fuzz/script_flags.cpp b/src/test/fuzz/script_flags.cpp
index ce8915ca2c..561230707c 100644
--- a/src/test/fuzz/script_flags.cpp
+++ b/src/test/fuzz/script_flags.cpp
@@ -5,7 +5,6 @@
#include <pubkey.h>
#include <script/interpreter.h>
#include <streams.h>
-#include <util/memory.h>
#include <version.h>
#include <test/fuzz/fuzz.h>
diff --git a/src/test/fuzz/signature_checker.cpp b/src/test/fuzz/signature_checker.cpp
index 3e7b72805e..7b57c5dfd8 100644
--- a/src/test/fuzz/signature_checker.cpp
+++ b/src/test/fuzz/signature_checker.cpp
@@ -6,7 +6,6 @@
#include <script/interpreter.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
-#include <util/memory.h>
#include <cstdint>
#include <limits>
@@ -15,7 +14,7 @@
void initialize_signature_checker()
{
- static const auto verify_handle = MakeUnique<ECCVerifyHandle>();
+ static const auto verify_handle = std::make_unique<ECCVerifyHandle>();
}
namespace {
diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp
index aa628371e6..9acd17c463 100644
--- a/src/test/miner_tests.cpp
+++ b/src/test/miner_tests.cpp
@@ -122,7 +122,7 @@ void MinerTestingSetup::TestPackageSelection(const CChainParams& chainparams, co
uint256 hashHighFeeTx = tx.GetHash();
m_node.mempool->addUnchecked(entry.Fee(50000).Time(GetTime()).SpendsCoinbase(false).FromTx(tx));
- std::unique_ptr<CBlockTemplate> pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey);
+ std::unique_ptr<CBlockTemplate> pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey);
BOOST_REQUIRE_EQUAL(pblocktemplate->block.vtx.size(), 4U);
BOOST_CHECK(pblocktemplate->block.vtx[1]->GetHash() == hashParentTx);
BOOST_CHECK(pblocktemplate->block.vtx[2]->GetHash() == hashHighFeeTx);
@@ -143,7 +143,7 @@ void MinerTestingSetup::TestPackageSelection(const CChainParams& chainparams, co
tx.vout[0].nValue = 5000000000LL - 1000 - 50000 - feeToUse;
uint256 hashLowFeeTx = tx.GetHash();
m_node.mempool->addUnchecked(entry.Fee(feeToUse).FromTx(tx));
- pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey);
+ pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey);
// Verify that the free tx and the low fee tx didn't get selected
for (size_t i=0; i<pblocktemplate->block.vtx.size(); ++i) {
BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashFreeTx);
@@ -157,7 +157,7 @@ void MinerTestingSetup::TestPackageSelection(const CChainParams& chainparams, co
tx.vout[0].nValue -= 2; // Now we should be just over the min relay fee
hashLowFeeTx = tx.GetHash();
m_node.mempool->addUnchecked(entry.Fee(feeToUse+2).FromTx(tx));
- pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey);
+ pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey);
BOOST_REQUIRE_EQUAL(pblocktemplate->block.vtx.size(), 6U);
BOOST_CHECK(pblocktemplate->block.vtx[4]->GetHash() == hashFreeTx);
BOOST_CHECK(pblocktemplate->block.vtx[5]->GetHash() == hashLowFeeTx);
@@ -179,7 +179,7 @@ void MinerTestingSetup::TestPackageSelection(const CChainParams& chainparams, co
tx.vout[0].nValue = 5000000000LL - 100000000 - feeToUse;
uint256 hashLowFeeTx2 = tx.GetHash();
m_node.mempool->addUnchecked(entry.Fee(feeToUse).SpendsCoinbase(false).FromTx(tx));
- pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey);
+ pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey);
// Verify that this tx isn't selected.
for (size_t i=0; i<pblocktemplate->block.vtx.size(); ++i) {
@@ -192,7 +192,7 @@ void MinerTestingSetup::TestPackageSelection(const CChainParams& chainparams, co
tx.vin[0].prevout.n = 1;
tx.vout[0].nValue = 100000000 - 10000; // 10k satoshi fee
m_node.mempool->addUnchecked(entry.Fee(10000).FromTx(tx));
- pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey);
+ pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey);
BOOST_REQUIRE_EQUAL(pblocktemplate->block.vtx.size(), 9U);
BOOST_CHECK(pblocktemplate->block.vtx[8]->GetHash() == hashLowFeeTx2);
}
@@ -215,7 +215,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
fCheckpointsEnabled = false;
// Simple block creation, nothing special yet:
- BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
+ BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey));
// We can't make transactions until we have inputs
// Therefore, load 110 blocks :)
@@ -252,7 +252,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
LOCK(m_node.mempool->cs);
// Just to make sure we can still make simple blocks
- BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
+ BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey));
const CAmount BLOCKSUBSIDY = 50*COIN;
const CAmount LOWFEE = CENT;
@@ -277,7 +277,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx.vin[0].prevout.hash = hash;
}
- BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error, HasReason("bad-blk-sigops"));
+ BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey), std::runtime_error, HasReason("bad-blk-sigops"));
m_node.mempool->clear();
tx.vin[0].prevout.hash = txFirst[0]->GetHash();
@@ -291,7 +291,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
m_node.mempool->addUnchecked(entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).SigOpsCost(80).FromTx(tx));
tx.vin[0].prevout.hash = hash;
}
- BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
+ BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey));
m_node.mempool->clear();
// block size > limit
@@ -311,13 +311,13 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
m_node.mempool->addUnchecked(entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx));
tx.vin[0].prevout.hash = hash;
}
- BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
+ BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey));
m_node.mempool->clear();
// orphan in *m_node.mempool, template creation fails
hash = tx.GetHash();
m_node.mempool->addUnchecked(entry.Fee(LOWFEE).Time(GetTime()).FromTx(tx));
- BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error, HasReason("bad-txns-inputs-missingorspent"));
+ BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey), std::runtime_error, HasReason("bad-txns-inputs-missingorspent"));
m_node.mempool->clear();
// child with higher feerate than parent
@@ -334,7 +334,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx.vout[0].nValue = tx.vout[0].nValue+BLOCKSUBSIDY-HIGHERFEE; //First txn output + fresh coinbase - new txn fee
hash = tx.GetHash();
m_node.mempool->addUnchecked(entry.Fee(HIGHERFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
- BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
+ BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey));
m_node.mempool->clear();
// coinbase in *m_node.mempool, template creation fails
@@ -346,7 +346,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
// give it a fee so it'll get mined
m_node.mempool->addUnchecked(entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(false).FromTx(tx));
// Should throw bad-cb-multiple
- BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error, HasReason("bad-cb-multiple"));
+ BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey), std::runtime_error, HasReason("bad-cb-multiple"));
m_node.mempool->clear();
// double spend txn pair in *m_node.mempool, template creation fails
@@ -359,7 +359,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx.vout[0].scriptPubKey = CScript() << OP_2;
hash = tx.GetHash();
m_node.mempool->addUnchecked(entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
- BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error, HasReason("bad-txns-inputs-missingorspent"));
+ BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey), std::runtime_error, HasReason("bad-txns-inputs-missingorspent"));
m_node.mempool->clear();
// subsidy changing
@@ -375,7 +375,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
next->BuildSkip();
::ChainActive().SetTip(next);
}
- BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
+ BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey));
// Extend to a 210000-long block chain.
while (::ChainActive().Tip()->nHeight < 210000) {
CBlockIndex* prev = ::ChainActive().Tip();
@@ -387,7 +387,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
next->BuildSkip();
::ChainActive().SetTip(next);
}
- BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
+ BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey));
// invalid p2sh txn in *m_node.mempool, template creation fails
tx.vin[0].prevout.hash = txFirst[0]->GetHash();
@@ -404,7 +404,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
hash = tx.GetHash();
m_node.mempool->addUnchecked(entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(false).FromTx(tx));
// Should throw block-validation-failed
- BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error, HasReason("block-validation-failed"));
+ BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey), std::runtime_error, HasReason("block-validation-failed"));
m_node.mempool->clear();
// Delete the dummy blocks again.
@@ -492,7 +492,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx.vin[0].nSequence = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG | 1;
BOOST_CHECK(!TestSequenceLocks(CTransaction(tx), flags)); // Sequence locks fail
- BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
+ BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey));
// None of the of the absolute height/time locked tx should have made
// it into the template because we still check IsFinalTx in CreateNewBlock,
@@ -505,7 +505,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
::ChainActive().Tip()->nHeight++;
SetMockTime(::ChainActive().Tip()->GetMedianTimePast() + 1);
- BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
+ BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey));
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 5U);
::ChainActive().Tip()->nHeight--;
diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp
index a29c6a2665..167242a971 100644
--- a/src/test/net_tests.cpp
+++ b/src/test/net_tests.cpp
@@ -14,7 +14,6 @@
#include <span.h>
#include <streams.h>
#include <test/util/setup_common.h>
-#include <util/memory.h>
#include <util/strencodings.h>
#include <util/string.h>
#include <util/system.h>
@@ -188,7 +187,7 @@ BOOST_AUTO_TEST_CASE(cnode_simple_test)
CAddress addr = CAddress(CService(ipv4Addr, 7777), NODE_NETWORK);
std::string pszDest;
- std::unique_ptr<CNode> pnode1 = MakeUnique<CNode>(
+ std::unique_ptr<CNode> pnode1 = std::make_unique<CNode>(
id++, NODE_NETWORK, hSocket, addr,
/* nKeyedNetGroupIn = */ 0,
/* nLocalHostNonceIn = */ 0,
@@ -203,7 +202,7 @@ BOOST_AUTO_TEST_CASE(cnode_simple_test)
BOOST_CHECK(pnode1->m_inbound_onion == false);
BOOST_CHECK_EQUAL(pnode1->ConnectedThroughNetwork(), Network::NET_IPV4);
- std::unique_ptr<CNode> pnode2 = MakeUnique<CNode>(
+ std::unique_ptr<CNode> pnode2 = std::make_unique<CNode>(
id++, NODE_NETWORK, hSocket, addr,
/* nKeyedNetGroupIn = */ 1,
/* nLocalHostNonceIn = */ 1,
@@ -218,7 +217,7 @@ BOOST_AUTO_TEST_CASE(cnode_simple_test)
BOOST_CHECK(pnode2->m_inbound_onion == false);
BOOST_CHECK_EQUAL(pnode2->ConnectedThroughNetwork(), Network::NET_IPV4);
- std::unique_ptr<CNode> pnode3 = MakeUnique<CNode>(
+ std::unique_ptr<CNode> pnode3 = std::make_unique<CNode>(
id++, NODE_NETWORK, hSocket, addr,
/* nKeyedNetGroupIn = */ 0,
/* nLocalHostNonceIn = */ 0,
@@ -233,7 +232,7 @@ BOOST_AUTO_TEST_CASE(cnode_simple_test)
BOOST_CHECK(pnode3->m_inbound_onion == false);
BOOST_CHECK_EQUAL(pnode3->ConnectedThroughNetwork(), Network::NET_IPV4);
- std::unique_ptr<CNode> pnode4 = MakeUnique<CNode>(
+ std::unique_ptr<CNode> pnode4 = std::make_unique<CNode>(
id++, NODE_NETWORK, hSocket, addr,
/* nKeyedNetGroupIn = */ 1,
/* nLocalHostNonceIn = */ 1,
@@ -711,7 +710,7 @@ BOOST_AUTO_TEST_CASE(ipv4_peer_with_ipv6_addrMe_test)
in_addr ipv4AddrPeer;
ipv4AddrPeer.s_addr = 0xa0b0c001;
CAddress addr = CAddress(CService(ipv4AddrPeer, 7777), NODE_NETWORK);
- std::unique_ptr<CNode> pnode = MakeUnique<CNode>(0, NODE_NETWORK, INVALID_SOCKET, addr, /* nKeyedNetGroupIn */ 0, /* nLocalHostNonceIn */ 0, CAddress{}, /* pszDest */ std::string{}, ConnectionType::OUTBOUND_FULL_RELAY, /* inbound_onion */ false);
+ std::unique_ptr<CNode> pnode = std::make_unique<CNode>(0, NODE_NETWORK, INVALID_SOCKET, addr, /* nKeyedNetGroupIn */ 0, /* nLocalHostNonceIn */ 0, CAddress{}, /* pszDest */ std::string{}, ConnectionType::OUTBOUND_FULL_RELAY, /* inbound_onion */ false);
pnode->fSuccessfullyConnected.store(true);
// the peer claims to be reaching us via IPv6
diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp
index 810665877d..2e0fc7e48f 100644
--- a/src/test/rpc_tests.cpp
+++ b/src/test/rpc_tests.cpp
@@ -36,7 +36,6 @@ UniValue RPCTestingSetup::CallRPC(std::string args)
JSONRPCRequest request(context);
request.strMethod = strMethod;
request.params = RPCConvertValues(strMethod, vArgs);
- request.fHelp = false;
if (RPCIsInWarmup(nullptr)) SetRPCWarmupFinished();
try {
UniValue result = tableRPC.execute(request);
diff --git a/src/test/util/logging.cpp b/src/test/util/logging.cpp
index c1dd47f06c..66f4efc139 100644
--- a/src/test/util/logging.cpp
+++ b/src/test/util/logging.cpp
@@ -7,7 +7,6 @@
#include <logging.h>
#include <noui.h>
#include <tinyformat.h>
-#include <util/memory.h>
#include <stdexcept>
diff --git a/src/test/util/mining.cpp b/src/test/util/mining.cpp
index 0c6487fbfa..ba1edba0ae 100644
--- a/src/test/util/mining.cpp
+++ b/src/test/util/mining.cpp
@@ -42,7 +42,7 @@ std::shared_ptr<CBlock> PrepareBlock(const NodeContext& node, const CScript& coi
{
auto block = std::make_shared<CBlock>(
BlockAssembler{*Assert(node.mempool), Params()}
- .CreateNewBlock(coinbase_scriptPubKey)
+ .CreateNewBlock(::ChainstateActive(), coinbase_scriptPubKey)
->block);
LOCK(cs_main);
diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp
index 46b28190d3..f866c2a1f9 100644
--- a/src/test/util/setup_common.cpp
+++ b/src/test/util/setup_common.cpp
@@ -25,7 +25,6 @@
#include <script/sigcache.h>
#include <streams.h>
#include <txdb.h>
-#include <util/memory.h>
#include <util/strencodings.h>
#include <util/string.h>
#include <util/time.h>
@@ -131,7 +130,7 @@ ChainTestingSetup::ChainTestingSetup(const std::string& chainName, const std::ve
{
// We have to run a scheduler thread to prevent ActivateBestChain
// from blocking due to queue overrun.
- m_node.scheduler = MakeUnique<CScheduler>();
+ m_node.scheduler = std::make_unique<CScheduler>();
m_node.scheduler->m_service_thread = std::thread([&] { TraceThread("scheduler", [&] { m_node.scheduler->serviceQueue(); }); });
GetMainSignals().RegisterBackgroundSignalScheduler(*m_node.scheduler);
@@ -188,8 +187,8 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector<const
throw std::runtime_error(strprintf("ActivateBestChain failed. (%s)", state.ToString()));
}
- m_node.banman = MakeUnique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME);
- m_node.connman = MakeUnique<CConnman>(0x1337, 0x1337); // Deterministic randomness for tests.
+ m_node.banman = std::make_unique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME);
+ m_node.connman = std::make_unique<CConnman>(0x1337, 0x1337); // Deterministic randomness for tests.
m_node.peerman = PeerManager::make(chainparams, *m_node.connman, m_node.banman.get(),
*m_node.scheduler, *m_node.chainman, *m_node.mempool,
false);
@@ -245,13 +244,13 @@ CBlock TestChain100Setup::CreateAndProcessBlock(const std::vector<CMutableTransa
{
const CChainParams& chainparams = Params();
CTxMemPool empty_pool;
- CBlock block = BlockAssembler(empty_pool, chainparams).CreateNewBlock(scriptPubKey)->block;
+ CBlock block = BlockAssembler(empty_pool, chainparams).CreateNewBlock(::ChainstateActive(), scriptPubKey)->block;
Assert(block.vtx.size() == 1);
for (const CMutableTransaction& tx : txns) {
block.vtx.push_back(MakeTransactionRef(tx));
}
- RegenerateCommitments(block);
+ RegenerateCommitments(block, WITH_LOCK(::cs_main, return std::ref(g_chainman.m_blockman)));
while (!CheckProofOfWork(block.GetHash(), block.nBits, chainparams.GetConsensus())) ++block.nNonce;
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
index 5a46002a79..b742fcaf0b 100644
--- a/src/test/util_tests.cpp
+++ b/src/test/util_tests.cpp
@@ -71,7 +71,7 @@ BOOST_AUTO_TEST_CASE(util_datadir)
BOOST_AUTO_TEST_CASE(util_check)
{
// Check that Assert can forward
- const std::unique_ptr<int> p_two = Assert(MakeUnique<int>(2));
+ const std::unique_ptr<int> p_two = Assert(std::make_unique<int>(2));
// Check that Assert works on lvalues and rvalues
const int two = *Assert(p_two);
Assert(two == 2);
diff --git a/src/test/validation_block_tests.cpp b/src/test/validation_block_tests.cpp
index 0c87c4d360..f3fc83078f 100644
--- a/src/test/validation_block_tests.cpp
+++ b/src/test/validation_block_tests.cpp
@@ -63,7 +63,7 @@ std::shared_ptr<CBlock> MinerTestingSetup::Block(const uint256& prev_hash)
static int i = 0;
static uint64_t time = Params().GenesisBlock().nTime;
- auto ptemplate = BlockAssembler(*m_node.mempool, Params()).CreateNewBlock(CScript{} << i++ << OP_TRUE);
+ auto ptemplate = BlockAssembler(*m_node.mempool, Params()).CreateNewBlock(::ChainstateActive(), CScript{} << i++ << OP_TRUE);
auto pblock = std::make_shared<CBlock>(ptemplate->block);
pblock->hashPrevBlock = prev_hash;
pblock->nTime = ++time;
@@ -325,7 +325,7 @@ BOOST_AUTO_TEST_CASE(witness_commitment_index)
{
CScript pubKey;
pubKey << 1 << OP_TRUE;
- auto ptemplate = BlockAssembler(*m_node.mempool, Params()).CreateNewBlock(pubKey);
+ auto ptemplate = BlockAssembler(*m_node.mempool, Params()).CreateNewBlock(::ChainstateActive(), pubKey);
CBlock pblock = ptemplate->block;
CTxOut witness;
diff --git a/src/txdb.cpp b/src/txdb.cpp
index 4b4766e1ba..3a08e28c01 100644
--- a/src/txdb.cpp
+++ b/src/txdb.cpp
@@ -10,7 +10,6 @@
#include <random.h>
#include <shutdown.h>
#include <uint256.h>
-#include <util/memory.h>
#include <util/system.h>
#include <util/translation.h>
#include <util/vector.h>
@@ -41,7 +40,7 @@ struct CoinEntry {
}
CCoinsViewDB::CCoinsViewDB(fs::path ldb_path, size_t nCacheSize, bool fMemory, bool fWipe) :
- m_db(MakeUnique<CDBWrapper>(ldb_path, nCacheSize, fMemory, fWipe, true)),
+ m_db(std::make_unique<CDBWrapper>(ldb_path, nCacheSize, fMemory, fWipe, true)),
m_ldb_path(ldb_path),
m_is_memory(fMemory) { }
@@ -53,7 +52,7 @@ void CCoinsViewDB::ResizeCache(size_t new_cache_size)
// Have to do a reset first to get the original `m_db` state to release its
// filesystem lock.
m_db.reset();
- m_db = MakeUnique<CDBWrapper>(
+ m_db = std::make_unique<CDBWrapper>(
m_ldb_path, new_cache_size, m_is_memory, /*fWipe*/ false, /*obfuscate*/ true);
}
}
diff --git a/src/txrequest.cpp b/src/txrequest.cpp
index e54c073328..58424134b0 100644
--- a/src/txrequest.cpp
+++ b/src/txrequest.cpp
@@ -9,7 +9,6 @@
#include <primitives/transaction.h>
#include <random.h>
#include <uint256.h>
-#include <util/memory.h>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
@@ -711,7 +710,7 @@ public:
};
TxRequestTracker::TxRequestTracker(bool deterministic) :
- m_impl{MakeUnique<TxRequestTracker::Impl>(deterministic)} {}
+ m_impl{std::make_unique<TxRequestTracker::Impl>(deterministic)} {}
TxRequestTracker::~TxRequestTracker() = default;
diff --git a/src/util/memory.h b/src/util/memory.h
deleted file mode 100644
index f21b81bade..0000000000
--- a/src/util/memory.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2020 The Bitcoin Core developers
-// Distributed under the MIT software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-#ifndef BITCOIN_UTIL_MEMORY_H
-#define BITCOIN_UTIL_MEMORY_H
-
-#include <memory>
-#include <utility>
-
-//! Substitute for C++14 std::make_unique.
-//! DEPRECATED use std::make_unique in new code.
-template <typename T, typename... Args>
-std::unique_ptr<T> MakeUnique(Args&&... args)
-{
- return std::make_unique<T>(std::forward<Args>(args)...);
-}
-
-#endif
diff --git a/src/util/system.cpp b/src/util/system.cpp
index 71453eed81..63b3c52ee5 100644
--- a/src/util/system.cpp
+++ b/src/util/system.cpp
@@ -100,7 +100,7 @@ bool LockDirectory(const fs::path& directory, const std::string lockfile_name, b
// Create empty lock file if it doesn't exist.
FILE* file = fsbridge::fopen(pathLockFile, "a");
if (file) fclose(file);
- auto lock = MakeUnique<fsbridge::FileLock>(pathLockFile);
+ auto lock = std::make_unique<fsbridge::FileLock>(pathLockFile);
if (!lock->TryLock()) {
return error("Error while attempting to lock directory %s: %s", directory.string(), lock->GetReason());
}
diff --git a/src/util/system.h b/src/util/system.h
index de47b93b6e..30b8cb1c68 100644
--- a/src/util/system.h
+++ b/src/util/system.h
@@ -22,7 +22,6 @@
#include <optional.h>
#include <sync.h>
#include <tinyformat.h>
-#include <util/memory.h>
#include <util/settings.h>
#include <util/threadnames.h>
#include <util/time.h>
diff --git a/src/util/tokenpipe.cpp b/src/util/tokenpipe.cpp
new file mode 100644
index 0000000000..79465dd430
--- /dev/null
+++ b/src/util/tokenpipe.cpp
@@ -0,0 +1,108 @@
+// Copyright (c) 2021 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include <util/tokenpipe.h>
+
+#include <config/bitcoin-config.h>
+
+#ifndef WIN32
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+TokenPipeEnd TokenPipe::TakeReadEnd()
+{
+ TokenPipeEnd res(m_fds[0]);
+ m_fds[0] = -1;
+ return res;
+}
+
+TokenPipeEnd TokenPipe::TakeWriteEnd()
+{
+ TokenPipeEnd res(m_fds[1]);
+ m_fds[1] = -1;
+ return res;
+}
+
+TokenPipeEnd::TokenPipeEnd(int fd) : m_fd(fd)
+{
+}
+
+TokenPipeEnd::~TokenPipeEnd()
+{
+ Close();
+}
+
+int TokenPipeEnd::TokenWrite(uint8_t token)
+{
+ while (true) {
+ ssize_t result = write(m_fd, &token, 1);
+ if (result < 0) {
+ // Failure. It's possible that the write was interrupted by a signal,
+ // in that case retry.
+ if (errno != EINTR) {
+ return TS_ERR;
+ }
+ } else if (result == 0) {
+ return TS_EOS;
+ } else { // ==1
+ return 0;
+ }
+ }
+}
+
+int TokenPipeEnd::TokenRead()
+{
+ uint8_t token;
+ while (true) {
+ ssize_t result = read(m_fd, &token, 1);
+ if (result < 0) {
+ // Failure. Check if the read was interrupted by a signal,
+ // in that case retry.
+ if (errno != EINTR) {
+ return TS_ERR;
+ }
+ } else if (result == 0) {
+ return TS_EOS;
+ } else { // ==1
+ return token;
+ }
+ }
+ return token;
+}
+
+void TokenPipeEnd::Close()
+{
+ if (m_fd != -1) close(m_fd);
+ m_fd = -1;
+}
+
+std::optional<TokenPipe> TokenPipe::Make()
+{
+ int fds[2] = {-1, -1};
+#if HAVE_O_CLOEXEC && HAVE_DECL_PIPE2
+ if (pipe2(fds, O_CLOEXEC) != 0) {
+ return std::nullopt;
+ }
+#else
+ if (pipe(fds) != 0) {
+ return std::nullopt;
+ }
+#endif
+ return TokenPipe(fds);
+}
+
+TokenPipe::~TokenPipe()
+{
+ Close();
+}
+
+void TokenPipe::Close()
+{
+ if (m_fds[0] != -1) close(m_fds[0]);
+ if (m_fds[1] != -1) close(m_fds[1]);
+ m_fds[0] = m_fds[1] = -1;
+}
+
+#endif // WIN32
diff --git a/src/util/tokenpipe.h b/src/util/tokenpipe.h
new file mode 100644
index 0000000000..f56be93a38
--- /dev/null
+++ b/src/util/tokenpipe.h
@@ -0,0 +1,127 @@
+// Copyright (c) 2021 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_UTIL_TOKENPIPE_H
+#define BITCOIN_UTIL_TOKENPIPE_H
+
+#ifndef WIN32
+
+#include <cstdint>
+#include <optional>
+
+/** One end of a token pipe. */
+class TokenPipeEnd
+{
+private:
+ int m_fd = -1;
+
+public:
+ TokenPipeEnd(int fd = -1);
+ ~TokenPipeEnd();
+
+ /** Return value constants for TokenWrite and TokenRead. */
+ enum Status {
+ TS_ERR = -1, //!< I/O error
+ TS_EOS = -2, //!< Unexpected end of stream
+ };
+
+ /** Write token to endpoint.
+ *
+ * @returns 0 If successful.
+ * <0 if error:
+ * TS_ERR If an error happened.
+ * TS_EOS If end of stream happened.
+ */
+ int TokenWrite(uint8_t token);
+
+ /** Read token from endpoint.
+ *
+ * @returns >=0 Token value, if successful.
+ * <0 if error:
+ * TS_ERR If an error happened.
+ * TS_EOS If end of stream happened.
+ */
+ int TokenRead();
+
+ /** Explicit close function.
+ */
+ void Close();
+
+ /** Return whether endpoint is open.
+ */
+ bool IsOpen() { return m_fd != -1; }
+
+ // Move-only class.
+ TokenPipeEnd(TokenPipeEnd&& other)
+ {
+ m_fd = other.m_fd;
+ other.m_fd = -1;
+ }
+ TokenPipeEnd& operator=(TokenPipeEnd&& other)
+ {
+ Close();
+ m_fd = other.m_fd;
+ other.m_fd = -1;
+ return *this;
+ }
+ TokenPipeEnd(const TokenPipeEnd&) = delete;
+ TokenPipeEnd& operator=(const TokenPipeEnd&) = delete;
+};
+
+/** An interprocess or interthread pipe for sending tokens (one-byte values)
+ * over.
+ */
+class TokenPipe
+{
+private:
+ int m_fds[2] = {-1, -1};
+
+ TokenPipe(int fds[2]) : m_fds{fds[0], fds[1]} {}
+
+public:
+ ~TokenPipe();
+
+ /** Create a new pipe.
+ * @returns The created TokenPipe, or an empty std::nullopt in case of error.
+ */
+ static std::optional<TokenPipe> Make();
+
+ /** Take the read end of this pipe. This can only be called once,
+ * as the object will be moved out.
+ */
+ TokenPipeEnd TakeReadEnd();
+
+ /** Take the write end of this pipe. This should only be called once,
+ * as the object will be moved out.
+ */
+ TokenPipeEnd TakeWriteEnd();
+
+ /** Close and end of the pipe that hasn't been moved out.
+ */
+ void Close();
+
+ // Move-only class.
+ TokenPipe(TokenPipe&& other)
+ {
+ for (int i = 0; i < 2; ++i) {
+ m_fds[i] = other.m_fds[i];
+ other.m_fds[i] = -1;
+ }
+ }
+ TokenPipe& operator=(TokenPipe&& other)
+ {
+ Close();
+ for (int i = 0; i < 2; ++i) {
+ m_fds[i] = other.m_fds[i];
+ other.m_fds[i] = -1;
+ }
+ return *this;
+ }
+ TokenPipe(const TokenPipe&) = delete;
+ TokenPipe& operator=(const TokenPipe&) = delete;
+};
+
+#endif // WIN32
+
+#endif // BITCOIN_UTIL_TOKENPIPE_H
diff --git a/src/validation.cpp b/src/validation.cpp
index e7439a2a1a..be0be904e9 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -1287,7 +1287,7 @@ CoinsViews::CoinsViews(
void CoinsViews::InitCache()
{
- m_cacheview = MakeUnique<CCoinsViewCache>(&m_catcherview);
+ m_cacheview = std::make_unique<CCoinsViewCache>(&m_catcherview);
}
CChainState::CChainState(CTxMemPool& mempool, BlockManager& blockman, uint256 from_snapshot_blockhash)
@@ -1305,7 +1305,7 @@ void CChainState::InitCoinsDB(
leveldb_name += "_" + m_from_snapshot_blockhash.ToString();
}
- m_coins_views = MakeUnique<CoinsViews>(
+ m_coins_views = std::make_unique<CoinsViews>(
leveldb_name, cache_size_bytes, in_memory, should_wipe);
}
@@ -5279,7 +5279,7 @@ bool ChainstateManager::ActivateSnapshot(
static_cast<size_t>(current_coinsdb_cache_size * IBD_CACHE_PERC));
}
- auto snapshot_chainstate = WITH_LOCK(::cs_main, return MakeUnique<CChainState>(
+ auto snapshot_chainstate = WITH_LOCK(::cs_main, return std::make_unique<CChainState>(
this->ActiveChainstate().m_mempool, m_blockman, base_blockhash));
{
@@ -5425,7 +5425,7 @@ bool ChainstateManager::PopulateAndValidateSnapshot(
// about the snapshot_chainstate.
CCoinsViewDB* snapshot_coinsdb = WITH_LOCK(::cs_main, return &snapshot_chainstate.CoinsDB());
- if (!GetUTXOStats(snapshot_coinsdb, stats, CoinStatsHashType::HASH_SERIALIZED, breakpoint_fnc)) {
+ if (!GetUTXOStats(snapshot_coinsdb, WITH_LOCK(::cs_main, return std::ref(m_blockman)), stats, CoinStatsHashType::HASH_SERIALIZED, breakpoint_fnc)) {
LogPrintf("[snapshot] failed to generate coins stats\n");
return false;
}
diff --git a/src/validation.h b/src/validation.h
index 74f8541934..512b306219 100644
--- a/src/validation.h
+++ b/src/validation.h
@@ -148,8 +148,6 @@ extern const std::vector<std::string> CHECKLEVEL_DOC;
FILE* OpenBlockFile(const FlatFilePos &pos, bool fReadOnly = false);
/** Translation to a filesystem path */
fs::path GetBlockPosFilename(const FlatFilePos &pos);
-/** Ensures we have a genesis block in the block tree, possibly writing one to disk. */
-bool LoadGenesisBlock(const CChainParams& chainparams);
/** Unload database information */
void UnloadBlockIndex(CTxMemPool* mempool, ChainstateManager& chainman);
/** Run instances of script checking worker threads */
@@ -725,6 +723,7 @@ public:
/** Replay blocks that aren't fully applied to the database. */
bool ReplayBlocks(const CChainParams& params);
bool RewindBlockIndex(const CChainParams& params) LOCKS_EXCLUDED(cs_main);
+ /** Ensures we have a genesis block in the block tree, possibly writing one to disk. */
bool LoadGenesisBlock(const CChainParams& chainparams);
void PruneBlockIndexCandidates();
diff --git a/src/wallet/bdb.cpp b/src/wallet/bdb.cpp
index ad40e6da9a..1dc23374e3 100644
--- a/src/wallet/bdb.cpp
+++ b/src/wallet/bdb.cpp
@@ -331,7 +331,7 @@ void BerkeleyDatabase::Open()
if (m_db == nullptr) {
int ret;
- std::unique_ptr<Db> pdb_temp = MakeUnique<Db>(env->dbenv.get(), 0);
+ std::unique_ptr<Db> pdb_temp = std::make_unique<Db>(env->dbenv.get(), 0);
bool fMockDb = env->IsMock();
if (fMockDb) {
@@ -462,7 +462,7 @@ bool BerkeleyDatabase::Rewrite(const char* pszSkip)
std::string strFileRes = strFile + ".rewrite";
{ // surround usage of db with extra {}
BerkeleyBatch db(*this, true);
- std::unique_ptr<Db> pdbCopy = MakeUnique<Db>(env->dbenv.get(), 0);
+ std::unique_ptr<Db> pdbCopy = std::make_unique<Db>(env->dbenv.get(), 0);
int ret = pdbCopy->open(nullptr, // Txn pointer
strFileRes.c_str(), // Filename
@@ -819,7 +819,7 @@ void BerkeleyDatabase::RemoveRef()
std::unique_ptr<DatabaseBatch> BerkeleyDatabase::MakeBatch(bool flush_on_close)
{
- return MakeUnique<BerkeleyBatch>(*this, false, flush_on_close);
+ return std::make_unique<BerkeleyBatch>(*this, false, flush_on_close);
}
std::unique_ptr<BerkeleyDatabase> MakeBerkeleyDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error)
@@ -835,7 +835,7 @@ std::unique_ptr<BerkeleyDatabase> MakeBerkeleyDatabase(const fs::path& path, con
status = DatabaseStatus::FAILED_ALREADY_LOADED;
return nullptr;
}
- db = MakeUnique<BerkeleyDatabase>(std::move(env), std::move(data_filename));
+ db = std::make_unique<BerkeleyDatabase>(std::move(env), std::move(data_filename));
}
if (options.verify && !db->Verify(error)) {
diff --git a/src/wallet/db.h b/src/wallet/db.h
index 2c75486a44..b64e9fa533 100644
--- a/src/wallet/db.h
+++ b/src/wallet/db.h
@@ -11,7 +11,6 @@
#include <optional.h>
#include <streams.h>
#include <support/allocators/secure.h>
-#include <util/memory.h>
#include <atomic>
#include <memory>
@@ -193,7 +192,7 @@ public:
void ReloadDbEnv() override {}
std::string Filename() override { return "dummy"; }
std::string Format() override { return "dummy"; }
- std::unique_ptr<DatabaseBatch> MakeBatch(bool flush_on_close = true) override { return MakeUnique<DummyBatch>(); }
+ std::unique_ptr<DatabaseBatch> MakeBatch(bool flush_on_close = true) override { return std::make_unique<DummyBatch>(); }
};
enum class DatabaseFormat {
diff --git a/src/wallet/interfaces.cpp b/src/wallet/interfaces.cpp
index 1fb789b128..ada586119a 100644
--- a/src/wallet/interfaces.cpp
+++ b/src/wallet/interfaces.cpp
@@ -588,10 +588,10 @@ public:
} // namespace wallet
namespace interfaces {
-std::unique_ptr<Wallet> MakeWallet(const std::shared_ptr<CWallet>& wallet) { return wallet ? MakeUnique<wallet::WalletImpl>(wallet) : nullptr; }
+std::unique_ptr<Wallet> MakeWallet(const std::shared_ptr<CWallet>& wallet) { return wallet ? std::make_unique<wallet::WalletImpl>(wallet) : nullptr; }
std::unique_ptr<WalletClient> MakeWalletClient(Chain& chain, ArgsManager& args)
{
- return MakeUnique<wallet::WalletClientImpl>(chain, args);
+ return std::make_unique<wallet::WalletClientImpl>(chain, args);
}
} // namespace interfaces
diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp
index a2872f10ae..50423c3e32 100644
--- a/src/wallet/rpcdump.cpp
+++ b/src/wallet/rpcdump.cpp
@@ -56,13 +56,13 @@ static std::string DecodeDumpString(const std::string &str) {
return ret.str();
}
-static bool GetWalletAddressesForKey(LegacyScriptPubKeyMan* spk_man, const CWallet* const pwallet, const CKeyID& keyid, std::string& strAddr, std::string& strLabel) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet)
+static bool GetWalletAddressesForKey(LegacyScriptPubKeyMan* spk_man, const CWallet& wallet, const CKeyID& keyid, std::string& strAddr, std::string& strLabel) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
{
bool fLabelFound = false;
CKey key;
spk_man->GetKey(keyid, key);
for (const auto& dest : GetAllDestinationsForKey(key.GetPubKey())) {
- const auto* address_book_entry = pwallet->FindAddressBookEntry(dest);
+ const auto* address_book_entry = wallet.FindAddressBookEntry(dest);
if (address_book_entry) {
if (!strAddr.empty()) {
strAddr += ",";
@@ -73,7 +73,7 @@ static bool GetWalletAddressesForKey(LegacyScriptPubKeyMan* spk_man, const CWall
}
}
if (!fLabelFound) {
- strAddr = EncodeDestination(GetDestinationForKey(key.GetPubKey(), pwallet->m_default_address_type));
+ strAddr = EncodeDestination(GetDestinationForKey(key.GetPubKey(), wallet.m_default_address_type));
}
return fLabelFound;
}
@@ -118,22 +118,21 @@ RPCHelpMan importprivkey()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
if (pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Cannot import private keys to a wallet with private keys disabled");
}
- EnsureLegacyScriptPubKeyMan(*wallet, true);
+ EnsureLegacyScriptPubKeyMan(*pwallet, true);
WalletRescanReserver reserver(*pwallet);
bool fRescan = true;
{
LOCK(pwallet->cs_wallet);
- EnsureWalletIsUnlocked(pwallet);
+ EnsureWalletIsUnlocked(*pwallet);
std::string strSecret = request.params[0].get_str();
std::string strLabel = "";
@@ -210,9 +209,8 @@ RPCHelpMan abortrescan()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
if (!pwallet->IsScanning() || pwallet->IsAbortingRescan()) return false;
pwallet->AbortRescan();
@@ -249,9 +247,8 @@ RPCHelpMan importaddress()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
EnsureLegacyScriptPubKeyMan(*pwallet, true);
@@ -335,9 +332,8 @@ RPCHelpMan importprunedfunds()
RPCExamples{""},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
CMutableTransaction tx;
if (!DecodeHexTx(tx, request.params[0].get_str())) {
@@ -397,9 +393,8 @@ RPCHelpMan removeprunedfunds()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
LOCK(pwallet->cs_wallet);
@@ -445,11 +440,10 @@ RPCHelpMan importpubkey()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
- EnsureLegacyScriptPubKeyMan(*wallet, true);
+ EnsureLegacyScriptPubKeyMan(*pwallet, true);
std::string strLabel;
if (!request.params[1].isNull())
@@ -527,11 +521,10 @@ RPCHelpMan importwallet()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
- EnsureLegacyScriptPubKeyMan(*wallet, true);
+ EnsureLegacyScriptPubKeyMan(*pwallet, true);
if (pwallet->chain().havePruned()) {
// Exit early and print an error.
@@ -550,7 +543,7 @@ RPCHelpMan importwallet()
{
LOCK(pwallet->cs_wallet);
- EnsureWalletIsUnlocked(pwallet);
+ EnsureWalletIsUnlocked(*pwallet);
fsbridge::ifstream file;
file.open(request.params[0].get_str(), std::ios::in | std::ios::ate);
@@ -684,15 +677,14 @@ RPCHelpMan dumpprivkey()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- const CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
- LegacyScriptPubKeyMan& spk_man = EnsureLegacyScriptPubKeyMan(*wallet);
+ LegacyScriptPubKeyMan& spk_man = EnsureLegacyScriptPubKeyMan(*pwallet);
LOCK2(pwallet->cs_wallet, spk_man.cs_KeyStore);
- EnsureWalletIsUnlocked(pwallet);
+ EnsureWalletIsUnlocked(*pwallet);
std::string strAddress = request.params[0].get_str();
CTxDestination dest = DecodeDestination(strAddress);
@@ -747,7 +739,7 @@ RPCHelpMan dumpwallet()
LOCK2(wallet.cs_wallet, spk_man.cs_KeyStore);
- EnsureWalletIsUnlocked(&wallet);
+ EnsureWalletIsUnlocked(wallet);
fs::path filepath = request.params[0].get_str();
filepath = fs::absolute(filepath);
@@ -809,7 +801,7 @@ RPCHelpMan dumpwallet()
CKey key;
if (spk_man.GetKey(keyid, key)) {
file << strprintf("%s %s ", EncodeSecret(key), strTime);
- if (GetWalletAddressesForKey(&spk_man, &wallet, keyid, strAddr, strLabel)) {
+ if (GetWalletAddressesForKey(&spk_man, wallet, keyid, strAddr, strLabel)) {
file << strprintf("label=%s", strLabel);
} else if (keyid == seed_id) {
file << "hdseed=1";
@@ -990,14 +982,14 @@ static UniValue ProcessImportLegacy(ImportData& import_data, std::map<CKeyID, CP
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid redeem script \"" + strRedeemScript + "\": must be hex string");
}
auto parsed_redeemscript = ParseHex(strRedeemScript);
- import_data.redeemscript = MakeUnique<CScript>(parsed_redeemscript.begin(), parsed_redeemscript.end());
+ import_data.redeemscript = std::make_unique<CScript>(parsed_redeemscript.begin(), parsed_redeemscript.end());
}
if (witness_script_hex.size()) {
if (!IsHex(witness_script_hex)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid witness script \"" + witness_script_hex + "\": must be hex string");
}
auto parsed_witnessscript = ParseHex(witness_script_hex);
- import_data.witnessscript = MakeUnique<CScript>(parsed_witnessscript.begin(), parsed_witnessscript.end());
+ import_data.witnessscript = std::make_unique<CScript>(parsed_witnessscript.begin(), parsed_witnessscript.end());
}
for (size_t i = 0; i < pubKeys.size(); ++i) {
const auto& str = pubKeys[i].get_str();
@@ -1169,7 +1161,7 @@ static UniValue ProcessImportDescriptor(ImportData& import_data, std::map<CKeyID
return warnings;
}
-static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet)
+static UniValue ProcessImport(CWallet& wallet, const UniValue& data, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
{
UniValue warnings(UniValue::VARR);
UniValue result(UniValue::VOBJ);
@@ -1184,7 +1176,7 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
const bool add_keypool = data.exists("keypool") ? data["keypool"].get_bool() : false;
// Add to keypool only works with privkeys disabled
- if (add_keypool && !pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
+ if (add_keypool && !wallet.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Keys can only be imported to the keypool when private keys are disabled");
}
@@ -1206,29 +1198,29 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
}
// If private keys are disabled, abort if private keys are being imported
- if (pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS) && !privkey_map.empty()) {
+ if (wallet.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS) && !privkey_map.empty()) {
throw JSONRPCError(RPC_WALLET_ERROR, "Cannot import private keys to a wallet with private keys disabled");
}
// Check whether we have any work to do
for (const CScript& script : script_pub_keys) {
- if (pwallet->IsMine(script) & ISMINE_SPENDABLE) {
+ if (wallet.IsMine(script) & ISMINE_SPENDABLE) {
throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script (\"" + HexStr(script) + "\")");
}
}
// All good, time to import
- pwallet->MarkDirty();
- if (!pwallet->ImportScripts(import_data.import_scripts, timestamp)) {
+ wallet.MarkDirty();
+ if (!wallet.ImportScripts(import_data.import_scripts, timestamp)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding script to wallet");
}
- if (!pwallet->ImportPrivKeys(privkey_map, timestamp)) {
+ if (!wallet.ImportPrivKeys(privkey_map, timestamp)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet");
}
- if (!pwallet->ImportPubKeys(ordered_pubkeys, pubkey_map, import_data.key_origins, add_keypool, internal, timestamp)) {
+ if (!wallet.ImportPubKeys(ordered_pubkeys, pubkey_map, import_data.key_origins, add_keypool, internal, timestamp)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
}
- if (!pwallet->ImportScriptPubKeys(label, script_pub_keys, have_solving_data, !internal, timestamp)) {
+ if (!wallet.ImportScriptPubKeys(label, script_pub_keys, have_solving_data, !internal, timestamp)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
}
@@ -1336,13 +1328,12 @@ RPCHelpMan importmulti()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& mainRequest) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(mainRequest);
- if (!wallet) return NullUniValue;
- CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(mainRequest);
+ if (!pwallet) return NullUniValue;
RPCTypeCheck(mainRequest.params, {UniValue::VARR, UniValue::VOBJ});
- EnsureLegacyScriptPubKeyMan(*wallet, true);
+ EnsureLegacyScriptPubKeyMan(*pwallet, true);
const UniValue& requests = mainRequest.params[0];
@@ -1368,7 +1359,7 @@ RPCHelpMan importmulti()
UniValue response(UniValue::VARR);
{
LOCK(pwallet->cs_wallet);
- EnsureWalletIsUnlocked(pwallet);
+ EnsureWalletIsUnlocked(*pwallet);
// Verify all timestamps are present before importing any keys.
CHECK_NONFATAL(pwallet->chain().findBlock(pwallet->GetLastBlockHash(), FoundBlock().time(nLowestTimestamp).mtpTime(now)));
@@ -1380,7 +1371,7 @@ RPCHelpMan importmulti()
for (const UniValue& data : requests.getValues()) {
const int64_t timestamp = std::max(GetImportTimestamp(data, now), minimumTimestamp);
- const UniValue result = ProcessImport(pwallet, data, timestamp);
+ const UniValue result = ProcessImport(*pwallet, data, timestamp);
response.push_back(result);
if (!fRescan) {
@@ -1447,7 +1438,7 @@ RPCHelpMan importmulti()
};
}
-static UniValue ProcessDescriptorImport(CWallet * const pwallet, const UniValue& data, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet)
+static UniValue ProcessDescriptorImport(CWallet& wallet, const UniValue& data, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
{
UniValue warnings(UniValue::VARR);
UniValue result(UniValue::VOBJ);
@@ -1516,7 +1507,7 @@ static UniValue ProcessDescriptorImport(CWallet * const pwallet, const UniValue&
}
// If the wallet disabled private keys, abort if private keys exist
- if (pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS) && !keys.keys.empty()) {
+ if (wallet.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS) && !keys.keys.empty()) {
throw JSONRPCError(RPC_WALLET_ERROR, "Cannot import private keys to a wallet with private keys disabled");
}
@@ -1540,7 +1531,7 @@ static UniValue ProcessDescriptorImport(CWallet * const pwallet, const UniValue&
}
// If private keys are enabled, check some things.
- if (!pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
+ if (!wallet.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
if (keys.keys.empty()) {
throw JSONRPCError(RPC_WALLET_ERROR, "Cannot import descriptor without private keys to a wallet with private keys enabled");
}
@@ -1552,7 +1543,7 @@ static UniValue ProcessDescriptorImport(CWallet * const pwallet, const UniValue&
WalletDescriptor w_desc(std::move(parsed_desc), timestamp, range_start, range_end, next_index);
// Check if the wallet already contains the descriptor
- auto existing_spk_manager = pwallet->GetDescriptorScriptPubKeyMan(w_desc);
+ auto existing_spk_manager = wallet.GetDescriptorScriptPubKeyMan(w_desc);
if (existing_spk_manager) {
LOCK(existing_spk_manager->cs_desc_man);
if (range_start > existing_spk_manager->GetWalletDescriptor().range_start) {
@@ -1561,7 +1552,7 @@ static UniValue ProcessDescriptorImport(CWallet * const pwallet, const UniValue&
}
// Add descriptor to the wallet
- auto spk_manager = pwallet->AddWalletDescriptor(w_desc, keys, label, internal);
+ auto spk_manager = wallet.AddWalletDescriptor(w_desc, keys, label, internal);
if (spk_manager == nullptr) {
throw JSONRPCError(RPC_WALLET_ERROR, strprintf("Could not add descriptor '%s'", descriptor));
}
@@ -1571,7 +1562,7 @@ static UniValue ProcessDescriptorImport(CWallet * const pwallet, const UniValue&
if (!w_desc.descriptor->GetOutputType()) {
warnings.push_back("Unknown output type, cannot set descriptor to active.");
} else {
- pwallet->AddActiveScriptPubKeyMan(spk_manager->GetID(), *w_desc.descriptor->GetOutputType(), internal);
+ wallet.AddActiveScriptPubKeyMan(spk_manager->GetID(), *w_desc.descriptor->GetOutputType(), internal);
}
}
@@ -1641,9 +1632,8 @@ RPCHelpMan importdescriptors()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& main_request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(main_request);
- if (!wallet) return NullUniValue;
- CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(main_request);
+ if (!pwallet) return NullUniValue;
// Make sure wallet is a descriptor wallet
if (!pwallet->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) {
@@ -1665,7 +1655,7 @@ RPCHelpMan importdescriptors()
UniValue response(UniValue::VARR);
{
LOCK(pwallet->cs_wallet);
- EnsureWalletIsUnlocked(pwallet);
+ EnsureWalletIsUnlocked(*pwallet);
CHECK_NONFATAL(pwallet->chain().findBlock(pwallet->GetLastBlockHash(), FoundBlock().time(lowest_timestamp).mtpTime(now)));
@@ -1673,7 +1663,7 @@ RPCHelpMan importdescriptors()
for (const UniValue& request : requests.getValues()) {
// This throws an error if "timestamp" doesn't exist
const int64_t timestamp = std::max(GetImportTimestamp(request, now), minimum_timestamp);
- const UniValue result = ProcessDescriptorImport(pwallet, request, timestamp);
+ const UniValue result = ProcessDescriptorImport(*pwallet, request, timestamp);
response.push_back(result);
if (lowest_timestamp > timestamp ) {
@@ -1775,7 +1765,7 @@ RPCHelpMan listdescriptors()
throw JSONRPCError(RPC_WALLET_ERROR, "listdescriptors is not available for non-descriptor wallets");
}
- EnsureWalletIsUnlocked(wallet.get());
+ EnsureWalletIsUnlocked(*wallet);
LOCK(wallet->cs_wallet);
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index 6d6cdedb2b..1b9071a712 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -48,8 +48,8 @@ using interfaces::FoundBlock;
static const std::string WALLET_ENDPOINT_BASE = "/wallet/";
static const std::string HELP_REQUIRING_PASSPHRASE{"\nRequires wallet passphrase to be set with walletpassphrase call if wallet is encrypted.\n"};
-static inline bool GetAvoidReuseFlag(const CWallet* const pwallet, const UniValue& param) {
- bool can_avoid_reuse = pwallet->IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE);
+static inline bool GetAvoidReuseFlag(const CWallet& wallet, const UniValue& param) {
+ bool can_avoid_reuse = wallet.IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE);
bool avoid_reuse = param.isNull() ? can_avoid_reuse : param.get_bool();
if (avoid_reuse && !can_avoid_reuse) {
@@ -64,11 +64,11 @@ static inline bool GetAvoidReuseFlag(const CWallet* const pwallet, const UniValu
* We default to true for watchonly wallets if include_watchonly isn't
* explicitly set.
*/
-static bool ParseIncludeWatchonly(const UniValue& include_watchonly, const CWallet& pwallet)
+static bool ParseIncludeWatchonly(const UniValue& include_watchonly, const CWallet& wallet)
{
if (include_watchonly.isNull()) {
// if include_watchonly isn't explicitly set, then check if we have a watchonly wallet
- return pwallet.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS);
+ return wallet.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS);
}
// otherwise return whatever include_watchonly was set to
@@ -96,7 +96,7 @@ bool GetWalletNameFromJSONRPCRequest(const JSONRPCRequest& request, std::string&
std::shared_ptr<CWallet> GetWalletForJSONRPCRequest(const JSONRPCRequest& request)
{
- CHECK_NONFATAL(!request.fHelp);
+ CHECK_NONFATAL(request.mode == JSONRPCRequest::EXECUTE);
std::string wallet_name;
if (GetWalletNameFromJSONRPCRequest(request, wallet_name)) {
std::shared_ptr<CWallet> pwallet = GetWallet(wallet_name);
@@ -117,9 +117,9 @@ std::shared_ptr<CWallet> GetWalletForJSONRPCRequest(const JSONRPCRequest& reques
"Wallet file not specified (must request wallet RPC through /wallet/<filename> uri-path).");
}
-void EnsureWalletIsUnlocked(const CWallet* pwallet)
+void EnsureWalletIsUnlocked(const CWallet& wallet)
{
- if (pwallet->IsLocked()) {
+ if (wallet.IsLocked()) {
throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first.");
}
}
@@ -249,9 +249,8 @@ static RPCHelpMan getnewaddress()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
LOCK(pwallet->cs_wallet);
@@ -299,9 +298,8 @@ static RPCHelpMan getrawchangeaddress()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
LOCK(pwallet->cs_wallet);
@@ -342,9 +340,8 @@ static RPCHelpMan setlabel()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
LOCK(pwallet->cs_wallet);
@@ -396,13 +393,13 @@ void ParseRecipients(const UniValue& address_amounts, const UniValue& subtract_f
}
}
-UniValue SendMoney(CWallet* const pwallet, const CCoinControl &coin_control, std::vector<CRecipient> &recipients, mapValue_t map_value, bool verbose)
+UniValue SendMoney(CWallet& wallet, const CCoinControl &coin_control, std::vector<CRecipient> &recipients, mapValue_t map_value, bool verbose)
{
- EnsureWalletIsUnlocked(pwallet);
+ EnsureWalletIsUnlocked(wallet);
// This function is only used by sendtoaddress and sendmany.
// This should always try to sign, if we don't have private keys, don't try to do anything here.
- if (pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
+ if (wallet.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Error: Private keys are disabled for this wallet");
}
@@ -415,11 +412,11 @@ UniValue SendMoney(CWallet* const pwallet, const CCoinControl &coin_control, std
bilingual_str error;
CTransactionRef tx;
FeeCalculation fee_calc_out;
- const bool fCreated = pwallet->CreateTransaction(recipients, tx, nFeeRequired, nChangePosRet, error, coin_control, fee_calc_out, true);
+ const bool fCreated = wallet.CreateTransaction(recipients, tx, nFeeRequired, nChangePosRet, error, coin_control, fee_calc_out, true);
if (!fCreated) {
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, error.original);
}
- pwallet->CommitTransaction(tx, std::move(map_value), {} /* orderForm */);
+ wallet.CommitTransaction(tx, std::move(map_value), {} /* orderForm */);
if (verbose) {
UniValue entry(UniValue::VOBJ);
entry.pushKV("txid", tx->GetHash().GetHex());
@@ -480,9 +477,8 @@ static RPCHelpMan sendtoaddress()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
// Make sure the results are valid at least up to the most recent block
// the user could have gotten from another RPC command prior to now
@@ -507,13 +503,13 @@ static RPCHelpMan sendtoaddress()
coin_control.m_signal_bip125_rbf = request.params[5].get_bool();
}
- coin_control.m_avoid_address_reuse = GetAvoidReuseFlag(pwallet, request.params[8]);
+ coin_control.m_avoid_address_reuse = GetAvoidReuseFlag(*pwallet, request.params[8]);
// We also enable partial spend avoidance if reuse avoidance is set.
coin_control.m_avoid_partial_spends |= coin_control.m_avoid_address_reuse;
SetFeeEstimateMode(*pwallet, coin_control, /* conf_target */ request.params[6], /* estimate_mode */ request.params[7], /* fee_rate */ request.params[9], /* override_min_fee */ false);
- EnsureWalletIsUnlocked(pwallet);
+ EnsureWalletIsUnlocked(*pwallet);
UniValue address_amounts(UniValue::VOBJ);
const std::string address = request.params[0].get_str();
@@ -527,7 +523,7 @@ static RPCHelpMan sendtoaddress()
ParseRecipients(address_amounts, subtractFeeFromAmount, recipients);
const bool verbose{request.params[10].isNull() ? false : request.params[10].get_bool()};
- return SendMoney(pwallet, coin_control, recipients, mapValue, verbose);
+ return SendMoney(*pwallet, coin_control, recipients, mapValue, verbose);
},
};
}
@@ -559,9 +555,8 @@ static RPCHelpMan listaddressgroupings()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- const CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
// Make sure the results are valid at least up to the most recent block
// the user could have gotten from another RPC command prior to now
@@ -617,13 +612,12 @@ static RPCHelpMan signmessage()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- const CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
LOCK(pwallet->cs_wallet);
- EnsureWalletIsUnlocked(pwallet);
+ EnsureWalletIsUnlocked(*pwallet);
std::string strAddress = request.params[0].get_str();
std::string strMessage = request.params[1].get_str();
@@ -720,9 +714,8 @@ static RPCHelpMan getreceivedbyaddress()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- const CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
// Make sure the results are valid at least up to the most recent block
// the user could have gotten from another RPC command prior to now
@@ -759,9 +752,8 @@ static RPCHelpMan getreceivedbylabel()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- const CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
// Make sure the results are valid at least up to the most recent block
// the user could have gotten from another RPC command prior to now
@@ -800,9 +792,8 @@ static RPCHelpMan getbalance()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- const CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
// Make sure the results are valid at least up to the most recent block
// the user could have gotten from another RPC command prior to now
@@ -822,7 +813,7 @@ static RPCHelpMan getbalance()
bool include_watchonly = ParseIncludeWatchonly(request.params[2], *pwallet);
- bool avoid_reuse = GetAvoidReuseFlag(pwallet, request.params[3]);
+ bool avoid_reuse = GetAvoidReuseFlag(*pwallet, request.params[3]);
const auto bal = pwallet->GetBalance(min_depth, avoid_reuse);
@@ -840,9 +831,8 @@ static RPCHelpMan getunconfirmedbalance()
RPCExamples{""},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- const CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
// Make sure the results are valid at least up to the most recent block
// the user could have gotten from another RPC command prior to now
@@ -911,9 +901,8 @@ static RPCHelpMan sendmany()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
// Make sure the results are valid at least up to the most recent block
// the user could have gotten from another RPC command prior to now
@@ -945,7 +934,7 @@ static RPCHelpMan sendmany()
ParseRecipients(sendTo, subtractFeeFromAmount, recipients);
const bool verbose{request.params[9].isNull() ? false : request.params[9].get_bool()};
- return SendMoney(pwallet, coin_control, recipients, std::move(mapValue), verbose);
+ return SendMoney(*pwallet, coin_control, recipients, std::move(mapValue), verbose);
},
};
}
@@ -985,9 +974,8 @@ static RPCHelpMan addmultisigaddress()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
LegacyScriptPubKeyMan& spk_man = EnsureLegacyScriptPubKeyMan(*pwallet);
@@ -1045,7 +1033,7 @@ struct tallyitem
}
};
-static UniValue ListReceived(const CWallet* const pwallet, const UniValue& params, bool by_label) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet)
+static UniValue ListReceived(const CWallet& wallet, const UniValue& params, bool by_label) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
{
// Minimum confirmations
int nMinDepth = 1;
@@ -1059,7 +1047,7 @@ static UniValue ListReceived(const CWallet* const pwallet, const UniValue& param
isminefilter filter = ISMINE_SPENDABLE;
- if (ParseIncludeWatchonly(params[2], *pwallet)) {
+ if (ParseIncludeWatchonly(params[2], wallet)) {
filter |= ISMINE_WATCH_ONLY;
}
@@ -1075,10 +1063,10 @@ static UniValue ListReceived(const CWallet* const pwallet, const UniValue& param
// Tally
std::map<CTxDestination, tallyitem> mapTally;
- for (const std::pair<const uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
+ for (const std::pair<const uint256, CWalletTx>& pairWtx : wallet.mapWallet) {
const CWalletTx& wtx = pairWtx.second;
- if (wtx.IsCoinBase() || !pwallet->chain().checkFinalTx(*wtx.tx)) {
+ if (wtx.IsCoinBase() || !wallet.chain().checkFinalTx(*wtx.tx)) {
continue;
}
@@ -1096,7 +1084,7 @@ static UniValue ListReceived(const CWallet* const pwallet, const UniValue& param
continue;
}
- isminefilter mine = pwallet->IsMine(address);
+ isminefilter mine = wallet.IsMine(address);
if(!(mine & filter))
continue;
@@ -1115,11 +1103,11 @@ static UniValue ListReceived(const CWallet* const pwallet, const UniValue& param
// Create m_address_book iterator
// If we aren't filtering, go from begin() to end()
- auto start = pwallet->m_address_book.begin();
- auto end = pwallet->m_address_book.end();
+ auto start = wallet.m_address_book.begin();
+ auto end = wallet.m_address_book.end();
// If we are filtering, find() the applicable entry
if (has_filtered_address) {
- start = pwallet->m_address_book.find(filtered_address);
+ start = wallet.m_address_book.find(filtered_address);
if (start != end) {
end = std::next(start);
}
@@ -1227,9 +1215,8 @@ static RPCHelpMan listreceivedbyaddress()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- const CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
// Make sure the results are valid at least up to the most recent block
// the user could have gotten from another RPC command prior to now
@@ -1237,7 +1224,7 @@ static RPCHelpMan listreceivedbyaddress()
LOCK(pwallet->cs_wallet);
- return ListReceived(pwallet, request.params, false);
+ return ListReceived(*pwallet, request.params, false);
},
};
}
@@ -1270,9 +1257,8 @@ static RPCHelpMan listreceivedbylabel()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- const CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
// Make sure the results are valid at least up to the most recent block
// the user could have gotten from another RPC command prior to now
@@ -1280,7 +1266,7 @@ static RPCHelpMan listreceivedbylabel()
LOCK(pwallet->cs_wallet);
- return ListReceived(pwallet, request.params, true);
+ return ListReceived(*pwallet, request.params, true);
},
};
}
@@ -1303,7 +1289,7 @@ static void MaybePushAddress(UniValue & entry, const CTxDestination &dest)
* @param filter_ismine The "is mine" filter flags.
* @param filter_label Optional label string to filter incoming transactions.
*/
-static void ListTransactions(const CWallet* const pwallet, const CWalletTx& wtx, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter_ismine, const std::string* filter_label) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet)
+static void ListTransactions(const CWallet& wallet, const CWalletTx& wtx, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter_ismine, const std::string* filter_label) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
{
CAmount nFee;
std::list<COutputEntry> listReceived;
@@ -1319,20 +1305,20 @@ static void ListTransactions(const CWallet* const pwallet, const CWalletTx& wtx,
for (const COutputEntry& s : listSent)
{
UniValue entry(UniValue::VOBJ);
- if (involvesWatchonly || (pwallet->IsMine(s.destination) & ISMINE_WATCH_ONLY)) {
+ if (involvesWatchonly || (wallet.IsMine(s.destination) & ISMINE_WATCH_ONLY)) {
entry.pushKV("involvesWatchonly", true);
}
MaybePushAddress(entry, s.destination);
entry.pushKV("category", "send");
entry.pushKV("amount", ValueFromAmount(-s.amount));
- const auto* address_book_entry = pwallet->FindAddressBookEntry(s.destination);
+ const auto* address_book_entry = wallet.FindAddressBookEntry(s.destination);
if (address_book_entry) {
entry.pushKV("label", address_book_entry->GetLabel());
}
entry.pushKV("vout", s.vout);
entry.pushKV("fee", ValueFromAmount(-nFee));
if (fLong)
- WalletTxToJSON(pwallet->chain(), wtx, entry);
+ WalletTxToJSON(wallet.chain(), wtx, entry);
entry.pushKV("abandoned", wtx.isAbandoned());
ret.push_back(entry);
}
@@ -1343,7 +1329,7 @@ static void ListTransactions(const CWallet* const pwallet, const CWalletTx& wtx,
for (const COutputEntry& r : listReceived)
{
std::string label;
- const auto* address_book_entry = pwallet->FindAddressBookEntry(r.destination);
+ const auto* address_book_entry = wallet.FindAddressBookEntry(r.destination);
if (address_book_entry) {
label = address_book_entry->GetLabel();
}
@@ -1351,7 +1337,7 @@ static void ListTransactions(const CWallet* const pwallet, const CWalletTx& wtx,
continue;
}
UniValue entry(UniValue::VOBJ);
- if (involvesWatchonly || (pwallet->IsMine(r.destination) & ISMINE_WATCH_ONLY)) {
+ if (involvesWatchonly || (wallet.IsMine(r.destination) & ISMINE_WATCH_ONLY)) {
entry.pushKV("involvesWatchonly", true);
}
MaybePushAddress(entry, r.destination);
@@ -1374,7 +1360,7 @@ static void ListTransactions(const CWallet* const pwallet, const CWalletTx& wtx,
}
entry.pushKV("vout", r.vout);
if (fLong)
- WalletTxToJSON(pwallet->chain(), wtx, entry);
+ WalletTxToJSON(wallet.chain(), wtx, entry);
ret.push_back(entry);
}
}
@@ -1451,9 +1437,8 @@ static RPCHelpMan listtransactions()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- const CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
// Make sure the results are valid at least up to the most recent block
// the user could have gotten from another RPC command prior to now
@@ -1494,7 +1479,7 @@ static RPCHelpMan listtransactions()
for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)
{
CWalletTx *const pwtx = (*it).second;
- ListTransactions(pwallet, *pwtx, 0, true, ret, filter, filter_label);
+ ListTransactions(*pwallet, *pwtx, 0, true, ret, filter, filter_label);
if ((int)ret.size() >= (nCount+nFrom)) break;
}
}
@@ -1616,7 +1601,7 @@ static RPCHelpMan listsinceblock()
const CWalletTx& tx = pairWtx.second;
if (depth == -1 || abs(tx.GetDepthInMainChain()) < depth) {
- ListTransactions(&wallet, tx, 0, true, transactions, filter, nullptr /* filter_label */);
+ ListTransactions(wallet, tx, 0, true, transactions, filter, nullptr /* filter_label */);
}
}
@@ -1633,7 +1618,7 @@ static RPCHelpMan listsinceblock()
if (it != wallet.mapWallet.end()) {
// We want all transactions regardless of confirmation count to appear here,
// even negative confirmation ones, hence the big negative.
- ListTransactions(&wallet, it->second, -100000000, true, removed, filter, nullptr /* filter_label */);
+ ListTransactions(wallet, it->second, -100000000, true, removed, filter, nullptr /* filter_label */);
}
}
blockId = block.hashPrevBlock;
@@ -1710,9 +1695,8 @@ static RPCHelpMan gettransaction()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- const CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
// Make sure the results are valid at least up to the most recent block
// the user could have gotten from another RPC command prior to now
@@ -1749,7 +1733,7 @@ static RPCHelpMan gettransaction()
WalletTxToJSON(pwallet->chain(), wtx, entry);
UniValue details(UniValue::VARR);
- ListTransactions(pwallet, wtx, 0, false, details, filter, nullptr /* filter_label */);
+ ListTransactions(*pwallet, wtx, 0, false, details, filter, nullptr /* filter_label */);
entry.pushKV("details", details);
std::string strHex = EncodeHexTx(*wtx.tx, pwallet->chain().rpcSerializationFlags());
@@ -1784,9 +1768,8 @@ static RPCHelpMan abandontransaction()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
// Make sure the results are valid at least up to the most recent block
// the user could have gotten from another RPC command prior to now
@@ -1823,9 +1806,8 @@ static RPCHelpMan backupwallet()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- const CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
// Make sure the results are valid at least up to the most recent block
// the user could have gotten from another RPC command prior to now
@@ -1859,9 +1841,8 @@ static RPCHelpMan keypoolrefill()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
if (pwallet->IsLegacy() && pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Error: Private keys are disabled for this wallet");
@@ -1877,7 +1858,7 @@ static RPCHelpMan keypoolrefill()
kpSize = (unsigned int)request.params[0].get_int();
}
- EnsureWalletIsUnlocked(pwallet);
+ EnsureWalletIsUnlocked(*pwallet);
pwallet->TopUpKeyPool(kpSize);
if (pwallet->GetKeyPoolSize() < kpSize) {
@@ -2001,9 +1982,8 @@ static RPCHelpMan walletpassphrasechange()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
LOCK(pwallet->cs_wallet);
@@ -2055,9 +2035,8 @@ static RPCHelpMan walletlock()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
LOCK(pwallet->cs_wallet);
@@ -2100,9 +2079,8 @@ static RPCHelpMan encryptwallet()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
LOCK(pwallet->cs_wallet);
@@ -2174,9 +2152,8 @@ static RPCHelpMan lockunspent()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
// Make sure the results are valid at least up to the most recent block
// the user could have gotten from another RPC command prior to now
@@ -2289,9 +2266,8 @@ static RPCHelpMan listlockunspent()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- const CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
LOCK(pwallet->cs_wallet);
@@ -2330,9 +2306,8 @@ static RPCHelpMan settxfee()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
LOCK(pwallet->cs_wallet);
@@ -2460,9 +2435,8 @@ static RPCHelpMan getwalletinfo()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- const CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
// Make sure the results are valid at least up to the most recent block
// the user could have gotten from another RPC command prior to now
@@ -2672,9 +2646,8 @@ static RPCHelpMan setwalletflag()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
std::string flag_str = request.params[0].get_str();
bool value = request.params[1].isNull() || request.params[1].get_bool();
@@ -2916,9 +2889,8 @@ static RPCHelpMan listunspent()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- const CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
int nMinDepth = 1;
if (!request.params[0].isNull()) {
@@ -3080,11 +3052,11 @@ static RPCHelpMan listunspent()
};
}
-void FundTransaction(CWallet* const pwallet, CMutableTransaction& tx, CAmount& fee_out, int& change_position, const UniValue& options, CCoinControl& coinControl, bool override_min_fee)
+void FundTransaction(CWallet& wallet, CMutableTransaction& tx, CAmount& fee_out, int& change_position, const UniValue& options, CCoinControl& coinControl, bool override_min_fee)
{
// Make sure the results are valid at least up to the most recent block
// the user could have gotten from another RPC command prior to now
- pwallet->BlockUntilSyncedToCurrentChain();
+ wallet.BlockUntilSyncedToCurrentChain();
change_position = -1;
bool lockUnspents = false;
@@ -3155,7 +3127,7 @@ void FundTransaction(CWallet* const pwallet, CMutableTransaction& tx, CAmount& f
}
const UniValue include_watching_option = options.exists("include_watching") ? options["include_watching"] : options["includeWatching"];
- coinControl.fAllowWatchOnly = ParseIncludeWatchonly(include_watching_option, *pwallet);
+ coinControl.fAllowWatchOnly = ParseIncludeWatchonly(include_watching_option, wallet);
if (options.exists("lockUnspents") || options.exists("lock_unspents")) {
lockUnspents = (options.exists("lock_unspents") ? options["lock_unspents"] : options["lockUnspents"]).get_bool();
@@ -3181,11 +3153,11 @@ void FundTransaction(CWallet* const pwallet, CMutableTransaction& tx, CAmount& f
if (options.exists("replaceable")) {
coinControl.m_signal_bip125_rbf = options["replaceable"].get_bool();
}
- SetFeeEstimateMode(*pwallet, coinControl, options["conf_target"], options["estimate_mode"], options["fee_rate"], override_min_fee);
+ SetFeeEstimateMode(wallet, coinControl, options["conf_target"], options["estimate_mode"], options["fee_rate"], override_min_fee);
}
} else {
// if options is null and not a bool
- coinControl.fAllowWatchOnly = ParseIncludeWatchonly(NullUniValue, *pwallet);
+ coinControl.fAllowWatchOnly = ParseIncludeWatchonly(NullUniValue, wallet);
}
if (tx.vout.size() == 0)
@@ -3207,7 +3179,7 @@ void FundTransaction(CWallet* const pwallet, CMutableTransaction& tx, CAmount& f
bilingual_str error;
- if (!pwallet->FundTransaction(tx, fee_out, change_position, error, lockUnspents, setSubtractFeeFromOutputs, coinControl)) {
+ if (!wallet.FundTransaction(tx, fee_out, change_position, error, lockUnspents, setSubtractFeeFromOutputs, coinControl)) {
throw JSONRPCError(RPC_WALLET_ERROR, error.original);
}
}
@@ -3283,9 +3255,8 @@ static RPCHelpMan fundrawtransaction()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
RPCTypeCheck(request.params, {UniValue::VSTR, UniValueType(), UniValue::VBOOL});
@@ -3302,7 +3273,7 @@ static RPCHelpMan fundrawtransaction()
CCoinControl coin_control;
// Automatically select (additional) coins. Can be overridden by options.add_inputs.
coin_control.m_add_inputs = true;
- FundTransaction(pwallet, tx, fee, change_position, request.params[1], coin_control, /* override_min_fee */ true);
+ FundTransaction(*pwallet, tx, fee, change_position, request.params[1], coin_control, /* override_min_fee */ true);
UniValue result(UniValue::VOBJ);
result.pushKV("hex", EncodeHexTx(CTransaction(tx)));
@@ -3369,9 +3340,8 @@ RPCHelpMan signrawtransactionwithwallet()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- const CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR, UniValue::VSTR}, true);
@@ -3382,7 +3352,7 @@ RPCHelpMan signrawtransactionwithwallet()
// Sign the transaction
LOCK(pwallet->cs_wallet);
- EnsureWalletIsUnlocked(pwallet);
+ EnsureWalletIsUnlocked(*pwallet);
// Fetch previous transactions (inputs):
std::map<COutPoint, Coin> coins;
@@ -3469,9 +3439,8 @@ static RPCHelpMan bumpfee_helper(std::string method_name)
},
[want_psbt](const RPCHelpMan& self, const JSONRPCRequest& request) mutable -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
if (pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS) && !want_psbt) {
throw JSONRPCError(RPC_WALLET_ERROR, "bumpfee is not available with wallets that have private keys disabled. Use psbtbumpfee instead.");
@@ -3514,7 +3483,8 @@ static RPCHelpMan bumpfee_helper(std::string method_name)
pwallet->BlockUntilSyncedToCurrentChain();
LOCK(pwallet->cs_wallet);
- EnsureWalletIsUnlocked(pwallet);
+
+ EnsureWalletIsUnlocked(*pwallet);
std::vector<bilingual_str> errors;
@@ -3608,9 +3578,8 @@ static RPCHelpMan rescanblockchain()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
WalletRescanReserver reserver(*pwallet);
if (!reserver.reserve()) {
@@ -3759,15 +3728,13 @@ public:
UniValue operator()(const WitnessUnknown& id) const { return UniValue(UniValue::VOBJ); }
};
-static UniValue DescribeWalletAddress(const CWallet* const pwallet, const CTxDestination& dest)
+static UniValue DescribeWalletAddress(const CWallet& wallet, const CTxDestination& dest)
{
UniValue ret(UniValue::VOBJ);
UniValue detail = DescribeAddress(dest);
CScript script = GetScriptForDestination(dest);
std::unique_ptr<SigningProvider> provider = nullptr;
- if (pwallet) {
- provider = pwallet->GetSolvingProvider(script);
- }
+ provider = wallet.GetSolvingProvider(script);
ret.pushKVs(detail);
ret.pushKVs(std::visit(DescribeWalletAddressVisitor(provider.get()), dest));
return ret;
@@ -3840,9 +3807,8 @@ RPCHelpMan getaddressinfo()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- const CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
LOCK(pwallet->cs_wallet);
@@ -3887,7 +3853,7 @@ RPCHelpMan getaddressinfo()
ret.pushKV("iswatchonly", bool(mine & ISMINE_WATCH_ONLY));
- UniValue detail = DescribeWalletAddress(pwallet, dest);
+ UniValue detail = DescribeWalletAddress(*pwallet, dest);
ret.pushKVs(detail);
ret.pushKV("ischange", pwallet->IsChange(scriptPubKey));
@@ -3943,9 +3909,8 @@ static RPCHelpMan getaddressesbylabel()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- const CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
LOCK(pwallet->cs_wallet);
@@ -4005,9 +3970,8 @@ static RPCHelpMan listlabels()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- const CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
LOCK(pwallet->cs_wallet);
@@ -4130,9 +4094,8 @@ static RPCHelpMan send()
}, true
);
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
UniValue options{request.params[4].isNull() ? UniValue::VOBJ : request.params[4]};
if (options.exists("conf_target") || options.exists("estimate_mode")) {
@@ -4185,7 +4148,7 @@ static RPCHelpMan send()
// Automatically select coins, unless at least one is manually selected. Can
// be overridden by options.add_inputs.
coin_control.m_add_inputs = rawTx.vin.size() == 0;
- FundTransaction(pwallet, rawTx, fee, change_position, options, coin_control, /* override_min_fee */ false);
+ FundTransaction(*pwallet, rawTx, fee, change_position, options, coin_control, /* override_min_fee */ false);
bool add_to_wallet = true;
if (options.exists("add_to_wallet")) {
@@ -4258,9 +4221,8 @@ static RPCHelpMan sethdseed()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
LegacyScriptPubKeyMan& spk_man = EnsureLegacyScriptPubKeyMan(*pwallet, true);
@@ -4275,7 +4237,7 @@ static RPCHelpMan sethdseed()
throw JSONRPCError(RPC_WALLET_ERROR, "Cannot set an HD seed on a non-HD wallet. Use the upgradewallet RPC in order to upgrade a non-HD wallet to HD");
}
- EnsureWalletIsUnlocked(pwallet);
+ EnsureWalletIsUnlocked(*pwallet);
bool flush_key_pool = true;
if (!request.params[0].isNull()) {
@@ -4336,9 +4298,8 @@ static RPCHelpMan walletprocesspsbt()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- const CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL, UniValue::VSTR});
@@ -4448,9 +4409,8 @@ static RPCHelpMan walletcreatefundedpsbt()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
RPCTypeCheck(request.params, {
UniValue::VARR,
@@ -4474,7 +4434,7 @@ static RPCHelpMan walletcreatefundedpsbt()
// Automatically select coins, unless at least one is manually selected. Can
// be overridden by options.add_inputs.
coin_control.m_add_inputs = rawTx.vin.size() == 0;
- FundTransaction(pwallet, rawTx, fee, change_position, request.params[3], coin_control, /* override_min_fee */ true);
+ FundTransaction(*pwallet, rawTx, fee, change_position, request.params[3], coin_control, /* override_min_fee */ true);
// Make a blank psbt
PartiallySignedTransaction psbtx(rawTx);
@@ -4524,13 +4484,12 @@ static RPCHelpMan upgradewallet()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return NullUniValue;
- CWallet* const pwallet = wallet.get();
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return NullUniValue;
RPCTypeCheck(request.params, {UniValue::VNUM}, true);
- EnsureWalletIsUnlocked(pwallet);
+ EnsureWalletIsUnlocked(*pwallet);
int version = 0;
if (!request.params[0].isNull()) {
diff --git a/src/wallet/rpcwallet.h b/src/wallet/rpcwallet.h
index 184a16e91d..b82fe1ec76 100644
--- a/src/wallet/rpcwallet.h
+++ b/src/wallet/rpcwallet.h
@@ -30,7 +30,7 @@ Span<const CRPCCommand> GetWalletRPCCommands();
*/
std::shared_ptr<CWallet> GetWalletForJSONRPCRequest(const JSONRPCRequest& request);
-void EnsureWalletIsUnlocked(const CWallet*);
+void EnsureWalletIsUnlocked(const CWallet&);
WalletContext& EnsureWalletContext(const util::Ref& context);
LegacyScriptPubKeyMan& EnsureLegacyScriptPubKeyMan(CWallet& wallet, bool also_create = false);
diff --git a/src/wallet/salvage.cpp b/src/wallet/salvage.cpp
index 09a9ec68cd..6d912be019 100644
--- a/src/wallet/salvage.cpp
+++ b/src/wallet/salvage.cpp
@@ -119,7 +119,7 @@ bool RecoverDatabaseFile(const fs::path& file_path, bilingual_str& error, std::v
return false;
}
- std::unique_ptr<Db> pdbCopy = MakeUnique<Db>(env->dbenv.get(), 0);
+ std::unique_ptr<Db> pdbCopy = std::make_unique<Db>(env->dbenv.get(), 0);
int ret = pdbCopy->open(nullptr, // Txn pointer
filename.c_str(), // Filename
"main", // Logical db name
diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp
index efb408c163..a8200981d8 100644
--- a/src/wallet/scriptpubkeyman.cpp
+++ b/src/wallet/scriptpubkeyman.cpp
@@ -378,7 +378,7 @@ void LegacyScriptPubKeyMan::UpgradeKeyMetadata()
return;
}
- std::unique_ptr<WalletBatch> batch = MakeUnique<WalletBatch>(m_storage.GetDatabase());
+ std::unique_ptr<WalletBatch> batch = std::make_unique<WalletBatch>(m_storage.GetDatabase());
for (auto& meta_pair : mapKeyMetadata) {
CKeyMetadata& meta = meta_pair.second;
if (!meta.hd_seed_id.IsNull() && !meta.has_key_origin && meta.hdKeypath != "s") { // If the hdKeypath is "s", that's the seed and it doesn't have a key origin
@@ -551,7 +551,7 @@ int64_t LegacyScriptPubKeyMan::GetTimeFirstKey() const
std::unique_ptr<SigningProvider> LegacyScriptPubKeyMan::GetSolvingProvider(const CScript& script) const
{
- return MakeUnique<LegacySigningProvider>(*this);
+ return std::make_unique<LegacySigningProvider>(*this);
}
bool LegacyScriptPubKeyMan::CanProvide(const CScript& script, SignatureData& sigdata)
@@ -651,14 +651,14 @@ std::unique_ptr<CKeyMetadata> LegacyScriptPubKeyMan::GetMetadata(const CTxDestin
if (!key_id.IsNull()) {
auto it = mapKeyMetadata.find(key_id);
if (it != mapKeyMetadata.end()) {
- return MakeUnique<CKeyMetadata>(it->second);
+ return std::make_unique<CKeyMetadata>(it->second);
}
}
CScript scriptPubKey = GetScriptForDestination(dest);
auto it = m_script_metadata.find(CScriptID(scriptPubKey));
if (it != m_script_metadata.end()) {
- return MakeUnique<CKeyMetadata>(it->second);
+ return std::make_unique<CKeyMetadata>(it->second);
}
return nullptr;
@@ -2026,7 +2026,7 @@ std::unique_ptr<FlatSigningProvider> DescriptorScriptPubKeyMan::GetSigningProvid
{
AssertLockHeld(cs_desc_man);
// Get the scripts, keys, and key origins for this script
- std::unique_ptr<FlatSigningProvider> out_keys = MakeUnique<FlatSigningProvider>();
+ std::unique_ptr<FlatSigningProvider> out_keys = std::make_unique<FlatSigningProvider>();
std::vector<CScript> scripts_temp;
if (!m_wallet_descriptor.descriptor->ExpandFromCache(index, m_wallet_descriptor.cache, scripts_temp, *out_keys)) return nullptr;
@@ -2051,7 +2051,7 @@ bool DescriptorScriptPubKeyMan::CanProvide(const CScript& script, SignatureData&
bool DescriptorScriptPubKeyMan::SignTransaction(CMutableTransaction& tx, const std::map<COutPoint, Coin>& coins, int sighash, std::map<int, std::string>& input_errors) const
{
- std::unique_ptr<FlatSigningProvider> keys = MakeUnique<FlatSigningProvider>();
+ std::unique_ptr<FlatSigningProvider> keys = std::make_unique<FlatSigningProvider>();
for (const auto& coin_pair : coins) {
std::unique_ptr<FlatSigningProvider> coin_keys = GetSigningProvider(coin_pair.second.out.scriptPubKey, true);
if (!coin_keys) {
@@ -2115,13 +2115,13 @@ TransactionError DescriptorScriptPubKeyMan::FillPSBT(PartiallySignedTransaction&
SignatureData sigdata;
input.FillSignatureData(sigdata);
- std::unique_ptr<FlatSigningProvider> keys = MakeUnique<FlatSigningProvider>();
+ std::unique_ptr<FlatSigningProvider> keys = std::make_unique<FlatSigningProvider>();
std::unique_ptr<FlatSigningProvider> script_keys = GetSigningProvider(script, sign);
if (script_keys) {
*keys = Merge(*keys, *script_keys);
} else {
// Maybe there are pubkeys listed that we can sign for
- script_keys = MakeUnique<FlatSigningProvider>();
+ script_keys = std::make_unique<FlatSigningProvider>();
for (const auto& pk_pair : input.hd_keypaths) {
const CPubKey& pubkey = pk_pair.first;
std::unique_ptr<FlatSigningProvider> pk_keys = GetSigningProvider(pubkey);
@@ -2162,7 +2162,7 @@ std::unique_ptr<CKeyMetadata> DescriptorScriptPubKeyMan::GetMetadata(const CTxDe
CKeyID key_id = GetKeyForDestination(*provider, dest);
if (provider->GetKeyOrigin(key_id, orig)) {
LOCK(cs_desc_man);
- std::unique_ptr<CKeyMetadata> meta = MakeUnique<CKeyMetadata>();
+ std::unique_ptr<CKeyMetadata> meta = std::make_unique<CKeyMetadata>();
meta->key_origin = orig;
meta->has_key_origin = true;
meta->nCreateTime = m_wallet_descriptor.creation_time;
diff --git a/src/wallet/sqlite.cpp b/src/wallet/sqlite.cpp
index 0fb3b1d3c4..975974cb6a 100644
--- a/src/wallet/sqlite.cpp
+++ b/src/wallet/sqlite.cpp
@@ -8,7 +8,6 @@
#include <crypto/common.h>
#include <logging.h>
#include <sync.h>
-#include <util/memory.h>
#include <util/strencodings.h>
#include <util/system.h>
#include <util/translation.h>
@@ -330,7 +329,7 @@ void SQLiteDatabase::Close()
std::unique_ptr<DatabaseBatch> SQLiteDatabase::MakeBatch(bool flush_on_close)
{
// We ignore flush_on_close because we don't do manual flushing for SQLite
- return MakeUnique<SQLiteBatch>(*this);
+ return std::make_unique<SQLiteBatch>(*this);
}
SQLiteBatch::SQLiteBatch(SQLiteDatabase& database)
@@ -571,7 +570,7 @@ std::unique_ptr<SQLiteDatabase> MakeSQLiteDatabase(const fs::path& path, const D
{
try {
fs::path data_file = SQLiteDataFile(path);
- auto db = MakeUnique<SQLiteDatabase>(data_file.parent_path(), data_file);
+ auto db = std::make_unique<SQLiteDatabase>(data_file.parent_path(), data_file);
if (options.verify && !db->Verify(error)) {
status = DatabaseStatus::FAILED_VERIFY;
return nullptr;
diff --git a/src/wallet/test/coinselector_tests.cpp b/src/wallet/test/coinselector_tests.cpp
index ffac78d752..0e9f3819eb 100644
--- a/src/wallet/test/coinselector_tests.cpp
+++ b/src/wallet/test/coinselector_tests.cpp
@@ -290,7 +290,7 @@ BOOST_AUTO_TEST_CASE(bnb_search_test)
// Make sure that can use BnB when there are preset inputs
empty_wallet();
{
- std::unique_ptr<CWallet> wallet = MakeUnique<CWallet>(m_node.chain.get(), "", CreateMockWalletDatabase());
+ std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain.get(), "", CreateMockWalletDatabase());
bool firstRun;
wallet->LoadWallet(firstRun);
wallet->SetupLegacyScriptPubKeyMan();
diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp
index 5480f3ab22..4598999b3c 100644
--- a/src/wallet/test/wallet_tests.cpp
+++ b/src/wallet/test/wallet_tests.cpp
@@ -485,7 +485,7 @@ public:
ListCoinsTestingSetup()
{
CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
- wallet = MakeUnique<CWallet>(m_node.chain.get(), "", CreateMockWalletDatabase());
+ wallet = std::make_unique<CWallet>(m_node.chain.get(), "", CreateMockWalletDatabase());
{
LOCK2(wallet->cs_wallet, ::cs_main);
wallet->SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash());
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 9e0befac43..58ab124061 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -791,6 +791,12 @@ bool CWallet::MarkReplaced(const uint256& originalHash, const uint256& newHash)
wtx.mapValue["replaced_by_txid"] = newHash.ToString();
+ // Refresh mempool status without waiting for transactionRemovedFromMempool
+ // notification so the wallet is in an internally consistent state and
+ // immediately knows the old transaction should not be considered trusted
+ // and is eligible to be abandoned
+ wtx.fInMempool = chain().isInMempool(originalHash);
+
WalletBatch batch(GetDatabase());
bool success = true;
diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp
index 69854cae05..a5a454f9a8 100644
--- a/src/wallet/walletdb.cpp
+++ b/src/wallet/walletdb.cpp
@@ -1086,15 +1086,15 @@ std::unique_ptr<WalletDatabase> MakeDatabase(const fs::path& path, const Databas
/** Return object for accessing dummy database with no read/write capabilities. */
std::unique_ptr<WalletDatabase> CreateDummyWalletDatabase()
{
- return MakeUnique<DummyDatabase>();
+ return std::make_unique<DummyDatabase>();
}
/** Return object for accessing temporary in-memory database. */
std::unique_ptr<WalletDatabase> CreateMockWalletDatabase()
{
#ifdef USE_BDB
- return MakeUnique<BerkeleyDatabase>(std::make_shared<BerkeleyEnvironment>(), "");
+ return std::make_unique<BerkeleyDatabase>(std::make_shared<BerkeleyEnvironment>(), "");
#elif USE_SQLITE
- return MakeUnique<SQLiteDatabase>("", "", true);
+ return std::make_unique<SQLiteDatabase>("", "", true);
#endif
}
diff --git a/src/zmq/zmqabstractnotifier.h b/src/zmq/zmqabstractnotifier.h
index 6f0b202a18..49c1c2a07d 100644
--- a/src/zmq/zmqabstractnotifier.h
+++ b/src/zmq/zmqabstractnotifier.h
@@ -5,7 +5,6 @@
#ifndef BITCOIN_ZMQ_ZMQABSTRACTNOTIFIER_H
#define BITCOIN_ZMQ_ZMQABSTRACTNOTIFIER_H
-#include <util/memory.h>
#include <memory>
#include <string>
@@ -27,7 +26,7 @@ public:
template <typename T>
static std::unique_ptr<CZMQAbstractNotifier> Create()
{
- return MakeUnique<T>();
+ return std::make_unique<T>();
}
std::string GetType() const { return type; }
diff --git a/test/functional/wallet_groups.py b/test/functional/wallet_groups.py
index e5c4f12f20..c0b76d960f 100755
--- a/test/functional/wallet_groups.py
+++ b/test/functional/wallet_groups.py
@@ -29,8 +29,9 @@ class WalletGroupTest(BitcoinTestFramework):
self.skip_if_no_wallet()
def run_test(self):
+ self.log.info("Setting up")
# Mine some coins
- self.nodes[0].generate(110)
+ self.nodes[0].generate(101)
# Get some addresses from the two nodes
addr1 = [self.nodes[1].getnewaddress() for _ in range(3)]
@@ -48,6 +49,7 @@ class WalletGroupTest(BitcoinTestFramework):
# - node[1] should pick one 0.5 UTXO and leave the rest
# - node[2] should pick one (1.0 + 0.5) UTXO group corresponding to a
# given address, and leave the rest
+ self.log.info("Test sending transactions picks one UTXO group and leaves the rest")
txid1 = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 0.2)
tx1 = self.nodes[1].getrawtransaction(txid1, True)
# txid1 should have 1 input and 2 outputs
@@ -70,7 +72,7 @@ class WalletGroupTest(BitcoinTestFramework):
assert_approx(v[0], vexp=0.2, vspan=0.0001)
assert_approx(v[1], vexp=1.3, vspan=0.0001)
- # Test 'avoid partial if warranted, even if disabled'
+ self.log.info("Test avoiding partial spends if warranted, even if avoidpartialspends is disabled")
self.sync_all()
self.nodes[0].generate(1)
# Nodes 1-2 now have confirmed UTXOs (letters denote destinations):
@@ -104,7 +106,7 @@ class WalletGroupTest(BitcoinTestFramework):
assert_equal(input_addrs[0], input_addrs[1])
# Node 2 enforces avoidpartialspends so needs no checking here
- # Test wallet option maxapsfee with Node 3
+ self.log.info("Test wallet option maxapsfee")
addr_aps = self.nodes[3].getnewaddress()
self.nodes[0].sendtoaddress(addr_aps, 1.0)
self.nodes[0].sendtoaddress(addr_aps, 1.0)
@@ -131,6 +133,7 @@ class WalletGroupTest(BitcoinTestFramework):
# Test wallet option maxapsfee with node 4, which sets maxapsfee
# 1 sat higher, crossing the threshold from non-grouped to grouped.
+ self.log.info("Test wallet option maxapsfee threshold from non-grouped to grouped")
addr_aps3 = self.nodes[4].getnewaddress()
[self.nodes[0].sendtoaddress(addr_aps3, 1.0) for _ in range(5)]
self.nodes[0].generate(1)
@@ -147,8 +150,7 @@ class WalletGroupTest(BitcoinTestFramework):
self.sync_all()
self.nodes[0].generate(1)
- # Fill node2's wallet with 10000 outputs corresponding to the same
- # scriptPubKey
+ self.log.info("Fill a wallet with 10,000 outputs corresponding to the same scriptPubKey")
for _ in range(5):
raw_tx = self.nodes[0].createrawtransaction([{"txid":"0"*64, "vout":0}], [{addr2[0]: 0.05}])
tx = FromHex(CTransaction(), raw_tx)
@@ -158,12 +160,12 @@ class WalletGroupTest(BitcoinTestFramework):
signed_tx = self.nodes[0].signrawtransactionwithwallet(funded_tx['hex'])
self.nodes[0].sendrawtransaction(signed_tx['hex'])
self.nodes[0].generate(1)
-
- self.sync_all()
+ self.sync_all()
# Check that we can create a transaction that only requires ~100 of our
# utxos, without pulling in all outputs and creating a transaction that
# is way too big.
+ self.log.info("Test creating txn that only requires ~100 of our UTXOs without pulling in all outputs")
assert self.nodes[2].sendtoaddress(address=addr2[0], amount=5)
diff --git a/test/fuzz/test_runner.py b/test/fuzz/test_runner.py
index 611061072f..eeff7a4515 100755
--- a/test/fuzz/test_runner.py
+++ b/test/fuzz/test_runner.py
@@ -27,7 +27,7 @@ def get_fuzz_env(*, target, source_dir):
def main():
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
- description='''Run the fuzz targets with all inputs from the seed_dir once.''',
+ description='''Run the fuzz targets with all inputs from the corpus_dir once.''',
)
parser.add_argument(
"-l",
@@ -54,8 +54,8 @@ def main():
help='How many targets to merge or execute in parallel.',
)
parser.add_argument(
- 'seed_dir',
- help='The seed corpus to run on (must contain subfolders for each fuzz target).',
+ 'corpus_dir',
+ help='The corpus to run on (must contain subfolders for each fuzz target).',
)
parser.add_argument(
'target',
@@ -64,15 +64,15 @@ def main():
)
parser.add_argument(
'--m_dir',
- help='Merge inputs from this directory into the seed_dir.',
+ help='Merge inputs from this directory into the corpus_dir.',
)
parser.add_argument(
'-g',
'--generate',
action='store_true',
- help='Create new corpus seeds (or extend the existing ones) by running'
+ help='Create new corpus (or extend the existing ones) by running'
' the given targets for a finite number of times. Outputs them to'
- ' the passed seed_dir.'
+ ' the passed corpus_dir.'
)
args = parser.parse_args()
@@ -119,19 +119,19 @@ def main():
logging.info("{} of {} detected fuzz target(s) selected: {}".format(len(test_list_selection), len(test_list_all), " ".join(test_list_selection)))
if not args.generate:
- test_list_seedless = []
+ test_list_missing_corpus = []
for t in test_list_selection:
- corpus_path = os.path.join(args.seed_dir, t)
+ corpus_path = os.path.join(args.corpus_dir, t)
if not os.path.exists(corpus_path) or len(os.listdir(corpus_path)) == 0:
- test_list_seedless.append(t)
- test_list_seedless.sort()
- if test_list_seedless:
+ test_list_missing_corpus.append(t)
+ test_list_missing_corpus.sort()
+ if test_list_missing_corpus:
logging.info(
- "Fuzzing harnesses lacking a seed corpus: {}".format(
- " ".join(test_list_seedless)
+ "Fuzzing harnesses lacking a corpus: {}".format(
+ " ".join(test_list_missing_corpus)
)
)
- logging.info("Please consider adding a fuzz seed corpus at https://github.com/bitcoin-core/qa-assets")
+ logging.info("Please consider adding a fuzz corpus at https://github.com/bitcoin-core/qa-assets")
try:
help_output = subprocess.run(
@@ -154,18 +154,18 @@ def main():
with ThreadPoolExecutor(max_workers=args.par) as fuzz_pool:
if args.generate:
- return generate_corpus_seeds(
+ return generate_corpus(
fuzz_pool=fuzz_pool,
src_dir=config['environment']['SRCDIR'],
build_dir=config["environment"]["BUILDDIR"],
- seed_dir=args.seed_dir,
+ corpus_dir=args.corpus_dir,
targets=test_list_selection,
)
if args.m_dir:
merge_inputs(
fuzz_pool=fuzz_pool,
- corpus=args.seed_dir,
+ corpus=args.corpus_dir,
test_list=test_list_selection,
src_dir=config['environment']['SRCDIR'],
build_dir=config["environment"]["BUILDDIR"],
@@ -175,7 +175,7 @@ def main():
run_once(
fuzz_pool=fuzz_pool,
- corpus=args.seed_dir,
+ corpus=args.corpus_dir,
test_list=test_list_selection,
src_dir=config['environment']['SRCDIR'],
build_dir=config["environment"]["BUILDDIR"],
@@ -183,13 +183,13 @@ def main():
)
-def generate_corpus_seeds(*, fuzz_pool, src_dir, build_dir, seed_dir, targets):
- """Generates new corpus seeds.
+def generate_corpus(*, fuzz_pool, src_dir, build_dir, corpus_dir, targets):
+ """Generates new corpus.
- Run {targets} without input, and outputs the generated corpus seeds to
- {seed_dir}.
+ Run {targets} without input, and outputs the generated corpus to
+ {corpus_dir}.
"""
- logging.info("Generating corpus seeds to {}".format(seed_dir))
+ logging.info("Generating corpus to {}".format(corpus_dir))
def job(command, t):
logging.debug("Running '{}'\n".format(" ".join(command)))
@@ -205,12 +205,12 @@ def generate_corpus_seeds(*, fuzz_pool, src_dir, build_dir, seed_dir, targets):
futures = []
for target in targets:
- target_seed_dir = os.path.join(seed_dir, target)
- os.makedirs(target_seed_dir, exist_ok=True)
+ target_corpus_dir = os.path.join(corpus_dir, target)
+ os.makedirs(target_corpus_dir, exist_ok=True)
command = [
os.path.join(build_dir, 'src', 'test', 'fuzz', 'fuzz'),
"-runs=100000",
- target_seed_dir,
+ target_corpus_dir,
]
futures.append(fuzz_pool.submit(job, command, target))
@@ -219,7 +219,7 @@ def generate_corpus_seeds(*, fuzz_pool, src_dir, build_dir, seed_dir, targets):
def merge_inputs(*, fuzz_pool, corpus, test_list, src_dir, build_dir, merge_dir):
- logging.info("Merge the inputs from the passed dir into the seed_dir. Passed dir {}".format(merge_dir))
+ logging.info("Merge the inputs from the passed dir into the corpus_dir. Passed dir {}".format(merge_dir))
jobs = []
for t in test_list:
args = [