aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--build-aux/m4/bitcoin_qt.m447
-rw-r--r--configure.ac102
-rw-r--r--depends/config.site.in4
-rw-r--r--depends/packages/libnatpmp.mk1
-rw-r--r--doc/build-osx.md2
-rw-r--r--doc/build-unix.md53
-rw-r--r--doc/build-windows.md2
-rw-r--r--share/setup.nsi.in1
-rw-r--r--src/Makefile.test.include1
-rw-r--r--src/test/fuzz/torcontrol.cpp79
-rw-r--r--src/torcontrol.cpp120
-rw-r--r--src/torcontrol.h136
13 files changed, 343 insertions, 208 deletions
diff --git a/.gitignore b/.gitignore
index 010586ee5a..c0b5661464 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,8 +10,7 @@ src/bitcoin-node
src/bitcoin-tx
src/bitcoin-util
src/bitcoin-wallet
-src/test/fuzz/*
-!src/test/fuzz/*.*
+src/test/fuzz/fuzz
src/test/test_bitcoin
src/qt/test/test_bitcoin-qt
diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4
index 658dfc5476..b559baba23 100644
--- a/build-aux/m4/bitcoin_qt.m4
+++ b/build-aux/m4/bitcoin_qt.m4
@@ -64,6 +64,13 @@ AC_DEFUN([BITCOIN_QT_INIT],[
],
[bitcoin_qt_want_version=auto])
+ AS_IF([test "x$with_gui" = xqt5_debug],
+ [AS_CASE([$host],
+ [*darwin*], [qt_lib_suffix=_debug],
+ [*mingw*], [qt_lib_suffix=d],
+ [qt_lib_suffix= ]); bitcoin_qt_want_version=qt5],
+ [qt_lib_suffix= ])
+
AC_ARG_WITH([qt-incdir],[AS_HELP_STRING([--with-qt-incdir=INC_DIR],[specify qt include path (overridden by pkgconfig)])], [qt_include_path=$withval], [])
AC_ARG_WITH([qt-libdir],[AS_HELP_STRING([--with-qt-libdir=LIB_DIR],[specify qt lib path (overridden by pkgconfig)])], [qt_lib_path=$withval], [])
AC_ARG_WITH([qt-plugindir],[AS_HELP_STRING([--with-qt-plugindir=PLUGIN_DIR],[specify qt plugin path (overridden by pkgconfig)])], [qt_plugin_path=$withval], [])
@@ -285,13 +292,13 @@ dnl Output: QT_LIBS is prepended or configure exits.
AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_PLUGINS],[
AC_MSG_CHECKING(for static Qt plugins: $2)
CHECK_STATIC_PLUGINS_TEMP_LIBS="$LIBS"
- LIBS="$2 $QT_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_LIBS"],
+ [AC_MSG_RESULT(yes); QT_LIBS="$2${qt_lib_suffix} $QT_LIBS"],
[AC_MSG_RESULT(no); BITCOIN_QT_FAIL(Could not resolve: $2)])
LIBS="$CHECK_STATIC_PLUGINS_TEMP_LIBS"
])
@@ -308,18 +315,18 @@ AC_DEFUN([_BITCOIN_QT_FIND_STATIC_PLUGINS],[
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_LIBS="-lQt5FontDatabaseSupport $QT_LIBS"])
- PKG_CHECK_MODULES([QTEVENTDISPATCHER], [Qt5EventDispatcherSupport], [QT_LIBS="-lQt5EventDispatcherSupport $QT_LIBS"])
- PKG_CHECK_MODULES([QTTHEME], [Qt5ThemeSupport], [QT_LIBS="-lQt5ThemeSupport $QT_LIBS"])
- PKG_CHECK_MODULES([QTDEVICEDISCOVERY], [Qt5DeviceDiscoverySupport], [QT_LIBS="-lQt5DeviceDiscoverySupport $QT_LIBS"])
- PKG_CHECK_MODULES([QTACCESSIBILITY], [Qt5AccessibilitySupport], [QT_LIBS="-lQt5AccessibilitySupport $QT_LIBS"])
- PKG_CHECK_MODULES([QTFB], [Qt5FbSupport], [QT_LIBS="-lQt5FbSupport $QT_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_LIBS="-lQt5ClipboardSupport $QT_LIBS"])
- PKG_CHECK_MODULES([QTGRAPHICS], [Qt5GraphicsSupport], [QT_LIBS="-lQt5GraphicsSupport $QT_LIBS"])
- PKG_CHECK_MODULES([QTCGL], [Qt5CglSupport], [QT_LIBS="-lQt5CglSupport $QT_LIBS"])
+ 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
])
@@ -329,26 +336,26 @@ dnl Outputs: All necessary QT_* variables are set.
dnl Outputs: have_qt_test and have_qt_dbus are set (if applicable) to yes|no.
AC_DEFUN([_BITCOIN_QT_FIND_LIBS],[
BITCOIN_QT_CHECK([
- PKG_CHECK_MODULES([QT_CORE], [${qt_lib_prefix}Core $qt_version], [],
- [BITCOIN_QT_FAIL([${qt_lib_prefix}Core $qt_version not found])])
+ PKG_CHECK_MODULES([QT_CORE], [${qt_lib_prefix}Core${qt_lib_suffix} $qt_version], [],
+ [BITCOIN_QT_FAIL([${qt_lib_prefix}Core${qt_lib_suffix} $qt_version not found])])
])
BITCOIN_QT_CHECK([
- PKG_CHECK_MODULES([QT_GUI], [${qt_lib_prefix}Gui $qt_version], [],
- [BITCOIN_QT_FAIL([${qt_lib_prefix}Gui $qt_version not found])])
+ PKG_CHECK_MODULES([QT_GUI], [${qt_lib_prefix}Gui${qt_lib_suffix} $qt_version], [],
+ [BITCOIN_QT_FAIL([${qt_lib_prefix}Gui${qt_lib_suffix} $qt_version not found])])
])
BITCOIN_QT_CHECK([
- PKG_CHECK_MODULES([QT_WIDGETS], [${qt_lib_prefix}Widgets $qt_version], [],
- [BITCOIN_QT_FAIL([${qt_lib_prefix}Widgets $qt_version not found])])
+ PKG_CHECK_MODULES([QT_WIDGETS], [${qt_lib_prefix}Widgets${qt_lib_suffix} $qt_version], [],
+ [BITCOIN_QT_FAIL([${qt_lib_prefix}Widgets${qt_lib_suffix} $qt_version not found])])
])
BITCOIN_QT_CHECK([
- PKG_CHECK_MODULES([QT_NETWORK], [${qt_lib_prefix}Network $qt_version], [],
- [BITCOIN_QT_FAIL([${qt_lib_prefix}Network $qt_version not found])])
+ PKG_CHECK_MODULES([QT_NETWORK], [${qt_lib_prefix}Network${qt_lib_suffix} $qt_version], [],
+ [BITCOIN_QT_FAIL([${qt_lib_prefix}Network${qt_lib_suffix} $qt_version not found])])
])
QT_INCLUDES="$QT_CORE_CFLAGS $QT_GUI_CFLAGS $QT_WIDGETS_CFLAGS $QT_NETWORK_CFLAGS"
QT_LIBS="$QT_CORE_LIBS $QT_GUI_LIBS $QT_WIDGETS_LIBS $QT_NETWORK_LIBS"
BITCOIN_QT_CHECK([
- PKG_CHECK_MODULES([QT_TEST], [${qt_lib_prefix}Test $qt_version], [QT_TEST_INCLUDES="$QT_TEST_CFLAGS"; have_qt_test=yes], [have_qt_test=no])
+ PKG_CHECK_MODULES([QT_TEST], [${qt_lib_prefix}Test${qt_lib_suffix} $qt_version], [QT_TEST_INCLUDES="$QT_TEST_CFLAGS"; have_qt_test=yes], [have_qt_test=no])
if test "x$use_dbus" != xno; then
PKG_CHECK_MODULES([QT_DBUS], [${qt_lib_prefix}DBus $qt_version], [QT_DBUS_INCLUDES="$QT_DBUS_CFLAGS"; have_qt_dbus=yes], [have_qt_dbus=no])
fi
diff --git a/configure.ac b/configure.ac
index c4ad5fae59..c5bc7ebc7f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1379,52 +1379,52 @@ if test "x$use_natpmp" != xno; then
fi
if test x$build_bitcoin_wallet$build_bitcoin_cli$build_bitcoin_tx$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench = xnonononononono; then
- use_boost=no
+ use_boost=no
else
- use_boost=yes
+ use_boost=yes
fi
if test x$use_boost = xyes; then
-dnl Check for Boost headers
-AX_BOOST_BASE([1.58.0],[],[AC_MSG_ERROR([Boost is not available!])])
-if test x$want_boost = xno; then
+ dnl Check for Boost headers
+ AX_BOOST_BASE([1.58.0],[],[AC_MSG_ERROR([Boost is not available!])])
+ if test x$want_boost = xno; then
AC_MSG_ERROR([[only libbitcoinconsensus can be built without boost]])
-fi
-AX_BOOST_SYSTEM
-AX_BOOST_FILESYSTEM
-
-dnl Opt-in to Boost Process if external signer support is requested
-if test "x$use_external_signer" != xno; then
-AC_MSG_CHECKING(for Boost Process)
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <boost/process.hpp>]],
- [[ boost::process::child* child = new boost::process::child; delete child; ]])],
- [ AC_MSG_RESULT(yes)
- AC_DEFINE([ENABLE_EXTERNAL_SIGNER],,[define if external signer support is enabled])
- ],
- [ AC_MSG_ERROR([Boost::Process is required for external signer support, but not available!])]
-)
-fi
-
-AM_CONDITIONAL([ENABLE_EXTERNAL_SIGNER], [test "x$use_external_signer" = "xyes"])
+ fi
+ AX_BOOST_SYSTEM
+ AX_BOOST_FILESYSTEM
+
+ dnl Opt-in to Boost Process if external signer support is requested
+ if test "x$use_external_signer" != xno; then
+ AC_MSG_CHECKING(for Boost Process)
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <boost/process.hpp>]],
+ [[ boost::process::child* child = new boost::process::child; delete child; ]])],
+ [ AC_MSG_RESULT(yes)
+ AC_DEFINE([ENABLE_EXTERNAL_SIGNER],,[define if external signer support is enabled])
+ ],
+ [ AC_MSG_ERROR([Boost::Process is required for external signer support, but not available!])]
+ )
+ fi
-if test x$suppress_external_warnings != xno; then
+ if test x$suppress_external_warnings != xno; then
BOOST_CPPFLAGS=SUPPRESS_WARNINGS($BOOST_CPPFLAGS)
-fi
+ fi
-dnl Boost 1.56 through 1.62 allow using std::atomic instead of its own atomic
-dnl counter implementations. In 1.63 and later the std::atomic approach is default.
-m4_pattern_allow(DBOOST_AC_USE_STD_ATOMIC) dnl otherwise it's treated like a macro
-BOOST_CPPFLAGS="-DBOOST_SP_USE_STD_ATOMIC -DBOOST_AC_USE_STD_ATOMIC $BOOST_CPPFLAGS"
+ dnl Boost 1.56 through 1.62 allow using std::atomic instead of its own atomic
+ dnl counter implementations. In 1.63 and later the std::atomic approach is default.
+ m4_pattern_allow(DBOOST_AC_USE_STD_ATOMIC) dnl otherwise it's treated like a macro
+ BOOST_CPPFLAGS="-DBOOST_SP_USE_STD_ATOMIC -DBOOST_AC_USE_STD_ATOMIC $BOOST_CPPFLAGS"
-BOOST_LIBS="$BOOST_LDFLAGS $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB"
+ BOOST_LIBS="$BOOST_LDFLAGS $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB"
fi
+AM_CONDITIONAL([ENABLE_EXTERNAL_SIGNER], [test "x$use_external_signer" = "xyes"])
+
dnl Check for reduced exports
if test x$use_reduce_exports = xyes; then
- AX_CHECK_COMPILE_FLAG([-fvisibility=hidden],[CXXFLAGS="$CXXFLAGS -fvisibility=hidden"],
- [AC_MSG_ERROR([Cannot set hidden symbol visibility. Use --disable-reduce-exports.])],[[$CXXFLAG_WERROR]])
- AX_CHECK_LINK_FLAG([[-Wl,--exclude-libs,ALL]],[RELDFLAGS="-Wl,--exclude-libs,ALL"],,[[$LDFLAG_WERROR]])
+ AX_CHECK_COMPILE_FLAG([-fvisibility=hidden],[CXXFLAGS="$CXXFLAGS -fvisibility=hidden"],
+ [AC_MSG_ERROR([Cannot set hidden symbol visibility. Use --disable-reduce-exports.])],[[$CXXFLAG_WERROR]])
+ AX_CHECK_LINK_FLAG([[-Wl,--exclude-libs,ALL]],[RELDFLAGS="-Wl,--exclude-libs,ALL"],,[[$LDFLAG_WERROR]])
fi
if test x$use_tests = xyes; then
@@ -1435,25 +1435,25 @@ if test x$use_tests = xyes; then
if test x$use_boost = xyes; then
- AX_BOOST_UNIT_TEST_FRAMEWORK
-
- dnl Determine if -DBOOST_TEST_DYN_LINK is needed
- AC_MSG_CHECKING([for dynamic linked boost test])
- TEMP_LIBS="$LIBS"
- LIBS="$LIBS $BOOST_LDFLAGS $BOOST_UNIT_TEST_FRAMEWORK_LIB"
- TEMP_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
- AC_LINK_IFELSE([AC_LANG_SOURCE([
- #define BOOST_TEST_DYN_LINK
- #define BOOST_TEST_MAIN
- #include <boost/test/unit_test.hpp>
-
- ])],
- [AC_MSG_RESULT(yes)]
- [TESTDEFS="$TESTDEFS -DBOOST_TEST_DYN_LINK"],
- [AC_MSG_RESULT(no)])
- LIBS="$TEMP_LIBS"
- CPPFLAGS="$TEMP_CPPFLAGS"
+ AX_BOOST_UNIT_TEST_FRAMEWORK
+
+ dnl Determine if -DBOOST_TEST_DYN_LINK is needed
+ AC_MSG_CHECKING([for dynamic linked boost test])
+ TEMP_LIBS="$LIBS"
+ LIBS="$LIBS $BOOST_LDFLAGS $BOOST_UNIT_TEST_FRAMEWORK_LIB"
+ TEMP_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+ AC_LINK_IFELSE([AC_LANG_SOURCE([
+ #define BOOST_TEST_DYN_LINK
+ #define BOOST_TEST_MAIN
+ #include <boost/test/unit_test.hpp>
+
+ ])],
+ [AC_MSG_RESULT(yes)]
+ [TESTDEFS="$TESTDEFS -DBOOST_TEST_DYN_LINK"],
+ [AC_MSG_RESULT(no)])
+ LIBS="$TEMP_LIBS"
+ CPPFLAGS="$TEMP_CPPFLAGS"
fi
fi
diff --git a/depends/config.site.in b/depends/config.site.in
index 391767357a..f1a59a5861 100644
--- a/depends/config.site.in
+++ b/depends/config.site.in
@@ -54,6 +54,10 @@ if test -z "$with_gui" && test -n "@no_qt@"; then
with_gui=no
fi
+if test -n "@debug@" && test -z "@no_qt@" && test "x$with_gui" != xno; then
+ with_gui=qt5_debug
+fi
+
if test -z "$enable_zmq" && test -n "@no_zmq@"; then
enable_zmq=no
fi
diff --git a/depends/packages/libnatpmp.mk b/depends/packages/libnatpmp.mk
index a24f201859..391b9337b7 100644
--- a/depends/packages/libnatpmp.mk
+++ b/depends/packages/libnatpmp.mk
@@ -6,6 +6,7 @@ $(package)_sha256_hash=e1aa9c4c4219bc06943d6b2130f664daee213fb262fcb94dd355815b8
define $(package)_set_vars
$(package)_build_opts=CC="$($(package)_cc)"
+ $(package)_build_env+=CFLAGS="$($(package)_cflags) $($(package)_cppflags)" AR="$($(package)_ar)"
endef
define $(package)_build_cmds
diff --git a/doc/build-osx.md b/doc/build-osx.md
index 04ee43f81d..52a734c80a 100644
--- a/doc/build-osx.md
+++ b/doc/build-osx.md
@@ -19,7 +19,7 @@ Then install [Homebrew](https://brew.sh).
## Dependencies
```shell
-brew install automake libtool boost miniupnpc libnatpmp pkg-config python qt libevent qrencode
+brew install automake libtool boost miniupnpc libnatpmp pkg-config python qt@5 libevent qrencode
```
If you run into issues, check [Homebrew's troubleshooting page](https://docs.brew.sh/Troubleshooting).
diff --git a/doc/build-unix.md b/doc/build-unix.md
index 07fb9c453e..d7e0ff705d 100644
--- a/doc/build-unix.md
+++ b/doc/build-unix.md
@@ -84,23 +84,22 @@ Now, you can either build from self-compiled [depends](/depends/README.md) or in
sudo apt-get install libevent-dev libboost-dev libboost-system-dev libboost-filesystem-dev libboost-test-dev
-BerkeleyDB is required for the wallet.
+Berkeley DB is required for the wallet.
Ubuntu and Debian have their own `libdb-dev` and `libdb++-dev` packages, but these will install
-BerkeleyDB 5.1 or later. This will break binary wallet compatibility with the distributed executables, which
+Berkeley DB 5.1 or later. This will break binary wallet compatibility with the distributed executables, which
are based on BerkeleyDB 4.8. If you do not care about wallet compatibility,
pass `--with-incompatible-bdb` to configure.
-Otherwise, you can build from self-compiled `depends` (see above).
+Otherwise, you can build Berkeley DB [yourself](#berkeley-db).
-SQLite is required for the wallet:
+SQLite is required for the descriptor wallet:
sudo apt install libsqlite3-dev
-To build Bitcoin Core without wallet, see [*Disable-wallet mode*](/doc/build-unix.md#disable-wallet-mode)
+To build Bitcoin Core without wallet, see [*Disable-wallet mode*](#disable-wallet-mode)
-
-Optional port mapping libraries (see: `--with-miniupnpc`, and `--enable-upnp-default`, `--with-natpmp`, `--enable-natpmp-default`):
+Optional port mapping libraries (see: `--with-miniupnpc`, `--enable-upnp-default`, and `--with-natpmp`, `--enable-natpmp-default`):
sudo apt install libminiupnpc-dev libnatpmp-dev
@@ -132,9 +131,30 @@ built by default.
Build requirements:
- sudo dnf install gcc-c++ libtool make autoconf automake libevent-devel boost-devel libdb4-devel libdb4-cxx-devel python3
+ sudo dnf install gcc-c++ libtool make autoconf automake python3
+
+Now, you can either build from self-compiled [depends](/depends/README.md) or install the required dependencies:
+
+ sudo dnf install libevent-devel boost-devel
+
+Berkeley DB is required for the wallet:
+
+ sudo dnf install libdb4-devel libdb4-cxx-devel
+
+Newer Fedora releases, since Fedora 33, have only `libdb-devel` and `libdb-cxx-devel` packages, but these will install
+Berkeley DB 5.3 or later. This will break binary wallet compatibility with the distributed executables, which
+are based on Berkeley DB 4.8. If you do not care about wallet compatibility,
+pass `--with-incompatible-bdb` to configure.
+
+Otherwise, you can build Berkeley DB [yourself](#berkeley-db).
+
+SQLite is required for the descriptor wallet:
+
+ sudo dnf install sqlite-devel
+
+To build Bitcoin Core without wallet, see [*Disable-wallet mode*](#disable-wallet-mode)
-Optional port mapping libraries (see: `--with-miniupnpc`, and `--enable-upnp-default`, `--with-natpmp`, `--enable-natpmp-default`):
+Optional port mapping libraries (see: `--with-miniupnpc`, `--enable-upnp-default`, and `--with-natpmp`, `--enable-natpmp-default`):
sudo dnf install miniupnpc-devel libnatpmp-devel
@@ -142,6 +162,12 @@ ZMQ dependencies (provides ZMQ API):
sudo dnf install zeromq-devel
+GUI dependencies:
+
+If you want to build bitcoin-qt, make sure that the required packages for Qt development
+are installed. Qt 5 is necessary to build the GUI.
+To build without GUI pass `--without-gui`.
+
To build with Qt 5 you need the following:
sudo dnf install qt5-qttools-devel qt5-qtbase-devel
@@ -150,9 +176,8 @@ libqrencode (optional) can be installed with:
sudo dnf install qrencode-devel
-SQLite can be installed with:
-
- sudo dnf install sqlite-devel
+Once these are installed, they will be found by configure and a bitcoin-qt executable will be
+built by default.
Notes
-----
@@ -193,7 +218,9 @@ like so:
from the root of the repository.
-**Note**: You only need Berkeley DB if the wallet is enabled (see [*Disable-wallet mode*](/doc/build-unix.md#disable-wallet-mode)).
+Otherwise, you can build Bitcoin Core from self-compiled [depends](/depends/README.md).
+
+**Note**: You only need Berkeley DB if the wallet is enabled (see [*Disable-wallet mode*](#disable-wallet-mode)).
Boost
-----
diff --git a/doc/build-windows.md b/doc/build-windows.md
index 28b6aceb3c..d1b84eef42 100644
--- a/doc/build-windows.md
+++ b/doc/build-windows.md
@@ -103,7 +103,7 @@ Build using:
cd depends
make HOST=x86_64-w64-mingw32
cd ..
- ./autogen.sh # not required when building from tarball
+ ./autogen.sh
CONFIG_SITE=$PWD/depends/x86_64-w64-mingw32/share/config.site ./configure --prefix=/
make
sudo bash -c "echo 1 > /proc/sys/fs/binfmt_misc/status" # Enable WSL support for Win32 applications.
diff --git a/share/setup.nsi.in b/share/setup.nsi.in
index 681f243d04..85ae7c57af 100644
--- a/share/setup.nsi.in
+++ b/share/setup.nsi.in
@@ -3,6 +3,7 @@ Name "@PACKAGE_NAME@ (64-bit)"
RequestExecutionLevel highest
SetCompressor /SOLID lzma
SetDateSave off
+Unicode true
# Uncomment these lines when investigating reproducibility errors
#SetCompress off
diff --git a/src/Makefile.test.include b/src/Makefile.test.include
index 502ee5cf37..133277baa6 100644
--- a/src/Makefile.test.include
+++ b/src/Makefile.test.include
@@ -292,6 +292,7 @@ test_fuzz_fuzz_SOURCES = \
test/fuzz/strprintf.cpp \
test/fuzz/system.cpp \
test/fuzz/timedata.cpp \
+ test/fuzz/torcontrol.cpp \
test/fuzz/transaction.cpp \
test/fuzz/tx_in.cpp \
test/fuzz/tx_out.cpp \
diff --git a/src/test/fuzz/torcontrol.cpp b/src/test/fuzz/torcontrol.cpp
new file mode 100644
index 0000000000..b7a42ea7f4
--- /dev/null
+++ b/src/test/fuzz/torcontrol.cpp
@@ -0,0 +1,79 @@
+// Copyright (c) 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.
+
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+#include <torcontrol.h>
+
+#include <cstdint>
+#include <string>
+#include <vector>
+
+class DummyTorControlConnection : public TorControlConnection
+{
+public:
+ DummyTorControlConnection() : TorControlConnection{nullptr}
+ {
+ }
+
+ bool Connect(const std::string&, const ConnectionCB&, const ConnectionCB&)
+ {
+ return true;
+ }
+
+ void Disconnect()
+ {
+ }
+
+ bool Command(const std::string&, const ReplyHandlerCB&)
+ {
+ return true;
+ }
+};
+
+void initialize_torcontrol()
+{
+ static const auto testing_setup = MakeNoLogFileContext<>();
+}
+
+FUZZ_TARGET_INIT(torcontrol, initialize_torcontrol)
+{
+ FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
+
+ TorController tor_controller;
+ while (fuzzed_data_provider.ConsumeBool()) {
+ TorControlReply tor_control_reply;
+ CallOneOf(
+ fuzzed_data_provider,
+ [&] {
+ tor_control_reply.code = 250;
+ },
+ [&] {
+ tor_control_reply.code = 510;
+ },
+ [&] {
+ tor_control_reply.code = fuzzed_data_provider.ConsumeIntegral<int>();
+ });
+ tor_control_reply.lines = ConsumeRandomLengthStringVector(fuzzed_data_provider);
+ if (tor_control_reply.lines.empty()) {
+ break;
+ }
+ DummyTorControlConnection dummy_tor_control_connection;
+ CallOneOf(
+ fuzzed_data_provider,
+ [&] {
+ tor_controller.add_onion_cb(dummy_tor_control_connection, tor_control_reply);
+ },
+ [&] {
+ tor_controller.auth_cb(dummy_tor_control_connection, tor_control_reply);
+ },
+ [&] {
+ tor_controller.authchallenge_cb(dummy_tor_control_connection, tor_control_reply);
+ },
+ [&] {
+ tor_controller.protocolinfo_cb(dummy_tor_control_connection, tor_control_reply);
+ });
+ }
+}
diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp
index 0f2a4895f1..6666e49a2b 100644
--- a/src/torcontrol.cpp
+++ b/src/torcontrol.cpp
@@ -56,77 +56,6 @@ static const int MAX_LINE_LENGTH = 100000;
/****** Low-level TorControlConnection ********/
-/** Reply from Tor, can be single or multi-line */
-class TorControlReply
-{
-public:
- TorControlReply() { Clear(); }
-
- int code;
- std::vector<std::string> lines;
-
- void Clear()
- {
- code = 0;
- lines.clear();
- }
-};
-
-/** Low-level handling for Tor control connection.
- * Speaks the SMTP-like protocol as defined in torspec/control-spec.txt
- */
-class TorControlConnection
-{
-public:
- typedef std::function<void(TorControlConnection&)> ConnectionCB;
- typedef std::function<void(TorControlConnection &,const TorControlReply &)> ReplyHandlerCB;
-
- /** Create a new TorControlConnection.
- */
- explicit TorControlConnection(struct event_base *base);
- ~TorControlConnection();
-
- /**
- * Connect to a Tor control port.
- * tor_control_center is address of the form host:port.
- * connected is the handler that is called when connection is successfully established.
- * disconnected is a handler that is called when the connection is broken.
- * Return true on success.
- */
- bool Connect(const std::string& tor_control_center, const ConnectionCB& connected, const ConnectionCB& disconnected);
-
- /**
- * Disconnect from Tor control port.
- */
- void Disconnect();
-
- /** Send a command, register a handler for the reply.
- * A trailing CRLF is automatically added.
- * Return true on success.
- */
- bool Command(const std::string &cmd, const ReplyHandlerCB& reply_handler);
-
- /** Response handlers for async replies */
- boost::signals2::signal<void(TorControlConnection &,const TorControlReply &)> async_handler;
-private:
- /** Callback when ready for use */
- std::function<void(TorControlConnection&)> connected;
- /** Callback when connection lost */
- std::function<void(TorControlConnection&)> disconnected;
- /** Libevent event base */
- struct event_base *base;
- /** Connection to control socket */
- struct bufferevent *b_conn;
- /** Message being received */
- TorControlReply message;
- /** Response handlers */
- std::deque<ReplyHandlerCB> reply_handlers;
-
- /** Libevent handlers: internal */
- static void readcb(struct bufferevent *bev, void *ctx);
- static void eventcb(struct bufferevent *bev, short what, void *ctx);
-};
-
TorControlConnection::TorControlConnection(struct event_base *_base):
base(_base), b_conn(nullptr)
{
@@ -363,55 +292,6 @@ std::map<std::string,std::string> ParseTorReplyMapping(const std::string &s)
return mapping;
}
-/****** Bitcoin specific TorController implementation ********/
-
-/** Controller that connects to Tor control socket, authenticate, then create
- * and maintain an ephemeral onion service.
- */
-class TorController
-{
-public:
- TorController(struct event_base* base, const std::string& tor_control_center, const CService& target);
- ~TorController();
-
- /** Get name of file to store private key in */
- fs::path GetPrivateKeyFile();
-
- /** Reconnect, after getting disconnected */
- void Reconnect();
-private:
- struct event_base* base;
- const std::string m_tor_control_center;
- TorControlConnection conn;
- std::string private_key;
- std::string service_id;
- bool reconnect;
- struct event *reconnect_ev;
- float reconnect_timeout;
- CService service;
- const CService m_target;
- /** Cookie for SAFECOOKIE auth */
- std::vector<uint8_t> cookie;
- /** ClientNonce for SAFECOOKIE auth */
- std::vector<uint8_t> clientNonce;
-
- /** Callback for ADD_ONION result */
- void add_onion_cb(TorControlConnection& conn, const TorControlReply& reply);
- /** Callback for AUTHENTICATE result */
- void auth_cb(TorControlConnection& conn, const TorControlReply& reply);
- /** Callback for AUTHCHALLENGE result */
- void authchallenge_cb(TorControlConnection& conn, const TorControlReply& reply);
- /** Callback for PROTOCOLINFO result */
- void protocolinfo_cb(TorControlConnection& conn, const TorControlReply& reply);
- /** Callback after successful connection */
- void connected_cb(TorControlConnection& conn);
- /** Callback after connection lost or failed connection attempt */
- void disconnected_cb(TorControlConnection& conn);
-
- /** Callback for reconnect timer */
- static void reconnect_cb(evutil_socket_t fd, short what, void *arg);
-};
-
TorController::TorController(struct event_base* _base, const std::string& tor_control_center, const CService& target):
base(_base),
m_tor_control_center(tor_control_center), conn(base), reconnect(true), reconnect_ev(0),
diff --git a/src/torcontrol.h b/src/torcontrol.h
index 00f19db6ae..7258f27cb6 100644
--- a/src/torcontrol.h
+++ b/src/torcontrol.h
@@ -8,7 +8,19 @@
#ifndef BITCOIN_TORCONTROL_H
#define BITCOIN_TORCONTROL_H
+#include <fs.h>
+#include <netaddress.h>
+
+#include <boost/signals2/signal.hpp>
+
+#include <event2/bufferevent.h>
+#include <event2/event.h>
+
+#include <cstdlib>
+#include <deque>
+#include <functional>
#include <string>
+#include <vector>
class CService;
@@ -21,4 +33,128 @@ void StopTorControl();
CService DefaultOnionServiceTarget();
+/** Reply from Tor, can be single or multi-line */
+class TorControlReply
+{
+public:
+ TorControlReply() { Clear(); }
+
+ int code;
+ std::vector<std::string> lines;
+
+ void Clear()
+ {
+ code = 0;
+ lines.clear();
+ }
+};
+
+/** Low-level handling for Tor control connection.
+ * Speaks the SMTP-like protocol as defined in torspec/control-spec.txt
+ */
+class TorControlConnection
+{
+public:
+ typedef std::function<void(TorControlConnection&)> ConnectionCB;
+ typedef std::function<void(TorControlConnection &,const TorControlReply &)> ReplyHandlerCB;
+
+ /** Create a new TorControlConnection.
+ */
+ explicit TorControlConnection(struct event_base *base);
+ ~TorControlConnection();
+
+ /**
+ * Connect to a Tor control port.
+ * tor_control_center is address of the form host:port.
+ * connected is the handler that is called when connection is successfully established.
+ * disconnected is a handler that is called when the connection is broken.
+ * Return true on success.
+ */
+ bool Connect(const std::string& tor_control_center, const ConnectionCB& connected, const ConnectionCB& disconnected);
+
+ /**
+ * Disconnect from Tor control port.
+ */
+ void Disconnect();
+
+ /** Send a command, register a handler for the reply.
+ * A trailing CRLF is automatically added.
+ * Return true on success.
+ */
+ bool Command(const std::string &cmd, const ReplyHandlerCB& reply_handler);
+
+ /** Response handlers for async replies */
+ boost::signals2::signal<void(TorControlConnection &,const TorControlReply &)> async_handler;
+private:
+ /** Callback when ready for use */
+ std::function<void(TorControlConnection&)> connected;
+ /** Callback when connection lost */
+ std::function<void(TorControlConnection&)> disconnected;
+ /** Libevent event base */
+ struct event_base *base;
+ /** Connection to control socket */
+ struct bufferevent *b_conn;
+ /** Message being received */
+ TorControlReply message;
+ /** Response handlers */
+ std::deque<ReplyHandlerCB> reply_handlers;
+
+ /** Libevent handlers: internal */
+ static void readcb(struct bufferevent *bev, void *ctx);
+ static void eventcb(struct bufferevent *bev, short what, void *ctx);
+};
+
+/****** Bitcoin specific TorController implementation ********/
+
+/** Controller that connects to Tor control socket, authenticate, then create
+ * and maintain an ephemeral onion service.
+ */
+class TorController
+{
+public:
+ TorController(struct event_base* base, const std::string& tor_control_center, const CService& target);
+ TorController() : conn{nullptr} {
+ // Used for testing only.
+ }
+ ~TorController();
+
+ /** Get name of file to store private key in */
+ fs::path GetPrivateKeyFile();
+
+ /** Reconnect, after getting disconnected */
+ void Reconnect();
+private:
+ struct event_base* base;
+ const std::string m_tor_control_center;
+ TorControlConnection conn;
+ std::string private_key;
+ std::string service_id;
+ bool reconnect;
+ struct event *reconnect_ev = nullptr;
+ float reconnect_timeout;
+ CService service;
+ const CService m_target;
+ /** Cookie for SAFECOOKIE auth */
+ std::vector<uint8_t> cookie;
+ /** ClientNonce for SAFECOOKIE auth */
+ std::vector<uint8_t> clientNonce;
+
+public:
+ /** Callback for ADD_ONION result */
+ void add_onion_cb(TorControlConnection& conn, const TorControlReply& reply);
+ /** Callback for AUTHENTICATE result */
+ void auth_cb(TorControlConnection& conn, const TorControlReply& reply);
+ /** Callback for AUTHCHALLENGE result */
+ void authchallenge_cb(TorControlConnection& conn, const TorControlReply& reply);
+ /** Callback for PROTOCOLINFO result */
+ void protocolinfo_cb(TorControlConnection& conn, const TorControlReply& reply);
+ /** Callback after successful connection */
+ void connected_cb(TorControlConnection& conn);
+ /** Callback after connection lost or failed connection attempt */
+ void disconnected_cb(TorControlConnection& conn);
+
+ /** Callback for reconnect timer */
+ static void reconnect_cb(evutil_socket_t fd, short what, void *arg);
+};
+
#endif /* BITCOIN_TORCONTROL_H */