diff options
49 files changed, 252 insertions, 118 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index 237560fc2e..dcd1323291 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -63,7 +63,7 @@ task: FILE_ENV: "./ci/test/00_setup_env_arm.sh" task: - name: 'Win64 [GOAL: deploy] [unit tests, no gui, no boost::process, no functional tests]' + name: 'Win64 [GOAL: deploy] [unit tests, no gui tests, no boost::process, no functional tests]' << : *GLOBAL_TASK_TEMPLATE container: image: ubuntu:bionic @@ -71,7 +71,16 @@ task: FILE_ENV: "./ci/test/00_setup_env_win64.sh" task: - name: 'x86_64 Linux [GOAL: install] [bionic] [C++17, previous releases, uses qt5 dev package and some depends packages] [unsigned char]' + name: '32-bit + dash [GOAL: install] [CentOS 8] [gui]' + << : *GLOBAL_TASK_TEMPLATE + container: + image: centos:8 + env: + PACKAGE_MANAGER_INSTALL: "yum install -y" + FILE_ENV: "./ci/test/00_setup_env_i686_centos.sh" + +task: + name: 'x86_64 Linux [GOAL: install] [bionic] [previous releases, uses qt5 dev package and some depends packages] [unsigned char]' << : *GLOBAL_TASK_TEMPLATE container: image: ubuntu:bionic @@ -122,7 +131,15 @@ task: FILE_ENV: "./ci/test/00_setup_env_native_multiprocess.sh" task: - name: 'macOS 10.12 [GOAL: deploy] [no functional tests]' + name: 'x86_64 Linux [GOAL: install] [bionic] [no wallet]' + << : *GLOBAL_TASK_TEMPLATE + container: + image: ubuntu:bionic + env: + FILE_ENV: "./ci/test/00_setup_env_native_nowallet.sh" + +task: + name: 'macOS 10.14 [GOAL: deploy] [no functional tests]' << : *GLOBAL_TASK_TEMPLATE container: image: ubuntu:bionic @@ -130,7 +147,7 @@ task: FILE_ENV: "./ci/test/00_setup_env_mac.sh" task: - name: 'macOS 10.14 native [GOAL: install] [GUI] [no depends]' + name: 'macOS 10.15 native [GOAL: install] [GUI] [no depends]' macos_brew_addon_script: - brew install boost libevent berkeley-db4 qt miniupnpc ccache zeromq qrencode sqlite libtool automake pkg-config gnu-getopt << : *GLOBAL_TASK_TEMPLATE diff --git a/.travis.yml b/.travis.yml index 780bc9944f..dd76aaacaf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -64,13 +64,3 @@ jobs: - set -o errexit; source ./ci/lint/05_before_script.sh script: - set -o errexit; source ./ci/lint/06_script.sh - - - stage: test - name: '32-bit + dash [GOAL: install] [CentOS 8] [gui]' - env: >- - FILE_ENV="./ci/test/00_setup_env_i686_centos.sh" - - - stage: test - name: 'x86_64 Linux [GOAL: install] [bionic] [no wallet]' - env: >- - FILE_ENV="./ci/test/00_setup_env_native_nowallet.sh" diff --git a/build-aux/m4/bitcoin_find_bdb48.m4 b/build-aux/m4/bitcoin_find_bdb48.m4 index aa0111e5a2..5fc5b493d3 100644 --- a/build-aux/m4/bitcoin_find_bdb48.m4 +++ b/build-aux/m4/bitcoin_find_bdb48.m4 @@ -6,7 +6,9 @@ AC_DEFUN([BITCOIN_FIND_BDB48],[ AC_ARG_VAR(BDB_CFLAGS, [C compiler flags for BerkeleyDB, bypasses autodetection]) AC_ARG_VAR(BDB_LIBS, [Linker flags for BerkeleyDB, bypasses autodetection]) - if test "x$BDB_CFLAGS" = "x"; then + if test "x$use_bdb" = "xno"; then + use_bdb=no + elif test "x$BDB_CFLAGS" = "x"; then AC_MSG_CHECKING([for Berkeley DB C++ headers]) BDB_CPPFLAGS= bdbpath=X @@ -44,25 +46,30 @@ AC_DEFUN([BITCOIN_FIND_BDB48],[ ],[]) done if test "x$bdbpath" = "xX"; then + use_bdb=no AC_MSG_RESULT([no]) - AC_MSG_ERROR([libdb_cxx headers missing, ]AC_PACKAGE_NAME[ requires this library for wallet functionality (--disable-wallet to disable wallet functionality)]) + AC_MSG_ERROR([libdb_cxx headers missing, ]AC_PACKAGE_NAME[ requires this library for BDB wallet support (--without-bdb to disable BDB wallet support)]) elif test "x$bdb48path" = "xX"; then BITCOIN_SUBDIR_TO_INCLUDE(BDB_CPPFLAGS,[${bdbpath}],db_cxx) AC_ARG_WITH([incompatible-bdb],[AS_HELP_STRING([--with-incompatible-bdb], [allow using a bdb version other than 4.8])],[ - AC_MSG_WARN([Found Berkeley DB other than 4.8; wallets opened by this build will not be portable!]) + AC_MSG_WARN([Found Berkeley DB other than 4.8; BDB wallets opened by this build will not be portable!]) ],[ - AC_MSG_ERROR([Found Berkeley DB other than 4.8, required for portable wallets (--with-incompatible-bdb to ignore or --disable-wallet to disable wallet functionality)]) + AC_MSG_ERROR([Found Berkeley DB other than 4.8, required for portable BDB wallets (--with-incompatible-bdb to ignore or --without-bdb to disable BDB wallet support)]) ]) + use_bdb=yes else BITCOIN_SUBDIR_TO_INCLUDE(BDB_CPPFLAGS,[${bdb48path}],db_cxx) bdbpath="${bdb48path}" + use_bdb=yes fi else BDB_CPPFLAGS=${BDB_CFLAGS} fi AC_SUBST(BDB_CPPFLAGS) - if test "x$BDB_LIBS" = "x"; then + if test "x$use_bdb" = "xno"; then + use_bdb=no + elif test "x$BDB_LIBS" = "x"; then # TODO: Ideally this could find the library version and make sure it matches the headers being used for searchlib in db_cxx-4.8 db_cxx db4_cxx; do AC_CHECK_LIB([$searchlib],[main],[ @@ -71,8 +78,12 @@ AC_DEFUN([BITCOIN_FIND_BDB48],[ ]) done if test "x$BDB_LIBS" = "x"; then - AC_MSG_ERROR([libdb_cxx missing, ]AC_PACKAGE_NAME[ requires this library for wallet functionality (--disable-wallet to disable wallet functionality)]) + AC_MSG_ERROR([libdb_cxx missing, ]AC_PACKAGE_NAME[ requires this library for BDB wallet support (--without-bdb to disable BDB wallet support)]) fi fi - AC_SUBST(BDB_LIBS) + if test "x$use_bdb" != "xno"; then + AC_SUBST(BDB_LIBS) + AC_DEFINE([USE_BDB], [1], [Define if BDB support should be compiled in]) + use_bdb=yes + fi ]) diff --git a/build_msvc/bitcoin_config.h b/build_msvc/bitcoin_config.h index aa849fc087..53aead38b5 100644 --- a/build_msvc/bitcoin_config.h +++ b/build_msvc/bitcoin_config.h @@ -35,6 +35,12 @@ /* Define to 1 to enable wallet functions */ #define ENABLE_WALLET 1 +/* Define to 1 to enable BDB wallet */ +#define USE_BDB 1 + +/* Define to 1 to enable SQLite wallet */ +#define USE_SQLITE 1 + /* Define to 1 to enable ZMQ functions */ #define ENABLE_ZMQ 1 diff --git a/build_msvc/bitcoind/bitcoind.vcxproj b/build_msvc/bitcoind/bitcoind.vcxproj index ae24cb100e..48dfafaee0 100644 --- a/build_msvc/bitcoind/bitcoind.vcxproj +++ b/build_msvc/bitcoind/bitcoind.vcxproj @@ -63,6 +63,10 @@ <ReplaceInFile FilePath="$(ConfigIniOut)" Replace="@ENABLE_WALLET_TRUE@" By=""></ReplaceInFile> <ReplaceInFile FilePath="$(ConfigIniOut)" + Replace="@USE_BDB_TRUE@" By=""></ReplaceInFile> + <ReplaceInFile FilePath="$(ConfigIniOut)" + Replace="@USE_SQLITE_TRUE@" By=""></ReplaceInFile> + <ReplaceInFile FilePath="$(ConfigIniOut)" Replace="@BUILD_BITCOIN_CLI_TRUE@" By=""></ReplaceInFile> <ReplaceInFile FilePath="$(ConfigIniOut)" Replace="@BUILD_BITCOIND_TRUE@" By=""></ReplaceInFile> diff --git a/build_msvc/libbitcoin_wallet/libbitcoin_wallet.vcxproj.in b/build_msvc/libbitcoin_wallet/libbitcoin_wallet.vcxproj.in index 9c8279c72a..613d5c7199 100644 --- a/build_msvc/libbitcoin_wallet/libbitcoin_wallet.vcxproj.in +++ b/build_msvc/libbitcoin_wallet/libbitcoin_wallet.vcxproj.in @@ -8,6 +8,9 @@ <ConfigurationType>StaticLibrary</ConfigurationType> </PropertyGroup> <ItemGroup> + <ClCompile Include="..\..\src\wallet\bdb.cpp" /> + <ClCompile Include="..\..\src\wallet\salvage.cpp" /> + <ClCompile Include="..\..\src\wallet\sqlite.cpp" /> @SOURCE_FILES@ </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> diff --git a/ci/test/00_setup_env_i686_centos.sh b/ci/test/00_setup_env_i686_centos.sh index 52cdb75a0c..eaa68b2ded 100644 --- a/ci/test/00_setup_env_i686_centos.sh +++ b/ci/test/00_setup_env_i686_centos.sh @@ -14,3 +14,4 @@ export GOAL="install" export DEP_OPTS="NO_QT=1" # Gui disabled for now to avoid build failures export BITCOIN_CONFIG="--enable-zmq --with-gui=no --enable-reduce-exports --with-boost-process" export CONFIG_SHELL="/bin/dash" +export TEST_RUNNER_ENV="LC_ALL=en_US.UTF-8" diff --git a/ci/test/00_setup_env_mac.sh b/ci/test/00_setup_env_mac.sh index e4450a65ce..4a022f9b39 100644 --- a/ci/test/00_setup_env_mac.sh +++ b/ci/test/00_setup_env_mac.sh @@ -8,7 +8,7 @@ export LC_ALL=C.UTF-8 export CONTAINER_NAME=ci_macos_cross export DOCKER_NAME_TAG=ubuntu:18.04 # Check that bionic can cross-compile to macos (bionic is used in the gitian build as well) -export HOST=x86_64-apple-darwin16 +export HOST=x86_64-apple-darwin18 export PACKAGES="cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python3-dev python3-setuptools" export XCODE_VERSION=11.3.1 export XCODE_BUILD_ID=11C505 diff --git a/ci/test/00_setup_env_mac_host.sh b/ci/test/00_setup_env_mac_host.sh index 7c25a34cfe..906f51fc1a 100644 --- a/ci/test/00_setup_env_mac_host.sh +++ b/ci/test/00_setup_env_mac_host.sh @@ -6,7 +6,7 @@ export LC_ALL=C.UTF-8 -export HOST=x86_64-apple-darwin16 +export HOST=x86_64-apple-darwin18 export PIP_PACKAGES="zmq" export GOAL="install" export BITCOIN_CONFIG="--with-gui --enable-reduce-exports --enable-werror --with-boost-process" diff --git a/ci/test/04_install.sh b/ci/test/04_install.sh index cce0c7e49e..f0ed314d19 100755 --- a/ci/test/04_install.sh +++ b/ci/test/04_install.sh @@ -6,9 +6,6 @@ export LC_ALL=C.UTF-8 -if [[ $DOCKER_NAME_TAG == centos* ]]; then - export LC_ALL=en_US.utf8 -fi if [[ $QEMU_USER_CMD == qemu-s390* ]]; then export LC_ALL=C fi diff --git a/ci/test/05_before_script.sh b/ci/test/05_before_script.sh index 42c244c2f5..d7dd5d9dec 100755 --- a/ci/test/05_before_script.sh +++ b/ci/test/05_before_script.sh @@ -40,7 +40,7 @@ if [ -z "$NO_DEPENDS" ]; then # CentOS has problems building the depends if the config shell is not explicitly set # (i.e. for libevent a Makefile with an empty SHELL variable is generated, leading to # an error as the first command is executed) - SHELL_OPTS="CONFIG_SHELL=/bin/bash" + SHELL_OPTS="LC_ALL=en_US.UTF-8 CONFIG_SHELL=/bin/bash" else SHELL_OPTS="CONFIG_SHELL=" fi diff --git a/configure.ac b/configure.ac index 6b0e374b21..a512fce83e 100644 --- a/configure.ac +++ b/configure.ac @@ -115,7 +115,7 @@ AC_ARG_ENABLE([wallet], [AS_HELP_STRING([--disable-wallet], [disable wallet (enabled by default)])], [enable_wallet=$enableval], - [enable_wallet=yes]) + [enable_wallet=auto]) AC_ARG_WITH([sqlite], [AS_HELP_STRING([--with-sqlite=yes|no|auto], @@ -123,6 +123,12 @@ AC_ARG_WITH([sqlite], [use_sqlite=$withval], [use_sqlite=auto]) +AC_ARG_WITH([bdb], + [AS_HELP_STRING([--without-bdb], + [disable bdb wallet support (default is enabled if wallet is enabled)])], + [use_bdb=$withval], + [use_bdb=auto]) + AC_ARG_WITH([miniupnpc], [AS_HELP_STRING([--with-miniupnpc], [enable UPNP (default is yes if libminiupnpc is found)])], @@ -1237,6 +1243,14 @@ if test x$enable_wallet != xno; then fi fi AC_MSG_RESULT([$use_sqlite]) + + dnl Disable wallet if both --without-bdb and --without-sqlite + if test "x$use_bdb$use_sqlite" = "xnono"; then + if test "x$enable_wallet" = "xyes"; then + AC_MSG_ERROR([wallet functionality requested but no BDB or SQLite support available.]) + fi + enable_wallet=no + fi fi dnl Check for libminiupnpc (optional) @@ -1492,6 +1506,7 @@ AC_MSG_CHECKING([if wallet should be enabled]) if test x$enable_wallet != xno; then AC_MSG_RESULT(yes) AC_DEFINE_UNQUOTED([ENABLE_WALLET],[1],[Define to 1 to enable wallet functions]) + enable_wallet=yes else AC_MSG_RESULT(no) @@ -1591,6 +1606,7 @@ AM_CONDITIONAL([TARGET_LINUX], [test x$TARGET_OS = xlinux]) AM_CONDITIONAL([TARGET_WINDOWS], [test x$TARGET_OS = xwindows]) AM_CONDITIONAL([ENABLE_WALLET],[test x$enable_wallet = xyes]) AM_CONDITIONAL([USE_SQLITE], [test "x$use_sqlite" = "xyes"]) +AM_CONDITIONAL([USE_BDB], [test "x$use_bdb" = "xyes"]) AM_CONDITIONAL([ENABLE_TESTS],[test x$BUILD_TEST = xyes]) AM_CONDITIONAL([ENABLE_FUZZ],[test x$enable_fuzz = xyes]) AM_CONDITIONAL([ENABLE_QT],[test x$bitcoin_enable_qt = xyes]) @@ -1655,6 +1671,7 @@ AC_SUBST(SHANI_CXXFLAGS) AC_SUBST(ARM_CRC_CXXFLAGS) AC_SUBST(LIBTOOL_APP_LDFLAGS) AC_SUBST(USE_SQLITE) +AC_SUBST(USE_BDB) AC_SUBST(USE_UPNP) AC_SUBST(USE_QRCODE) AC_SUBST(BOOST_LIBS) @@ -1732,6 +1749,7 @@ echo " multiprocess = $build_multiprocess" echo " with wallet = $enable_wallet" if test "x$enable_wallet" != "xno"; then echo " with sqlite = $use_sqlite" + echo " with bdb = $use_bdb" fi echo " with gui / qt = $bitcoin_enable_qt" if test x$bitcoin_enable_qt != xno; then diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index 852207edbb..4119e88003 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -37,7 +37,7 @@ script: | set -e -o pipefail WRAP_DIR=$HOME/wrapped - HOSTS="x86_64-apple-darwin16" + HOSTS="x86_64-apple-darwin18" CONFIGFLAGS="--enable-reduce-exports --disable-bench --disable-gui-tests GENISOIMAGE=$WRAP_DIR/genisoimage" FAKETIME_HOST_PROGS="" FAKETIME_PROGS="ar ranlib date dmg genisoimage" diff --git a/depends/README.md b/depends/README.md index 5225a6d5c4..bf8f829848 100644 --- a/depends/README.md +++ b/depends/README.md @@ -25,7 +25,7 @@ Common `host-platform-triplets` for cross compilation are: - `i686-pc-linux-gnu` for Linux 32 bit - `x86_64-pc-linux-gnu` for x86 Linux - `x86_64-w64-mingw32` for Win64 -- `x86_64-apple-darwin16` for macOS +- `x86_64-apple-darwin18` for macOS - `arm-linux-gnueabihf` for Linux ARM 32 bit - `aarch64-linux-gnu` for Linux ARM 64 bit - `powerpc64-linux-gnu` for Linux POWER 64-bit (big endian) diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk index 6099fd4c71..e9faeba336 100644 --- a/depends/hosts/darwin.mk +++ b/depends/hosts/darwin.mk @@ -1,4 +1,4 @@ -OSX_MIN_VERSION=10.12 +OSX_MIN_VERSION=10.14 OSX_SDK_VERSION=10.15.1 XCODE_VERSION=11.3.1 XCODE_BUILD_ID=11C505 diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk index d8bce108b1..0446b07009 100644 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -1,31 +1,27 @@ package=boost -$(package)_version=1_70_0 -$(package)_download_path=https://dl.bintray.com/boostorg/release/1.70.0/source/ +$(package)_version=1_71_0 +$(package)_download_path=https://dl.bintray.com/boostorg/release/$(subst _,.,$($(package)_version))/source/ $(package)_file_name=boost_$($(package)_version).tar.bz2 -$(package)_sha256_hash=430ae8354789de4fd19ee52f3b1f739e1fba576f0aded0897c3c2bc00fb38778 -$(package)_patches=unused_var_in_process.patch +$(package)_sha256_hash=d73a8da01e8bf8c7eda40b4c84915071a8c8a0df4a6734537ddde4a8580524ee +$(package)_dependencies=native_b2 define $(package)_set_vars $(package)_config_opts_release=variant=release $(package)_config_opts_debug=variant=debug $(package)_config_opts=--layout=tagged --build-type=complete --user-config=user-config.jam -$(package)_config_opts+=threading=multi link=static -sNO_BZIP2=1 -sNO_ZLIB=1 +$(package)_config_opts+=threading=multi link=static -sNO_COMPRESSION=1 $(package)_config_opts_linux=target-os=linux threadapi=pthread runtime-link=shared $(package)_config_opts_darwin=target-os=darwin runtime-link=shared $(package)_config_opts_mingw32=target-os=windows binary-format=pe threadapi=win32 runtime-link=static -$(package)_config_opts_x86_64_mingw32=address-model=64 -$(package)_config_opts_i686_mingw32=address-model=32 -$(package)_config_opts_i686_linux=address-model=32 architecture=x86 -$(package)_config_opts_i686_android=address-model=32 -$(package)_config_opts_aarch64_android=address-model=64 -$(package)_config_opts_x86_64_android=address-model=64 -$(package)_config_opts_armv7a_android=address-model=32 -$(package)_toolset_$(host_os)=gcc -$(package)_toolset_darwin=clang +$(package)_config_opts_x86_64=architecture=x86 address-model=64 +$(package)_config_opts_i686=architecture=x86 address-model=32 +$(package)_config_opts_aarch64=address-model=64 +$(package)_config_opts_armv7a=address-model=32 ifneq (,$(findstring clang,$($(package)_cxx))) - $(package)_toolset_$(host_os)=clang +$(package)_toolset_$(host_os)=clang +else +$(package)_toolset_$(host_os)=gcc endif -$(package)_archiver_$(host_os)=$($(package)_ar) $(package)_config_libraries=filesystem,system,thread,test $(package)_cxxflags=-std=c++11 -fvisibility=hidden $(package)_cxxflags_linux=-fPIC @@ -33,18 +29,17 @@ $(package)_cxxflags_android=-fPIC endef define $(package)_preprocess_cmds - patch -p1 < $($(package)_patch_dir)/unused_var_in_process.patch && \ - echo "using $($(package)_toolset_$(host_os)) : : $($(package)_cxx) : <cxxflags>\"$($(package)_cxxflags) $($(package)_cppflags)\" <linkflags>\"$($(package)_ldflags)\" <archiver>\"$($(package)_archiver_$(host_os))\" <striper>\"$(host_STRIP)\" <ranlib>\"$(host_RANLIB)\" <rc>\"$(host_WINDRES)\" : ;" > user-config.jam + echo "using $($(package)_toolset_$(host_os)) : : $($(package)_cxx) : <cflags>\"$($(package)_cflags)\" <cxxflags>\"$($(package)_cxxflags)\" <compileflags>\"$($(package)_cppflags)\" <linkflags>\"$($(package)_ldflags)\" <archiver>\"$($(package)_ar)\" <striper>\"$(host_STRIP)\" <ranlib>\"$(host_RANLIB)\" <rc>\"$(host_WINDRES)\" : ;" > user-config.jam endef define $(package)_config_cmds - ./bootstrap.sh --without-icu --with-libraries=$($(package)_config_libraries) --with-toolset=$($(package)_toolset_$(host_os)) + ./bootstrap.sh --without-icu --with-libraries=$($(package)_config_libraries) --with-toolset=$($(package)_toolset_$(host_os)) --with-bjam=b2 endef define $(package)_build_cmds - ./b2 -d2 -j2 -d1 --prefix=$($(package)_staging_prefix_dir) $($(package)_config_opts) toolset=$($(package)_toolset_$(host_os)) stage + b2 -d2 -j2 -d1 --prefix=$($(package)_staging_prefix_dir) $($(package)_config_opts) toolset=$($(package)_toolset_$(host_os)) stage endef define $(package)_stage_cmds - ./b2 -d0 -j4 --prefix=$($(package)_staging_prefix_dir) $($(package)_config_opts) toolset=$($(package)_toolset_$(host_os)) install + b2 -d0 -j4 --prefix=$($(package)_staging_prefix_dir) $($(package)_config_opts) toolset=$($(package)_toolset_$(host_os)) install endef diff --git a/depends/packages/native_b2.mk b/depends/packages/native_b2.mk new file mode 100644 index 0000000000..aaa37cdcfa --- /dev/null +++ b/depends/packages/native_b2.mk @@ -0,0 +1,20 @@ +package=native_b2 +$(package)_version=$(boost_version) +$(package)_download_path=$(boost_download_path) +$(package)_file_name=$(boost_file_name) +$(package)_sha256_hash=$(boost_sha256_hash) +$(package)_build_subdir=tools/build/src/engine +ifneq (,$(findstring clang,$($(package)_cxx))) +$(package)_toolset_$(host_os)=clang +else +$(package)_toolset_$(host_os)=gcc +endif + +define $(package)_build_cmds + CXX="$($(package)_cxx)" CXXFLAGS="$($(package)_cxxflags)" ./build.sh "$($(package)_toolset_$(host_os))" +endef + +define $(package)_stage_cmds + mkdir -p "$($(package)_staging_prefix_dir)"/bin/ && \ + cp b2 "$($(package)_staging_prefix_dir)"/bin/ +endef diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index ca06b6dd7e..4b4cc7d9ff 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -22,6 +22,8 @@ multiprocess_native_packages = native_libmultiprocess native_capnp darwin_native_packages = native_ds_store native_mac_alias +$(host_arch)_$(host_os)_native_packages += native_b2 + ifneq ($(build_os),darwin) darwin_native_packages += native_cctools native_cdrkit native_libdmg-hfsplus endif diff --git a/depends/patches/boost/unused_var_in_process.patch b/depends/patches/boost/unused_var_in_process.patch deleted file mode 100644 index 722f7bb5ea..0000000000 --- a/depends/patches/boost/unused_var_in_process.patch +++ /dev/null @@ -1,22 +0,0 @@ -commit dbd95cdaefdea95307d004f019a1c394cf9389f0 -Author: fanquake <fanquake@gmail.com> -Date: Mon Aug 17 20:15:17 2020 +0800 - - Remove unused variable in Boost Process - - This causes issues with our linters / CI. - - Can be removed once depends Boost is 1.71.0 or later. - -diff --git a/boost/process/detail/posix/wait_group.hpp b/boost/process/detail/posix/wait_group.hpp -index 9dc249803..2502d9772 100644 ---- a/boost/process/detail/posix/wait_group.hpp -+++ b/boost/process/detail/posix/wait_group.hpp -@@ -137,7 +137,6 @@ inline bool wait_until( - - do - { -- int ret_sig = 0; - int status; - if ((::waitpid(timeout_pid, &status, WNOHANG) != 0) - && (WIFEXITED(status) || WIFSIGNALED(status))) diff --git a/doc/build-osx.md b/doc/build-osx.md index 2a7d71eea6..0a091f6afd 100644 --- a/doc/build-osx.md +++ b/doc/build-osx.md @@ -111,6 +111,6 @@ tail -f $HOME/Library/Application\ Support/Bitcoin/debug.log ``` ## Notes -* Tested on OS X 10.12 Sierra through macOS 10.15 Catalina on 64-bit Intel +* Tested on OS X 10.14 Mojave through macOS 11 Big Sur on 64-bit Intel processors only. * Building with downloaded Qt binaries is not officially supported. See the notes in [#7714](https://github.com/bitcoin/bitcoin/issues/7714). diff --git a/doc/build-unix.md b/doc/build-unix.md index ab83ceff3d..cfe3328b45 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -41,7 +41,7 @@ Optional dependencies: Library | Purpose | Description ------------|------------------|---------------------- miniupnpc | UPnP Support | Firewall-jumping support - libdb4.8 | Berkeley DB | Wallet storage (only needed when wallet enabled) + libdb4.8 | Berkeley DB | Optional, wallet storage (only needed when wallet enabled) qt | GUI | GUI toolkit (only needed when GUI enabled) libqrencode | QR codes in GUI | Optional for generating QR codes (only needed when GUI enabled) univalue | Utility | JSON parsing and encoding (bundled version will be used unless --with-system-univalue passed to configure) diff --git a/doc/dependencies.md b/doc/dependencies.md index 6a743caba2..76e8910871 100644 --- a/doc/dependencies.md +++ b/doc/dependencies.md @@ -6,7 +6,7 @@ These are the dependencies currently used by Bitcoin Core. You can find instruct | Dependency | Version used | Minimum required | CVEs | Shared | [Bundled Qt library](https://doc.qt.io/qt-5/configure-options.html#third-party-libraries) | | --- | --- | --- | --- | --- | --- | | Berkeley DB | [4.8.30](https://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html) | 4.8.x | No | | | -| Boost | [1.70.0](https://www.boost.org/users/download/) | [1.58.0](https://github.com/bitcoin/bitcoin/pull/19667) | No | | | +| Boost | [1.71.0](https://www.boost.org/users/download/) | [1.58.0](https://github.com/bitcoin/bitcoin/pull/19667) | No | | | | Clang | | [5.0+](https://releases.llvm.org/download.html) (C++17 support) | | | | | Expat | [2.2.7](https://libexpat.github.io/) | | No | Yes | | | fontconfig | [2.12.1](https://www.freedesktop.org/software/fontconfig/release/) | | No | Yes | | @@ -33,7 +33,7 @@ Some dependencies are not needed in all configurations. The following are some f #### Options passed to `./configure` * MiniUPnPc is not needed with `--with-miniupnpc=no`. -* Berkeley DB is not needed with `--disable-wallet`. +* Berkeley DB is not needed with `--disable-wallet` or `--without-bdb`. * SQLite is not needed with `--disable-wallet` or `--without-sqlite`. * Qt is not needed with `--without-gui`. * If the qrencode dependency is absent, QR support won't be added. To force an error when that happens, pass `--with-qrencode`. diff --git a/doc/release-notes.md b/doc/release-notes.md index 57067138b0..22015fd7a1 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -46,12 +46,12 @@ Compatibility ============== Bitcoin Core is supported and extensively tested on operating systems -using the Linux kernel, macOS 10.12+, and Windows 7 and newer. Bitcoin +using the Linux kernel, macOS 10.14+, and Windows 7 and newer. Bitcoin Core should also work on most other Unix-like systems but is not as frequently tested on them. It is not recommended to use Bitcoin Core on unsupported systems. -From Bitcoin Core 0.20.0 onwards, macOS versions earlier than 10.12 are no +From Bitcoin Core 0.22.0 onwards, macOS versions earlier than 10.14 are no longer supported. Additionally, Bitcoin Core does not yet change appearance when macOS "dark mode" is activated. diff --git a/share/qt/Info.plist.in b/share/qt/Info.plist.in index 8c0eb22540..207d60aca3 100644 --- a/share/qt/Info.plist.in +++ b/share/qt/Info.plist.in @@ -3,7 +3,7 @@ <plist version="0.9"> <dict> <key>LSMinimumSystemVersion</key> - <string>10.12.0</string> + <string>10.14.0</string> <key>LSArchitecturePriority</key> <array> @@ -17,7 +17,7 @@ <string>APPL</string> <key>NSHumanReadableCopyright</key> - <string>@CLIENT_VERSION_MAJOR@.@CLIENT_VERSION_MINOR@.@.@CLIENT_VERSION_BUILD@, Copyright © 2009-@COPYRIGHT_YEAR@ @COPYRIGHT_HOLDERS_FINAL@</string> + <string>@CLIENT_VERSION_MAJOR@.@CLIENT_VERSION_MINOR@.@CLIENT_VERSION_BUILD@, Copyright © 2009-@COPYRIGHT_YEAR@ @COPYRIGHT_HOLDERS_FINAL@</string> <key>CFBundleShortVersionString</key> <string>@CLIENT_VERSION_MAJOR@.@CLIENT_VERSION_MINOR@.@CLIENT_VERSION_BUILD@</string> diff --git a/share/setup.nsi.in b/share/setup.nsi.in index 1c4dcf3842..681f243d04 100644 --- a/share/setup.nsi.in +++ b/share/setup.nsi.in @@ -56,7 +56,7 @@ CRCCheck on XPStyle on BrandingText " " ShowInstDetails show -VIProductVersion @CLIENT_VERSION_MAJOR@.@CLIENT_VERSION_MINOR@.@.@CLIENT_VERSION_BUILD@ +VIProductVersion @CLIENT_VERSION_MAJOR@.@CLIENT_VERSION_MINOR@.@CLIENT_VERSION_BUILD@.0 VIAddVersionKey ProductName "@PACKAGE_NAME@" VIAddVersionKey ProductVersion "@PACKAGE_VERSION@" VIAddVersionKey CompanyName "${COMPANY}" diff --git a/src/Makefile.am b/src/Makefile.am index 67fd402603..0409faee1e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -360,7 +360,6 @@ libbitcoin_wallet_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(SQLITE_CFLAG libbitcoin_wallet_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_wallet_a_SOURCES = \ interfaces/wallet.cpp \ - wallet/bdb.cpp \ wallet/coincontrol.cpp \ wallet/context.cpp \ wallet/crypter.cpp \ @@ -370,7 +369,6 @@ libbitcoin_wallet_a_SOURCES = \ wallet/load.cpp \ wallet/rpcdump.cpp \ wallet/rpcwallet.cpp \ - wallet/salvage.cpp \ wallet/scriptpubkeyman.cpp \ wallet/wallet.cpp \ wallet/walletdb.cpp \ @@ -381,6 +379,9 @@ libbitcoin_wallet_a_SOURCES = \ if USE_SQLITE libbitcoin_wallet_a_SOURCES += wallet/sqlite.cpp endif +if USE_BDB +libbitcoin_wallet_a_SOURCES += wallet/bdb.cpp wallet/salvage.cpp +endif libbitcoin_wallet_tool_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) libbitcoin_wallet_tool_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) diff --git a/src/Makefile.test.include b/src/Makefile.test.include index f6c5a06f6f..87166ecb79 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -292,7 +292,6 @@ BITCOIN_TESTS =\ if ENABLE_WALLET BITCOIN_TESTS += \ - wallet/test/db_tests.cpp \ wallet/test/psbt_wallet_tests.cpp \ wallet/test/wallet_tests.cpp \ wallet/test/walletdb_tests.cpp \ @@ -302,6 +301,10 @@ BITCOIN_TESTS += \ wallet/test/ismine_tests.cpp \ wallet/test/scriptpubkeyman_tests.cpp +if USE_BDB +BITCOIN_TESTS += wallet/test/db_tests.cpp +endif + BITCOIN_TEST_SUITE += \ wallet/test/wallet_test_fixture.cpp \ wallet/test/wallet_test_fixture.h \ diff --git a/src/net.cpp b/src/net.cpp index e8f5bc2116..9c6d7b6375 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -629,7 +629,7 @@ void CNode::copyStats(CNodeStats &stats, const std::vector<bool> &m_asmap) } #undef X -bool CNode::ReceiveMsgBytes(Span<const char> msg_bytes, bool& complete) +bool CNode::ReceiveMsgBytes(Span<const uint8_t> msg_bytes, bool& complete) { complete = false; const auto time = GetTime<std::chrono::microseconds>(); @@ -673,7 +673,7 @@ bool CNode::ReceiveMsgBytes(Span<const char> msg_bytes, bool& complete) return true; } -int V1TransportDeserializer::readHeader(Span<const char> msg_bytes) +int V1TransportDeserializer::readHeader(Span<const uint8_t> msg_bytes) { // copy data to temporary parsing buffer unsigned int nRemaining = CMessageHeader::HEADER_SIZE - nHdrPos; @@ -713,7 +713,7 @@ int V1TransportDeserializer::readHeader(Span<const char> msg_bytes) return nCopy; } -int V1TransportDeserializer::readData(Span<const char> msg_bytes) +int V1TransportDeserializer::readData(Span<const uint8_t> msg_bytes) { unsigned int nRemaining = hdr.nMessageSize - nDataPos; unsigned int nCopy = std::min<unsigned int>(nRemaining, msg_bytes.size()); @@ -723,7 +723,7 @@ int V1TransportDeserializer::readData(Span<const char> msg_bytes) vRecv.resize(std::min(hdr.nMessageSize, nDataPos + nCopy + 256 * 1024)); } - hasher.Write(MakeUCharSpan(msg_bytes.first(nCopy))); + hasher.Write(msg_bytes.first(nCopy)); memcpy(&vRecv[nDataPos], msg_bytes.data(), nCopy); nDataPos += nCopy; @@ -1463,18 +1463,18 @@ void CConnman::SocketHandler() if (recvSet || errorSet) { // typical socket buffer is 8K-64K - char pchBuf[0x10000]; + uint8_t pchBuf[0x10000]; int nBytes = 0; { LOCK(pnode->cs_hSocket); if (pnode->hSocket == INVALID_SOCKET) continue; - nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT); + nBytes = recv(pnode->hSocket, (char*)pchBuf, sizeof(pchBuf), MSG_DONTWAIT); } if (nBytes > 0) { bool notify = false; - if (!pnode->ReceiveMsgBytes(Span<const char>(pchBuf, nBytes), notify)) + if (!pnode->ReceiveMsgBytes(Span<const uint8_t>(pchBuf, nBytes), notify)) pnode->CloseSocketDisconnect(); RecordBytesRecv(nBytes); if (notify) { @@ -758,7 +758,7 @@ public: // set the serialization context version virtual void SetVersion(int version) = 0; /** read and deserialize data, advances msg_bytes data pointer */ - virtual int Read(Span<const char>& msg_bytes) = 0; + virtual int Read(Span<const uint8_t>& msg_bytes) = 0; // decomposes a message from the context virtual Optional<CNetMessage> GetMessage(std::chrono::microseconds time, uint32_t& out_err) = 0; virtual ~TransportDeserializer() {} @@ -779,8 +779,8 @@ private: unsigned int nDataPos; const uint256& GetMessageHash() const; - int readHeader(Span<const char> msg_bytes); - int readData(Span<const char> msg_bytes); + int readHeader(Span<const uint8_t> msg_bytes); + int readData(Span<const uint8_t> msg_bytes); void Reset() { vRecv.clear(); @@ -814,7 +814,7 @@ public: hdrbuf.SetVersion(nVersionIn); vRecv.SetVersion(nVersionIn); } - int Read(Span<const char>& msg_bytes) override + int Read(Span<const uint8_t>& msg_bytes) override { int ret = in_data ? readData(msg_bytes) : readHeader(msg_bytes); if (ret < 0) { @@ -1132,7 +1132,7 @@ public: * @return True if the peer should stay connected, * False if the peer should be disconnected from. */ - bool ReceiveMsgBytes(Span<const char> msg_bytes, bool& complete); + bool ReceiveMsgBytes(Span<const uint8_t> msg_bytes, bool& complete); void SetCommonVersion(int greatest_common_version) { diff --git a/src/qt/createwalletdialog.cpp b/src/qt/createwalletdialog.cpp index 2ded6a1d89..3945159c26 100644 --- a/src/qt/createwalletdialog.cpp +++ b/src/qt/createwalletdialog.cpp @@ -51,12 +51,15 @@ CreateWalletDialog::CreateWalletDialog(QWidget* parent) : } }); - #ifndef USE_SQLITE +#ifndef USE_SQLITE ui->descriptor_checkbox->setToolTip(tr("Compiled without sqlite support (required for descriptor wallets)")); ui->descriptor_checkbox->setEnabled(false); ui->descriptor_checkbox->setChecked(false); - #endif - +#endif +#ifndef USE_BDB + ui->descriptor_checkbox->setEnabled(false); + ui->descriptor_checkbox->setChecked(true); +#endif } CreateWalletDialog::~CreateWalletDialog() diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 354a82b064..236c6e13d5 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -25,6 +25,9 @@ #include <univalue.h> #ifdef ENABLE_WALLET +#ifdef USE_BDB +#include <wallet/bdb.h> +#endif #include <wallet/db.h> #include <wallet/wallet.h> #endif diff --git a/src/test/fuzz/net.cpp b/src/test/fuzz/net.cpp index 36afd4744d..a0c8b7aac5 100644 --- a/src/test/fuzz/net.cpp +++ b/src/test/fuzz/net.cpp @@ -128,7 +128,7 @@ void test_one_input(const std::vector<uint8_t>& buffer) case 11: { const std::vector<uint8_t> b = ConsumeRandomLengthByteVector(fuzzed_data_provider); bool complete; - node.ReceiveMsgBytes({(const char*)b.data(), b.size()}, complete); + node.ReceiveMsgBytes(b, complete); break; } } diff --git a/src/test/fuzz/p2p_transport_deserializer.cpp b/src/test/fuzz/p2p_transport_deserializer.cpp index 3feabcc99a..7a6236efac 100644 --- a/src/test/fuzz/p2p_transport_deserializer.cpp +++ b/src/test/fuzz/p2p_transport_deserializer.cpp @@ -21,7 +21,7 @@ void test_one_input(const std::vector<uint8_t>& buffer) { // Construct deserializer, with a dummy NodeId V1TransportDeserializer deserializer{Params(), (NodeId)0, SER_NETWORK, INIT_PROTO_VERSION}; - Span<const char> msg_bytes{(const char*)buffer.data(), buffer.size()}; + Span<const uint8_t> msg_bytes{buffer}; while (msg_bytes.size() > 0) { const int handled = deserializer.Read(msg_bytes); if (handled < 0) { diff --git a/src/test/util/net.cpp b/src/test/util/net.cpp index 3b31ec4031..847a490e03 100644 --- a/src/test/util/net.cpp +++ b/src/test/util/net.cpp @@ -7,7 +7,7 @@ #include <chainparams.h> #include <net.h> -void ConnmanTestMsg::NodeReceiveMsgBytes(CNode& node, Span<const char> msg_bytes, bool& complete) const +void ConnmanTestMsg::NodeReceiveMsgBytes(CNode& node, Span<const uint8_t> msg_bytes, bool& complete) const { assert(node.ReceiveMsgBytes(msg_bytes, complete)); if (complete) { @@ -29,11 +29,11 @@ void ConnmanTestMsg::NodeReceiveMsgBytes(CNode& node, Span<const char> msg_bytes bool ConnmanTestMsg::ReceiveMsgFrom(CNode& node, CSerializedNetMsg& ser_msg) const { - std::vector<unsigned char> ser_msg_header; + std::vector<uint8_t> ser_msg_header; node.m_serializer->prepareForTransport(ser_msg, ser_msg_header); bool complete; - NodeReceiveMsgBytes(node, {(const char*)ser_msg_header.data(), ser_msg_header.size()}, complete); - NodeReceiveMsgBytes(node, {(const char*)ser_msg.data.data(), ser_msg.data.size()}, complete); + NodeReceiveMsgBytes(node, ser_msg_header, complete); + NodeReceiveMsgBytes(node, ser_msg.data, complete); return complete; } diff --git a/src/test/util/net.h b/src/test/util/net.h index fe423e7e89..1208e92762 100644 --- a/src/test/util/net.h +++ b/src/test/util/net.h @@ -25,7 +25,7 @@ struct ConnmanTestMsg : public CConnman { void ProcessMessagesOnce(CNode& node) { m_msgproc->ProcessMessages(&node, flagInterruptMsgProc); } - void NodeReceiveMsgBytes(CNode& node, Span<const char> msg_bytes, bool& complete) const; + void NodeReceiveMsgBytes(CNode& node, Span<const uint8_t> msg_bytes, bool& complete) const; bool ReceiveMsgFrom(CNode& node, CSerializedNetMsg& ser_msg) const; }; diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 8f2fc71cce..36fa1a0299 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -1423,10 +1423,18 @@ BOOST_AUTO_TEST_CASE(test_ParseInt32) BOOST_CHECK(ParseInt32("2147483647", &n) && n == 2147483647); BOOST_CHECK(ParseInt32("-2147483648", &n) && n == (-2147483647 - 1)); // (-2147483647 - 1) equals INT_MIN BOOST_CHECK(ParseInt32("-1234", &n) && n == -1234); + BOOST_CHECK(ParseInt32("00000000000000001234", &n) && n == 1234); + BOOST_CHECK(ParseInt32("-00000000000000001234", &n) && n == -1234); + BOOST_CHECK(ParseInt32("00000000000000000000", &n) && n == 0); + BOOST_CHECK(ParseInt32("-00000000000000000000", &n) && n == 0); // Invalid values BOOST_CHECK(!ParseInt32("", &n)); BOOST_CHECK(!ParseInt32(" 1", &n)); // no padding inside BOOST_CHECK(!ParseInt32("1 ", &n)); + BOOST_CHECK(!ParseInt32("++1", &n)); + BOOST_CHECK(!ParseInt32("+-1", &n)); + BOOST_CHECK(!ParseInt32("-+1", &n)); + BOOST_CHECK(!ParseInt32("--1", &n)); BOOST_CHECK(!ParseInt32("1a", &n)); BOOST_CHECK(!ParseInt32("aap", &n)); BOOST_CHECK(!ParseInt32("0x1", &n)); // no hex @@ -1482,10 +1490,19 @@ BOOST_AUTO_TEST_CASE(test_ParseUInt32) BOOST_CHECK(ParseUInt32("2147483647", &n) && n == 2147483647); BOOST_CHECK(ParseUInt32("2147483648", &n) && n == (uint32_t)2147483648); BOOST_CHECK(ParseUInt32("4294967295", &n) && n == (uint32_t)4294967295); + BOOST_CHECK(ParseUInt32("+1234", &n) && n == 1234); + BOOST_CHECK(ParseUInt32("00000000000000001234", &n) && n == 1234); + BOOST_CHECK(ParseUInt32("00000000000000000000", &n) && n == 0); // Invalid values + BOOST_CHECK(!ParseUInt32("-00000000000000000000", &n)); BOOST_CHECK(!ParseUInt32("", &n)); BOOST_CHECK(!ParseUInt32(" 1", &n)); // no padding inside BOOST_CHECK(!ParseUInt32(" -1", &n)); + BOOST_CHECK(!ParseUInt32("++1", &n)); + BOOST_CHECK(!ParseUInt32("+-1", &n)); + BOOST_CHECK(!ParseUInt32("-+1", &n)); + BOOST_CHECK(!ParseUInt32("--1", &n)); + BOOST_CHECK(!ParseUInt32("-1", &n)); BOOST_CHECK(!ParseUInt32("1 ", &n)); BOOST_CHECK(!ParseUInt32("1a", &n)); BOOST_CHECK(!ParseUInt32("aap", &n)); diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp index 8b2ef191fb..085dde1026 100644 --- a/src/wallet/init.cpp +++ b/src/wallet/init.cpp @@ -15,6 +15,9 @@ #include <util/moneystr.h> #include <util/system.h> #include <util/translation.h> +#ifdef USE_BDB +#include <wallet/bdb.h> +#endif #include <wallet/coincontrol.h> #include <wallet/wallet.h> #include <walletinitinterface.h> @@ -68,9 +71,14 @@ void WalletInit::AddWalletOptions(ArgsManager& argsman) const #endif argsman.AddArg("-walletrbf", strprintf("Send transactions with full-RBF opt-in enabled (RPC only, default: %u)", DEFAULT_WALLET_RBF), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET); +#ifdef USE_BDB argsman.AddArg("-dblogsize=<n>", strprintf("Flush wallet database activity from memory to disk log every <n> megabytes (default: %u)", DEFAULT_WALLET_DBLOGSIZE), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::WALLET_DEBUG_TEST); argsman.AddArg("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", DEFAULT_FLUSHWALLET), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::WALLET_DEBUG_TEST); argsman.AddArg("-privdb", strprintf("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)", DEFAULT_WALLET_PRIVDB), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::WALLET_DEBUG_TEST); +#else + argsman.AddHiddenArgs({"-dblogsize", "-flushwallet", "-privdb"}); +#endif + argsman.AddArg("-walletrejectlongchains", strprintf("Wallet will not create transactions that violate mempool chain limits (default: %u)", DEFAULT_WALLET_REJECT_LONG_CHAINS), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::WALLET_DEBUG_TEST); argsman.AddHiddenArgs({"-zapwallettxes"}); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index dd75e876bc..a00a544637 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2757,6 +2757,12 @@ static RPCHelpMan createwallet() warnings.emplace_back(Untranslated("Wallet is an experimental descriptor wallet")); } +#ifndef USE_BDB + if (!(flags & WALLET_FLAG_DESCRIPTORS)) { + throw JSONRPCError(RPC_WALLET_ERROR, "Compiled without bdb support (required for legacy wallets)"); + } +#endif + DatabaseOptions options; DatabaseStatus status; options.require_create = true; @@ -2785,7 +2791,7 @@ static RPCHelpMan unloadwallet() "Unloads the wallet referenced by the request endpoint otherwise unloads the wallet specified in the argument.\n" "Specifying the wallet name on a wallet endpoint is invalid.", { - {"wallet_name", RPCArg::Type::STR, /* default */ "the wallet name from the RPC request", "The name of the wallet to unload."}, + {"wallet_name", RPCArg::Type::STR, /* default */ "the wallet name from the RPC endpoint", "The name of the wallet to unload. Must be provided in the RPC endpoint or this parameter (but not both)."}, {"load_on_startup", RPCArg::Type::BOOL, /* default */ "null", "Save wallet name to persistent settings and load on startup. True to add wallet to startup list, false to remove, null to leave unchanged."}, }, RPCResult{RPCResult::Type::OBJ, "", "", { @@ -2800,7 +2806,7 @@ static RPCHelpMan unloadwallet() std::string wallet_name; if (GetWalletNameFromJSONRPCRequest(request, wallet_name)) { if (!request.params[0].isNull()) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot unload the requested wallet"); + throw JSONRPCError(RPC_INVALID_PARAMETER, "Both the RPC endpoint wallet and wallet_name parameter were provided (only one allowed)"); } } else { wallet_name = request.params[0].get_str(); diff --git a/src/wallet/salvage.cpp b/src/wallet/salvage.cpp index 225b975067..da5ca7858f 100644 --- a/src/wallet/salvage.cpp +++ b/src/wallet/salvage.cpp @@ -6,6 +6,7 @@ #include <fs.h> #include <streams.h> #include <util/translation.h> +#include <wallet/bdb.h> #include <wallet/salvage.h> #include <wallet/wallet.h> #include <wallet/walletdb.h> @@ -27,6 +28,7 @@ bool RecoverDatabaseFile(const fs::path& file_path, bilingual_str& error, std::v DatabaseStatus status; options.require_existing = true; options.verify = false; + options.require_format = DatabaseFormat::BERKELEY; std::unique_ptr<WalletDatabase> database = MakeDatabase(file_path, options, status, error); if (!database) return false; diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp index d2e1be6402..7ed20e4394 100644 --- a/src/wallet/scriptpubkeyman.cpp +++ b/src/wallet/scriptpubkeyman.cpp @@ -3,12 +3,15 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <key_io.h> +#include <logging.h> #include <outputtype.h> #include <script/descriptor.h> #include <script/sign.h> #include <util/bip32.h> #include <util/strencodings.h> #include <util/string.h> +#include <util/system.h> +#include <util/time.h> #include <util/translation.h> #include <wallet/scriptpubkeyman.h> diff --git a/src/wallet/scriptpubkeyman.h b/src/wallet/scriptpubkeyman.h index 3bf8f78120..43791acfcf 100644 --- a/src/wallet/scriptpubkeyman.h +++ b/src/wallet/scriptpubkeyman.h @@ -11,6 +11,7 @@ #include <script/standard.h> #include <util/error.h> #include <util/message.h> +#include <util/time.h> #include <wallet/crypter.h> #include <wallet/ismine.h> #include <wallet/walletdb.h> diff --git a/src/wallet/sqlite.cpp b/src/wallet/sqlite.cpp index d83332c194..d278d96476 100644 --- a/src/wallet/sqlite.cpp +++ b/src/wallet/sqlite.cpp @@ -206,7 +206,9 @@ void SQLiteDatabase::Open() } if (m_db == nullptr) { - TryCreateDirectories(m_dir_path); + if (!m_mock) { + TryCreateDirectories(m_dir_path); + } int ret = sqlite3_open_v2(m_file_path.c_str(), &m_db, flags, nullptr); if (ret != SQLITE_OK) { throw std::runtime_error(strprintf("SQLiteDatabase: Failed to open database: %s\n", sqlite3_errstr(ret))); diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 5d3fbd3431..45807ae6fd 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -14,7 +14,9 @@ #include <util/system.h> #include <util/time.h> #include <util/translation.h> +#ifdef USE_BDB #include <wallet/bdb.h> +#endif #ifdef USE_SQLITE #include <wallet/sqlite.h> #endif @@ -1011,9 +1013,11 @@ std::unique_ptr<WalletDatabase> MakeDatabase(const fs::path& path, const Databas Optional<DatabaseFormat> format; if (exists) { +#ifdef USE_BDB if (ExistsBerkeleyDatabase(path)) { format = DatabaseFormat::BERKELEY; } +#endif #ifdef USE_SQLITE if (ExistsSQLiteDatabase(path)) { if (format) { @@ -1052,15 +1056,31 @@ std::unique_ptr<WalletDatabase> MakeDatabase(const fs::path& path, const Databas // Format is not set when a db doesn't already exist, so use the format specified by the options if it is set. if (!format && options.require_format) format = options.require_format; + // If the format is not specified or detected, choose the default format based on what is available. We prefer BDB over SQLite for now. + if (!format) { #ifdef USE_SQLITE - if (format && format == DatabaseFormat::SQLITE) { - return MakeSQLiteDatabase(path, options, status, error); + format = DatabaseFormat::SQLITE; +#endif +#ifdef USE_BDB + format = DatabaseFormat::BERKELEY; +#endif } -#else - assert(format != DatabaseFormat::SQLITE); + + if (format == DatabaseFormat::SQLITE) { +#ifdef USE_SQLITE + return MakeSQLiteDatabase(path, options, status, error); #endif + error = Untranslated(strprintf("Failed to open database path '%s'. Build does not support SQLite database format.", path.string())); + status = DatabaseStatus::FAILED_BAD_FORMAT; + return nullptr; + } +#ifdef USE_BDB return MakeBerkeleyDatabase(path, options, status, error); +#endif + error = Untranslated(strprintf("Failed to open database path '%s'. Build does not support Berkeley DB database format.", path.string())); + status = DatabaseStatus::FAILED_BAD_FORMAT; + return nullptr; } /** Return object for accessing dummy database with no read/write capabilities. */ @@ -1072,5 +1092,9 @@ std::unique_ptr<WalletDatabase> CreateDummyWalletDatabase() /** Return object for accessing temporary in-memory database. */ std::unique_ptr<WalletDatabase> CreateMockWalletDatabase() { +#ifdef USE_BDB return MakeUnique<BerkeleyDatabase>(std::make_shared<BerkeleyEnvironment>(), ""); +#elif USE_SQLITE + return MakeUnique<SQLiteDatabase>("", "", true); +#endif } diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index 7f1b86e458..e7b2d7d780 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -8,7 +8,6 @@ #include <amount.h> #include <script/sign.h> -#include <wallet/bdb.h> #include <wallet/db.h> #include <wallet/walletutil.h> #include <key.h> diff --git a/src/wallet/wallettool.cpp b/src/wallet/wallettool.cpp index 0e18d6a740..dad1232e10 100644 --- a/src/wallet/wallettool.cpp +++ b/src/wallet/wallettool.cpp @@ -122,6 +122,7 @@ bool ExecuteWalletToolFunc(const std::string& command, const std::string& name) WalletShowInfo(wallet_instance.get()); wallet_instance->Close(); } else if (command == "salvage") { +#ifdef USE_BDB bilingual_str error; std::vector<bilingual_str> warnings; bool ret = RecoverDatabaseFile(path, error, warnings); @@ -134,6 +135,10 @@ bool ExecuteWalletToolFunc(const std::string& command, const std::string& name) } } return ret; +#else + tfm::format(std::cerr, "Salvage command is not available as BDB support is not compiled"); + return false; +#endif } } else { tfm::format(std::cerr, "Invalid command: %s\n", command); diff --git a/src/wallet/walletutil.cpp b/src/wallet/walletutil.cpp index 702293e6c7..d3f76ec66c 100644 --- a/src/wallet/walletutil.cpp +++ b/src/wallet/walletutil.cpp @@ -7,7 +7,11 @@ #include <logging.h> #include <util/system.h> +#ifdef USE_BDB bool ExistsBerkeleyDatabase(const fs::path& path); +#else +# define ExistsBerkeleyDatabase(path) (false) +#endif #ifdef USE_SQLITE bool ExistsSQLiteDatabase(const fs::path& path); #else diff --git a/test/config.ini.in b/test/config.ini.in index 4b4a092a9d..77c9a720c3 100644 --- a/test/config.ini.in +++ b/test/config.ini.in @@ -17,6 +17,7 @@ RPCAUTH=@abs_top_srcdir@/share/rpcauth/rpcauth.py # Which components are enabled. These are commented out by `configure` if they were disabled when running config. @ENABLE_WALLET_TRUE@ENABLE_WALLET=true @USE_SQLITE_TRUE@USE_SQLITE=true +@USE_BDB_TRUE@USE_BDB=true @BUILD_BITCOIN_CLI_TRUE@ENABLE_CLI=true @BUILD_BITCOIN_WALLET_TRUE@ENABLE_WALLET_TOOL=true @BUILD_BITCOIND_TRUE@ENABLE_BITCOIND=true diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py index 831599913d..bf047c5f68 100755 --- a/test/functional/test_framework/test_framework.py +++ b/test/functional/test_framework/test_framework.py @@ -782,6 +782,11 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass): if not self.is_sqlite_compiled(): raise SkipTest("sqlite has not been compiled.") + def skip_if_no_bdb(self): + """Skip the running test if BDB has not been compiled.""" + if not self.is_bdb_compiled(): + raise SkipTest("BDB has not been compiled.") + def skip_if_no_wallet_tool(self): """Skip the running test if bitcoin-wallet has not been compiled.""" if not self.is_wallet_tool_compiled(): @@ -822,5 +827,9 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass): return self.config["components"].getboolean("ENABLE_ZMQ") def is_sqlite_compiled(self): - """Checks whether the wallet module was compiled.""" + """Checks whether the wallet module was compiled with Sqlite support.""" return self.config["components"].getboolean("USE_SQLITE") + + def is_bdb_compiled(self): + """Checks whether the wallet module was compiled with BDB support.""" + return self.config["components"].getboolean("USE_BDB") diff --git a/test/functional/wallet_multiwallet.py b/test/functional/wallet_multiwallet.py index df16ec741f..0d715b3130 100755 --- a/test/functional/wallet_multiwallet.py +++ b/test/functional/wallet_multiwallet.py @@ -355,7 +355,8 @@ class MultiWalletTest(BitcoinTestFramework): assert_raises_rpc_error(-1, "JSON value is not a string as expected", self.nodes[0].unloadwallet) assert_raises_rpc_error(-18, "Requested wallet does not exist or is not loaded", self.nodes[0].unloadwallet, "dummy") assert_raises_rpc_error(-18, "Requested wallet does not exist or is not loaded", node.get_wallet_rpc("dummy").unloadwallet) - assert_raises_rpc_error(-8, "Cannot unload the requested wallet", w1.unloadwallet, "w2"), + assert_raises_rpc_error(-8, "Both the RPC endpoint wallet and wallet_name parameter were provided (only one allowed)", w1.unloadwallet, "w2"), + assert_raises_rpc_error(-8, "Both the RPC endpoint wallet and wallet_name parameter were provided (only one allowed)", w1.unloadwallet, "w1"), # Successfully unload the specified wallet name self.nodes[0].unloadwallet("w1") |