aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml8
-rw-r--r--Makefile.am14
-rw-r--r--ci/test/00_setup_env_native_centos.sh14
-rw-r--r--ci/test/00_setup_env_native_trusty.sh14
-rwxr-xr-xci/test/04_install.sh11
-rw-r--r--configure.ac1
-rwxr-xr-xcontrib/gitian-build.py2
-rw-r--r--contrib/gitian-descriptors/gitian-win-signer.yml2
-rw-r--r--depends/Makefile7
-rw-r--r--depends/README.md1
-rw-r--r--depends/config.site.in4
-rw-r--r--depends/packages/packages.mk4
-rw-r--r--depends/packages/qt.mk1
-rw-r--r--doc/release-process.md2
-rw-r--r--src/Makefile.test.include126
-rw-r--r--src/pubkey.cpp6
-rw-r--r--src/qt/bitcoingui.cpp2
-rw-r--r--src/qt/optionsdialog.cpp4
-rw-r--r--src/random.cpp75
-rw-r--r--src/random.h2
-rw-r--r--src/test/fuzz/descriptor_parse.cpp3
-rw-r--r--src/test/fuzz/deserialize.cpp318
-rw-r--r--src/test/fuzz/transaction.cpp22
-rw-r--r--src/wallet/scriptpubkeyman.cpp40
-rw-r--r--src/wallet/scriptpubkeyman.h19
-rw-r--r--src/wallet/wallet.cpp15
-rw-r--r--src/wallet/wallet.h5
-rwxr-xr-xtest/functional/wallet_abandonconflict.py5
-rwxr-xr-xtest/fuzz/test_runner.py27
29 files changed, 539 insertions, 215 deletions
diff --git a/.travis.yml b/.travis.yml
index 8a04326bab..4f9dbeded4 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -105,14 +105,14 @@ jobs:
FILE_ENV="./ci/test/00_setup_env_i686.sh"
- stage: test
- name: 'x86_64 Linux [GOAL: install] [bionic] [uses qt5 dev package instead of depends Qt to speed up build and avoid timeout] [unsigned char]'
+ name: 'x86_64 Linux [GOAL: install] [CentOS 7] [no depends, only system libs]'
env: >-
- FILE_ENV="./ci/test/00_setup_env_native_qt5.sh"
+ FILE_ENV="./ci/test/00_setup_env_native_centos.sh"
- stage: test
- name: 'x86_64 Linux [GOAL: install] [trusty] [no functional tests, no depends, only system libs]'
+ name: 'x86_64 Linux [GOAL: install] [bionic] [uses qt5 dev package instead of depends Qt to speed up build and avoid timeout] [unsigned char]'
env: >-
- FILE_ENV="./ci/test/00_setup_env_native_trusty.sh"
+ FILE_ENV="./ci/test/00_setup_env_native_qt5.sh"
- stage: test
name: 'x86_64 Linux [GOAL: install] [xenial] [no depends, only system libs, sanitizers: thread (TSan), no wallet]'
diff --git a/Makefile.am b/Makefile.am
index deae2c1b57..f121c33b24 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -99,7 +99,7 @@ $(OSX_APP)/Contents/PkgInfo:
$(OSX_APP)/Contents/Resources/empty.lproj:
$(MKDIR_P) $(@D)
- @touch $@
+ @touch $@
$(OSX_APP)/Contents/Info.plist: $(OSX_PLIST)
$(MKDIR_P) $(@D)
@@ -189,7 +189,16 @@ $(BITCOIN_WALLET_BIN): FORCE
$(MAKE) -C src $(@F)
if USE_LCOV
-LCOV_FILTER_PATTERN=-p "/usr/include/" -p "/usr/lib/" -p "src/leveldb/" -p "src/bench/" -p "src/univalue" -p "src/crypto/ctaes" -p "src/secp256k1"
+LCOV_FILTER_PATTERN = \
+ -p "/usr/include/" \
+ -p "/usr/lib/" \
+ -p "/usr/lib64/" \
+ -p "src/leveldb/" \
+ -p "src/bench/" \
+ -p "src/univalue" \
+ -p "src/crypto/ctaes" \
+ -p "src/secp256k1" \
+ -p "depends"
baseline.info:
$(LCOV) -c -i -d $(abs_builddir)/src -o $@
@@ -321,4 +330,3 @@ clean-local: clean-docs
rm -rf coverage_percent.txt test_bitcoin.coverage/ total.coverage/ test/tmp/ cache/ $(OSX_APP)
rm -rf test/functional/__pycache__ test/functional/test_framework/__pycache__ test/cache share/rpcauth/__pycache__
rm -rf osx_volname dist/ dpi36.background.tiff dpi72.background.tiff
-
diff --git a/ci/test/00_setup_env_native_centos.sh b/ci/test/00_setup_env_native_centos.sh
new file mode 100644
index 0000000000..56b915b6c7
--- /dev/null
+++ b/ci/test/00_setup_env_native_centos.sh
@@ -0,0 +1,14 @@
+#!/usr/bin/env bash
+#
+# Copyright (c) 2019 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+export LC_ALL=C.UTF-8
+
+export DOCKER_NAME_TAG=centos:7
+export DOCKER_PACKAGES="gcc-c++ libtool make git python3 python36-zmq"
+export PACKAGES="boost-devel libevent-devel libdb4-devel libdb4-cxx-devel miniupnpc-devel zeromq-devel qt5-qtbase-devel qt5-qttools-devel qrencode-devel"
+export NO_DEPENDS=1
+export GOAL="install"
+export BITCOIN_CONFIG="--enable-reduce-exports"
diff --git a/ci/test/00_setup_env_native_trusty.sh b/ci/test/00_setup_env_native_trusty.sh
deleted file mode 100644
index 893c1f6b53..0000000000
--- a/ci/test/00_setup_env_native_trusty.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) 2019 The Bitcoin Core developers
-# Distributed under the MIT software license, see the accompanying
-# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-export LC_ALL=C.UTF-8
-
-export DOCKER_NAME_TAG=ubuntu:14.04
-export PACKAGES="python3-zmq qtbase5-dev qttools5-dev-tools libicu-dev libpng-dev libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-test-dev libboost-thread-dev libdb5.1++-dev libzmq3-dev libqrencode-dev"
-export NO_DEPENDS=1
-export RUN_FUNCTIONAL_TESTS=false
-export GOAL="install"
-export BITCOIN_CONFIG="--enable-zmq --with-incompatible-bdb --with-gui=no"
diff --git a/ci/test/04_install.sh b/ci/test/04_install.sh
index b9eaae0b0d..c721345250 100755
--- a/ci/test/04_install.sh
+++ b/ci/test/04_install.sh
@@ -6,6 +6,10 @@
export LC_ALL=C.UTF-8
+if [[ $DOCKER_NAME_TAG == centos* ]]; then
+ export LC_ALL=en_US.utf8
+fi
+
if [ "$TRAVIS_OS_NAME" == "osx" ]; then
set +o errexit
pushd /usr/local/Homebrew || exit 1
@@ -33,7 +37,7 @@ fi
mkdir -p "${BASE_SCRATCH_DIR}"
mkdir -p "${CCACHE_DIR}"
-export ASAN_OPTIONS="detect_stack_use_after_return=1"
+export ASAN_OPTIONS="detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1"
export LSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/lsan"
export TSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/tsan:log_path=${BASE_SCRATCH_DIR}/sanitizer-output/tsan"
export UBSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/ubsan:print_stacktrace=1:halt_on_error=1:report_error_type=1"
@@ -82,7 +86,10 @@ if [ -n "$DPKG_ADD_ARCH" ]; then
DOCKER_EXEC dpkg --add-architecture "$DPKG_ADD_ARCH"
fi
-if [ "$TRAVIS_OS_NAME" != "osx" ]; then
+if [[ $DOCKER_NAME_TAG == centos* ]]; then
+ ${CI_RETRY_EXE} DOCKER_EXEC yum -y install epel-release
+ ${CI_RETRY_EXE} DOCKER_EXEC yum -y install $DOCKER_PACKAGES $PACKAGES
+elif [ "$TRAVIS_OS_NAME" != "osx" ]; then
${CI_RETRY_EXE} DOCKER_EXEC apt-get update
${CI_RETRY_EXE} DOCKER_EXEC apt-get install --no-install-recommends --no-upgrade -y $PACKAGES $DOCKER_PACKAGES
fi
diff --git a/configure.ac b/configure.ac
index ed9ccade6d..e0bec0882e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -783,6 +783,7 @@ fi
dnl this flag screws up non-darwin gcc even when the check fails. special-case it.
if test x$TARGET_OS = xdarwin; then
AX_CHECK_LINK_FLAG([[-Wl,-dead_strip]], [LDFLAGS="$LDFLAGS -Wl,-dead_strip"])
+ AX_CHECK_LINK_FLAG([[-Wl,-dead_strip_dylibs]], [LDFLAGS="$LDFLAGS -Wl,-dead_strip_dylibs"])
fi
AC_CHECK_HEADERS([endian.h sys/endian.h byteswap.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h sys/sysctl.h vm/vm_param.h sys/vmmeter.h sys/resources.h])
diff --git a/contrib/gitian-build.py b/contrib/gitian-build.py
index 712352d6b7..e38fa6fcb0 100755
--- a/contrib/gitian-build.py
+++ b/contrib/gitian-build.py
@@ -51,7 +51,7 @@ def build():
os.chdir('gitian-builder')
os.makedirs('inputs', exist_ok=True)
- subprocess.check_call(['wget', '-O' 'osslsigncode-2.0.tar.gz' '-N', '-P', 'inputs', 'https://github.com/mtrojnar/osslsigncode/archive/2.0.tar.gz'])
+ subprocess.check_call(['wget', '-O', 'inputs/osslsigncode-2.0.tar.gz', 'https://github.com/mtrojnar/osslsigncode/archive/2.0.tar.gz'])
subprocess.check_call(["echo '5a60e0a4b3e0b4d655317b2f12a810211c50242138322b16e7e01c6fbb89d92f inputs/osslsigncode-2.0.tar.gz' | sha256sum -c"], shell=True)
subprocess.check_call(['make', '-C', '../bitcoin/depends', 'download', 'SOURCES_PATH=' + os.getcwd() + '/cache/common'])
diff --git a/contrib/gitian-descriptors/gitian-win-signer.yml b/contrib/gitian-descriptors/gitian-win-signer.yml
index 6a52db1f9f..70b7bb111d 100644
--- a/contrib/gitian-descriptors/gitian-win-signer.yml
+++ b/contrib/gitian-descriptors/gitian-win-signer.yml
@@ -36,6 +36,6 @@ script: |
make
find ${UNSIGNED_DIR} -name "*-unsigned.exe" | while read i; do
INFILE="$(basename "${i}")"
- OUTFILE="${INFILE/%-unsigned}"
+ OUTFILE="${INFILE/-unsigned}"
./osslsigncode attach-signature -in "${i}" -out "${OUTDIR}/${OUTFILE}" -sigin "${SIGDIR}/${INFILE}.pem"
done
diff --git a/depends/Makefile b/depends/Makefile
index 5b0b0d9688..f81bc3001b 100644
--- a/depends/Makefile
+++ b/depends/Makefile
@@ -9,6 +9,7 @@ WORK_PATH = $(BASEDIR)/work
BASE_CACHE ?= $(BASEDIR)/built
SDK_PATH ?= $(BASEDIR)/SDKs
NO_QT ?=
+NO_QR ?=
RAPIDCHECK ?=
NO_WALLET ?=
NO_ZMQ ?=
@@ -100,7 +101,10 @@ $(host_arch)_$(host_os)_id_string+=$(shell $(host_CXX) --version 2>/dev/null)
$(host_arch)_$(host_os)_id_string+=$(shell $(host_RANLIB) --version 2>/dev/null)
$(host_arch)_$(host_os)_id_string+=$(shell $(host_STRIP) --version 2>/dev/null)
-qt_packages_$(NO_QT) = $(qt_packages) $(qt_$(host_os)_packages) $(qt_$(host_arch)_$(host_os)_packages)
+qrencode_packages_$(NO_QR) = $(qrencode_packages)
+
+qt_packages_$(NO_QT) = $(qt_packages) $(qt_$(host_os)_packages) $(qt_$(host_arch)_$(host_os)_packages) $(qrencode_packages_)
+
wallet_packages_$(NO_WALLET) = $(wallet_packages)
upnp_packages_$(NO_UPNP) = $(upnp_packages)
zmq_packages_$(NO_ZMQ) = $(zmq_packages)
@@ -154,6 +158,7 @@ $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_
-e 's|@LDFLAGS@|$(strip $(host_LDFLAGS) $(host_$(release_type)_LDFLAGS))|' \
-e 's|@allow_host_packages@|$(ALLOW_HOST_PACKAGES)|' \
-e 's|@no_qt@|$(NO_QT)|' \
+ -e 's|@no_qr@|$(NO_QR)|' \
-e 's|@no_zmq@|$(NO_ZMQ)|' \
-e 's|@no_wallet@|$(NO_WALLET)|' \
-e 's|@no_upnp@|$(NO_UPNP)|' \
diff --git a/depends/README.md b/depends/README.md
index 0449d295fe..93f619983f 100644
--- a/depends/README.md
+++ b/depends/README.md
@@ -87,6 +87,7 @@ The following can be set when running make: make FOO=bar
SDK_PATH: Path where sdk's can be found (used by macOS)
FALLBACK_DOWNLOAD_PATH: If a source file can't be fetched, try here before giving up
NO_QT: Don't download/build/cache qt and its dependencies
+ NO_QR: Don't download/build/cache packages needed for enabling qrencode
NO_ZMQ: Don't download/build/cache packages needed for enabling zeromq
NO_WALLET: Don't download/build/cache libs needed to enable the wallet
NO_UPNP: Don't download/build/cache packages needed for enabling upnp
diff --git a/depends/config.site.in b/depends/config.site.in
index dee568bc25..c5731e5269 100644
--- a/depends/config.site.in
+++ b/depends/config.site.in
@@ -17,6 +17,10 @@ if test -z $with_qt_bindir && test -z "@no_qt@"; then
with_qt_bindir=$depends_prefix/native/bin
fi
+if test -z $with_qrencode && test -n "@no_qr@"; then
+ with_qrencode=no
+fi
+
if test -z $enable_wallet && test -n "@no_wallet@"; then
enable_wallet=no
fi
diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk
index 09f3187ac4..d8ccb208cc 100644
--- a/depends/packages/packages.mk
+++ b/depends/packages/packages.mk
@@ -1,6 +1,8 @@
packages:=boost libevent
-qt_packages = qrencode zlib
+qt_packages = zlib
+
+qrencode_packages = qrencode
qt_linux_packages:=qt expat libxcb xcb_proto libXau xproto freetype fontconfig
qt_android_packages=qt
diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk
index 4d45f55e2d..2087fec14d 100644
--- a/depends/packages/qt.mk
+++ b/depends/packages/qt.mk
@@ -105,6 +105,7 @@ $(package)_config_opts += -no-feature-wizard
$(package)_config_opts += -no-feature-xml
$(package)_config_opts_darwin = -no-dbus
+$(package)_config_opts_darwin += -no-opengl
ifneq ($(build_os),darwin)
$(package)_config_opts_darwin += -xplatform macx-clang-linux
diff --git a/doc/release-process.md b/doc/release-process.md
index 6d1e7c69e9..36d79a0c34 100644
--- a/doc/release-process.md
+++ b/doc/release-process.md
@@ -116,7 +116,7 @@ Ensure gitian-builder is up-to-date:
pushd ./gitian-builder
mkdir -p inputs
- wget -O osslsigncode-2.0.tar.gz -P inputs https://github.com/mtrojnar/osslsigncode/archive/2.0.tar.gz
+ wget -O inputs/osslsigncode-2.0.tar.gz https://github.com/mtrojnar/osslsigncode/archive/2.0.tar.gz
echo '5a60e0a4b3e0b4d655317b2f12a810211c50242138322b16e7e01c6fbb89d92f inputs/osslsigncode-2.0.tar.gz' | sha256sum -c
popd
diff --git a/src/Makefile.test.include b/src/Makefile.test.include
index b4ca01b1fe..6ae15cc553 100644
--- a/src/Makefile.test.include
+++ b/src/Makefile.test.include
@@ -4,11 +4,15 @@
FUZZ_TARGETS = \
+ test/fuzz/addr_info_deserialize \
test/fuzz/address_deserialize \
test/fuzz/addrman_deserialize \
test/fuzz/banentry_deserialize \
test/fuzz/bech32 \
test/fuzz/block_deserialize \
+ test/fuzz/block_file_info_deserialize \
+ test/fuzz/block_filter_deserialize \
+ test/fuzz/block_header_and_short_txids_deserialize \
test/fuzz/blockheader_deserialize \
test/fuzz/blocklocator_deserialize \
test/fuzz/blockmerkleroot \
@@ -20,16 +24,30 @@ FUZZ_TARGETS = \
test/fuzz/descriptor_parse \
test/fuzz/diskblockindex_deserialize \
test/fuzz/eval_script \
+ test/fuzz/fee_rate_deserialize \
+ test/fuzz/flat_file_pos_deserialize \
test/fuzz/inv_deserialize \
+ test/fuzz/key_origin_info_deserialize \
+ test/fuzz/merkle_block_deserialize \
test/fuzz/messageheader_deserialize \
test/fuzz/netaddr_deserialize \
+ test/fuzz/out_point_deserialize \
test/fuzz/parse_iso8601 \
+ test/fuzz/partial_merkle_tree_deserialize \
+ test/fuzz/partially_signed_transaction_deserialize \
+ test/fuzz/prefilled_transaction_deserialize \
test/fuzz/psbt \
+ test/fuzz/psbt_input_deserialize \
+ test/fuzz/psbt_output_deserialize \
+ test/fuzz/pub_key_deserialize \
test/fuzz/script \
+ test/fuzz/script_deserialize \
test/fuzz/script_flags \
test/fuzz/service_deserialize \
test/fuzz/spanparsing \
+ test/fuzz/sub_net_deserialize \
test/fuzz/transaction \
+ test/fuzz/tx_in_deserialize \
test/fuzz/txoutcompressor_deserialize \
test/fuzz/txundo_deserialize
@@ -371,6 +389,114 @@ test_fuzz_transaction_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
test_fuzz_transaction_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
test_fuzz_transaction_LDADD = $(FUZZ_SUITE_LD_COMMON)
+test_fuzz_addr_info_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp
+test_fuzz_addr_info_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DADDR_INFO_DESERIALIZE=1
+test_fuzz_addr_info_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
+test_fuzz_addr_info_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
+test_fuzz_addr_info_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
+
+test_fuzz_block_file_info_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp
+test_fuzz_block_file_info_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DBLOCK_FILE_INFO_DESERIALIZE=1
+test_fuzz_block_file_info_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
+test_fuzz_block_file_info_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
+test_fuzz_block_file_info_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
+
+test_fuzz_block_filter_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp
+test_fuzz_block_filter_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DBLOCK_FILTER_DESERIALIZE=1
+test_fuzz_block_filter_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
+test_fuzz_block_filter_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
+test_fuzz_block_filter_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
+
+test_fuzz_block_header_and_short_txids_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp
+test_fuzz_block_header_and_short_txids_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DBLOCK_HEADER_AND_SHORT_TXIDS_DESERIALIZE=1
+test_fuzz_block_header_and_short_txids_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
+test_fuzz_block_header_and_short_txids_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
+test_fuzz_block_header_and_short_txids_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
+
+test_fuzz_fee_rate_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp
+test_fuzz_fee_rate_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DFEE_RATE_DESERIALIZE=1
+test_fuzz_fee_rate_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
+test_fuzz_fee_rate_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
+test_fuzz_fee_rate_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
+
+test_fuzz_flat_file_pos_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp
+test_fuzz_flat_file_pos_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DFLAT_FILE_POS_DESERIALIZE=1
+test_fuzz_flat_file_pos_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
+test_fuzz_flat_file_pos_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
+test_fuzz_flat_file_pos_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
+
+test_fuzz_key_origin_info_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp
+test_fuzz_key_origin_info_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DKEY_ORIGIN_INFO_DESERIALIZE=1
+test_fuzz_key_origin_info_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
+test_fuzz_key_origin_info_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
+test_fuzz_key_origin_info_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
+
+test_fuzz_merkle_block_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp
+test_fuzz_merkle_block_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DMERKLE_BLOCK_DESERIALIZE=1
+test_fuzz_merkle_block_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
+test_fuzz_merkle_block_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
+test_fuzz_merkle_block_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
+
+test_fuzz_out_point_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp
+test_fuzz_out_point_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DOUT_POINT_DESERIALIZE=1
+test_fuzz_out_point_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
+test_fuzz_out_point_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
+test_fuzz_out_point_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
+
+test_fuzz_partially_signed_transaction_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp
+test_fuzz_partially_signed_transaction_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DPARTIALLY_SIGNED_TRANSACTION_DESERIALIZE=1
+test_fuzz_partially_signed_transaction_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
+test_fuzz_partially_signed_transaction_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
+test_fuzz_partially_signed_transaction_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
+
+test_fuzz_partial_merkle_tree_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp
+test_fuzz_partial_merkle_tree_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DPARTIAL_MERKLE_TREE_DESERIALIZE=1
+test_fuzz_partial_merkle_tree_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
+test_fuzz_partial_merkle_tree_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
+test_fuzz_partial_merkle_tree_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
+
+test_fuzz_prefilled_transaction_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp
+test_fuzz_prefilled_transaction_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DPREFILLED_TRANSACTION_DESERIALIZE=1
+test_fuzz_prefilled_transaction_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
+test_fuzz_prefilled_transaction_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
+test_fuzz_prefilled_transaction_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
+
+test_fuzz_psbt_input_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp
+test_fuzz_psbt_input_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DPSBT_INPUT_DESERIALIZE=1
+test_fuzz_psbt_input_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
+test_fuzz_psbt_input_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
+test_fuzz_psbt_input_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
+
+test_fuzz_psbt_output_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp
+test_fuzz_psbt_output_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DPSBT_OUTPUT_DESERIALIZE=1
+test_fuzz_psbt_output_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
+test_fuzz_psbt_output_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
+test_fuzz_psbt_output_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
+
+test_fuzz_pub_key_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp
+test_fuzz_pub_key_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DPUB_KEY_DESERIALIZE=1
+test_fuzz_pub_key_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
+test_fuzz_pub_key_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
+test_fuzz_pub_key_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
+
+test_fuzz_script_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp
+test_fuzz_script_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DSCRIPT_DESERIALIZE=1
+test_fuzz_script_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
+test_fuzz_script_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
+test_fuzz_script_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
+
+test_fuzz_sub_net_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp
+test_fuzz_sub_net_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DSUB_NET_DESERIALIZE=1
+test_fuzz_sub_net_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
+test_fuzz_sub_net_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
+test_fuzz_sub_net_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
+
+test_fuzz_tx_in_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp
+test_fuzz_tx_in_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DTX_IN_DESERIALIZE=1
+test_fuzz_tx_in_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
+test_fuzz_tx_in_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
+test_fuzz_tx_in_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
+
endif # ENABLE_FUZZ
nodist_test_test_bitcoin_SOURCES = $(GENERATED_TEST_FILES)
diff --git a/src/pubkey.cpp b/src/pubkey.cpp
index 10953adc35..21e51a380d 100644
--- a/src/pubkey.cpp
+++ b/src/pubkey.cpp
@@ -171,6 +171,7 @@ bool CPubKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchS
return false;
secp256k1_pubkey pubkey;
secp256k1_ecdsa_signature sig;
+ assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, vch, size())) {
return false;
}
@@ -190,6 +191,7 @@ bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector<unsigned cha
bool fComp = ((vchSig[0] - 27) & 4) != 0;
secp256k1_pubkey pubkey;
secp256k1_ecdsa_recoverable_signature sig;
+ assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
if (!secp256k1_ecdsa_recoverable_signature_parse_compact(secp256k1_context_verify, &sig, &vchSig[1], recid)) {
return false;
}
@@ -207,6 +209,7 @@ bool CPubKey::IsFullyValid() const {
if (!IsValid())
return false;
secp256k1_pubkey pubkey;
+ assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
return secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, vch, size());
}
@@ -214,6 +217,7 @@ bool CPubKey::Decompress() {
if (!IsValid())
return false;
secp256k1_pubkey pubkey;
+ assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, vch, size())) {
return false;
}
@@ -232,6 +236,7 @@ bool CPubKey::Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChi
BIP32Hash(cc, nChild, *begin(), begin()+1, out);
memcpy(ccChild.begin(), out+32, 32);
secp256k1_pubkey pubkey;
+ assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, vch, size())) {
return false;
}
@@ -273,6 +278,7 @@ bool CExtPubKey::Derive(CExtPubKey &out, unsigned int _nChild) const {
/* static */ bool CPubKey::CheckLowS(const std::vector<unsigned char>& vchSig) {
secp256k1_ecdsa_signature sig;
+ assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
if (!ecdsa_signature_parse_der_lax(secp256k1_context_verify, &sig, vchSig.data(), vchSig.size())) {
return false;
}
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 2aeba6d82c..8444984b27 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -341,6 +341,7 @@ void BitcoinGUI::createActions()
m_close_wallet_action->setStatusTip(tr("Close wallet"));
m_create_wallet_action = new QAction(tr("Create Wallet..."), this);
+ m_create_wallet_action->setEnabled(false);
m_create_wallet_action->setStatusTip(tr("Create a new wallet"));
showHelpMessageAction = new QAction(tr("&Command-line options"), this);
@@ -618,6 +619,7 @@ void BitcoinGUI::setWalletController(WalletController* wallet_controller)
m_wallet_controller = wallet_controller;
+ m_create_wallet_action->setEnabled(true);
m_open_wallet_action->setEnabled(true);
m_open_wallet_action->setMenu(m_open_wallet_menu);
diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp
index d48c537c75..0f5ba08a5b 100644
--- a/src/qt/optionsdialog.cpp
+++ b/src/qt/optionsdialog.cpp
@@ -77,9 +77,11 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) :
ui->verticalLayout_Main->removeItem(ui->horizontalSpacer_0_Main);
#endif
- /* remove Wallet tab in case of -disablewallet */
+ /* remove Wallet tab and 3rd party-URL textbox in case of -disablewallet */
if (!enableWallet) {
ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tabWallet));
+ ui->thirdPartyTxUrlsLabel->setVisible(false);
+ ui->thirdPartyTxUrls->setVisible(false);
}
/* Display elements init */
diff --git a/src/random.cpp b/src/random.cpp
index fd1dfe506f..99927fc5d2 100644
--- a/src/random.cpp
+++ b/src/random.cpp
@@ -360,6 +360,9 @@ class RNGState {
uint64_t m_counter GUARDED_BY(m_mutex) = 0;
bool m_strongly_seeded GUARDED_BY(m_mutex) = false;
+ Mutex m_events_mutex;
+ CSHA256 m_events_hasher GUARDED_BY(m_events_mutex);
+
public:
RNGState() noexcept
{
@@ -370,6 +373,35 @@ public:
{
}
+ void AddEvent(uint32_t event_info) noexcept
+ {
+ LOCK(m_events_mutex);
+
+ m_events_hasher.Write((const unsigned char *)&event_info, sizeof(event_info));
+ // Get the low four bytes of the performance counter. This translates to roughly the
+ // subsecond part.
+ uint32_t perfcounter = (GetPerformanceCounter() & 0xffffffff);
+ m_events_hasher.Write((const unsigned char*)&perfcounter, sizeof(perfcounter));
+ }
+
+ /**
+ * Feed (the hash of) all events added through AddEvent() to hasher.
+ */
+ void SeedEvents(CSHA512& hasher) noexcept
+ {
+ // We use only SHA256 for the events hashing to get the ASM speedups we have for SHA256,
+ // since we want it to be fast as network peers may be able to trigger it repeatedly.
+ LOCK(m_events_mutex);
+
+ unsigned char events_hash[32];
+ m_events_hasher.Finalize(events_hash);
+ hasher.Write(events_hash, 32);
+
+ // Re-initialize the hasher with the finalized state to use later.
+ m_events_hasher.Reset();
+ m_events_hasher.Write(events_hash, 32);
+ }
+
/** Extract up to 32 bytes of entropy from the RNG state, mixing in new entropy from hasher.
*
* If this function has never been called with strong_seed = true, false is returned.
@@ -440,24 +472,7 @@ static void SeedFast(CSHA512& hasher) noexcept
SeedTimestamp(hasher);
}
-// We use only SHA256 for the events hashing to get the ASM speedups we have for SHA256,
-// since we want it to be fast as network peers may be able to trigger it repeatedly.
-static Mutex events_mutex;
-static CSHA256 events_hasher;
-static void SeedEvents(CSHA512& hasher)
-{
- LOCK(events_mutex);
-
- unsigned char events_hash[32];
- events_hasher.Finalize(events_hash);
- hasher.Write(events_hash, 32);
-
- // Re-initialize the hasher with the finalized state to use later.
- events_hasher.Reset();
- events_hasher.Write(events_hash, 32);
-}
-
-static void SeedSlow(CSHA512& hasher) noexcept
+static void SeedSlow(CSHA512& hasher, RNGState& rng) noexcept
{
unsigned char buffer[32];
@@ -469,7 +484,7 @@ static void SeedSlow(CSHA512& hasher) noexcept
hasher.Write(buffer, sizeof(buffer));
// Add the events hasher into the mix
- SeedEvents(hasher);
+ rng.SeedEvents(hasher);
// High-precision timestamp.
//
@@ -497,12 +512,12 @@ static void SeedPeriodic(CSHA512& hasher, RNGState& rng) noexcept
SeedTimestamp(hasher);
// Add the events hasher into the mix
- SeedEvents(hasher);
+ rng.SeedEvents(hasher);
// Dynamic environment data (performance monitoring, ...)
auto old_size = hasher.Size();
RandAddDynamicEnv(hasher);
- LogPrintf("Feeding %i bytes of dynamic environment data into RNG\n", hasher.Size() - old_size);
+ LogPrint(BCLog::RAND, "Feeding %i bytes of dynamic environment data into RNG\n", hasher.Size() - old_size);
// Strengthen for 10 ms
SeedStrengthen(hasher, rng, 10000);
@@ -514,7 +529,7 @@ static void SeedStartup(CSHA512& hasher, RNGState& rng) noexcept
SeedHardwareSlow(hasher);
// Everything that the 'slow' seeder includes.
- SeedSlow(hasher);
+ SeedSlow(hasher, rng);
// Dynamic environment data (performance monitoring, ...)
auto old_size = hasher.Size();
@@ -522,7 +537,7 @@ static void SeedStartup(CSHA512& hasher, RNGState& rng) noexcept
// Static environment data
RandAddStaticEnv(hasher);
- LogPrintf("Feeding %i bytes of environment data into RNG\n", hasher.Size() - old_size);
+ LogPrint(BCLog::RAND, "Feeding %i bytes of environment data into RNG\n", hasher.Size() - old_size);
// Strengthen for 100 ms
SeedStrengthen(hasher, rng, 100000);
@@ -534,7 +549,7 @@ enum class RNGLevel {
PERIODIC, //!< Called by RandAddPeriodic()
};
-static void ProcRand(unsigned char* out, int num, RNGLevel level)
+static void ProcRand(unsigned char* out, int num, RNGLevel level) noexcept
{
// Make sure the RNG is initialized first (as all Seed* function possibly need hwrand to be available).
RNGState& rng = GetRNGState();
@@ -547,7 +562,7 @@ static void ProcRand(unsigned char* out, int num, RNGLevel level)
SeedFast(hasher);
break;
case RNGLevel::SLOW:
- SeedSlow(hasher);
+ SeedSlow(hasher, rng);
break;
case RNGLevel::PERIODIC:
SeedPeriodic(hasher, rng);
@@ -566,15 +581,7 @@ static void ProcRand(unsigned char* out, int num, RNGLevel level)
void GetRandBytes(unsigned char* buf, int num) noexcept { ProcRand(buf, num, RNGLevel::FAST); }
void GetStrongRandBytes(unsigned char* buf, int num) noexcept { ProcRand(buf, num, RNGLevel::SLOW); }
void RandAddPeriodic() noexcept { ProcRand(nullptr, 0, RNGLevel::PERIODIC); }
-
-void RandAddEvent(const uint32_t event_info) {
- LOCK(events_mutex);
- events_hasher.Write((const unsigned char *)&event_info, sizeof(event_info));
- // Get the low four bytes of the performance counter. This translates to roughly the
- // subsecond part.
- uint32_t perfcounter = (GetPerformanceCounter() & 0xffffffff);
- events_hasher.Write((const unsigned char*)&perfcounter, sizeof(perfcounter));
-}
+void RandAddEvent(const uint32_t event_info) noexcept { GetRNGState().AddEvent(event_info); }
bool g_mock_deterministic_tests{false};
diff --git a/src/random.h b/src/random.h
index 82dd6ecf9f..e1b105168d 100644
--- a/src/random.h
+++ b/src/random.h
@@ -95,7 +95,7 @@ void RandAddPeriodic() noexcept;
*
* Thread-safe.
*/
-void RandAddEvent(const uint32_t event_info);
+void RandAddEvent(const uint32_t event_info) noexcept;
/**
* Fast randomness source. This is seeded once with secure random data, but
diff --git a/src/test/fuzz/descriptor_parse.cpp b/src/test/fuzz/descriptor_parse.cpp
index c4c25854fd..47d5038c26 100644
--- a/src/test/fuzz/descriptor_parse.cpp
+++ b/src/test/fuzz/descriptor_parse.cpp
@@ -3,11 +3,14 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <chainparams.h>
+#include <pubkey.h>
#include <script/descriptor.h>
#include <test/fuzz/fuzz.h>
+#include <util/memory.h>
void initialize()
{
+ static const auto verify_handle = MakeUnique<ECCVerifyHandle>();
SelectParams(CBaseChainParams::REGTEST);
}
diff --git a/src/test/fuzz/deserialize.cpp b/src/test/fuzz/deserialize.cpp
index bcd8691359..46bc38fdab 100644
--- a/src/test/fuzz/deserialize.cpp
+++ b/src/test/fuzz/deserialize.cpp
@@ -5,18 +5,24 @@
#include <addrdb.h>
#include <addrman.h>
#include <blockencodings.h>
+#include <blockfilter.h>
#include <chain.h>
#include <coins.h>
#include <compressor.h>
#include <consensus/merkle.h>
+#include <key.h>
+#include <merkleblock.h>
#include <net.h>
#include <primitives/block.h>
#include <protocol.h>
+#include <psbt.h>
#include <pubkey.h>
+#include <script/keyorigin.h>
#include <streams.h>
#include <undo.h>
#include <version.h>
+#include <stdexcept>
#include <stdint.h>
#include <unistd.h>
@@ -37,129 +43,237 @@ void test_one_input(const std::vector<uint8_t>& buffer)
int nVersion;
ds >> nVersion;
ds.SetVersion(nVersion);
- } catch (const std::ios_base::failure& e) {
+ } catch (const std::ios_base::failure&) {
return;
}
-#if BLOCK_DESERIALIZE
- try
- {
- CBlock block;
- ds >> block;
- } catch (const std::ios_base::failure& e) {return;}
+#if BLOCK_FILTER_DESERIALIZE
+ try {
+ BlockFilter block_filter;
+ ds >> block_filter;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif ADDR_INFO_DESERIALIZE
+ try {
+ CAddrInfo addr_info;
+ ds >> addr_info;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif BLOCK_FILE_INFO_DESERIALIZE
+ try {
+ CBlockFileInfo block_file_info;
+ ds >> block_file_info;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif BLOCK_HEADER_AND_SHORT_TXIDS_DESERIALIZE
+ try {
+ CBlockHeaderAndShortTxIDs block_header_and_short_txids;
+ ds >> block_header_and_short_txids;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif FEE_RATE_DESERIALIZE
+ try {
+ CFeeRate fee_rate;
+ ds >> fee_rate;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif MERKLE_BLOCK_DESERIALIZE
+ try {
+ CMerkleBlock merkle_block;
+ ds >> merkle_block;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif OUT_POINT_DESERIALIZE
+ try {
+ COutPoint out_point;
+ ds >> out_point;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif PARTIAL_MERKLE_TREE_DESERIALIZE
+ try {
+ CPartialMerkleTree partial_merkle_tree;
+ ds >> partial_merkle_tree;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif PUB_KEY_DESERIALIZE
+ try {
+ CPubKey pub_key;
+ ds >> pub_key;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif SCRIPT_DESERIALIZE
+ try {
+ CScript script;
+ ds >> script;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif SUB_NET_DESERIALIZE
+ try {
+ CSubNet sub_net;
+ ds >> sub_net;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif TX_IN_DESERIALIZE
+ try {
+ CTxIn tx_in;
+ ds >> tx_in;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif FLAT_FILE_POS_DESERIALIZE
+ try {
+ FlatFilePos flat_file_pos;
+ ds >> flat_file_pos;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif KEY_ORIGIN_INFO_DESERIALIZE
+ try {
+ KeyOriginInfo key_origin_info;
+ ds >> key_origin_info;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif PARTIALLY_SIGNED_TRANSACTION_DESERIALIZE
+ try {
+ PartiallySignedTransaction partially_signed_transaction;
+ ds >> partially_signed_transaction;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif PREFILLED_TRANSACTION_DESERIALIZE
+ try {
+ PrefilledTransaction prefilled_transaction;
+ ds >> prefilled_transaction;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif PSBT_INPUT_DESERIALIZE
+ try {
+ PSBTInput psbt_input;
+ ds >> psbt_input;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif PSBT_OUTPUT_DESERIALIZE
+ try {
+ PSBTOutput psbt_output;
+ ds >> psbt_output;
+ } catch (const std::ios_base::failure&) {
+ }
+#elif BLOCK_DESERIALIZE
+ try {
+ CBlock block;
+ ds >> block;
+ } catch (const std::ios_base::failure&) {
+ }
#elif BLOCKLOCATOR_DESERIALIZE
- try
- {
- CBlockLocator bl;
- ds >> bl;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CBlockLocator bl;
+ ds >> bl;
+ } catch (const std::ios_base::failure&) {
+ }
#elif BLOCKMERKLEROOT
- try
- {
- CBlock block;
- ds >> block;
- bool mutated;
- BlockMerkleRoot(block, &mutated);
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CBlock block;
+ ds >> block;
+ bool mutated;
+ BlockMerkleRoot(block, &mutated);
+ } catch (const std::ios_base::failure&) {
+ }
#elif ADDRMAN_DESERIALIZE
- try
- {
- CAddrMan am;
- ds >> am;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CAddrMan am;
+ ds >> am;
+ } catch (const std::ios_base::failure&) {
+ }
#elif BLOCKHEADER_DESERIALIZE
- try
- {
- CBlockHeader bh;
- ds >> bh;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CBlockHeader bh;
+ ds >> bh;
+ } catch (const std::ios_base::failure&) {
+ }
#elif BANENTRY_DESERIALIZE
- try
- {
- CBanEntry be;
- ds >> be;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CBanEntry be;
+ ds >> be;
+ } catch (const std::ios_base::failure&) {
+ }
#elif TXUNDO_DESERIALIZE
- try
- {
- CTxUndo tu;
- ds >> tu;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CTxUndo tu;
+ ds >> tu;
+ } catch (const std::ios_base::failure&) {
+ }
#elif BLOCKUNDO_DESERIALIZE
- try
- {
- CBlockUndo bu;
- ds >> bu;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CBlockUndo bu;
+ ds >> bu;
+ } catch (const std::ios_base::failure&) {
+ }
#elif COINS_DESERIALIZE
- try
- {
- Coin coin;
- ds >> coin;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ Coin coin;
+ ds >> coin;
+ } catch (const std::ios_base::failure&) {
+ }
#elif NETADDR_DESERIALIZE
- try
- {
- CNetAddr na;
- ds >> na;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CNetAddr na;
+ ds >> na;
+ } catch (const std::ios_base::failure&) {
+ }
#elif SERVICE_DESERIALIZE
- try
- {
- CService s;
- ds >> s;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CService s;
+ ds >> s;
+ } catch (const std::ios_base::failure&) {
+ }
#elif MESSAGEHEADER_DESERIALIZE
- CMessageHeader::MessageStartChars pchMessageStart = {0x00, 0x00, 0x00, 0x00};
- try
- {
- CMessageHeader mh(pchMessageStart);
- ds >> mh;
- if (!mh.IsValid(pchMessageStart)) {return;}
- } catch (const std::ios_base::failure& e) {return;}
+ CMessageHeader::MessageStartChars pchMessageStart = {0x00, 0x00, 0x00, 0x00};
+ try {
+ CMessageHeader mh(pchMessageStart);
+ ds >> mh;
+ (void)mh.IsValid(pchMessageStart);
+ } catch (const std::ios_base::failure&) {
+ }
#elif ADDRESS_DESERIALIZE
- try
- {
- CAddress a;
- ds >> a;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CAddress a;
+ ds >> a;
+ } catch (const std::ios_base::failure&) {
+ }
#elif INV_DESERIALIZE
- try
- {
- CInv i;
- ds >> i;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CInv i;
+ ds >> i;
+ } catch (const std::ios_base::failure&) {
+ }
#elif BLOOMFILTER_DESERIALIZE
- try
- {
- CBloomFilter bf;
- ds >> bf;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CBloomFilter bf;
+ ds >> bf;
+ } catch (const std::ios_base::failure&) {
+ }
#elif DISKBLOCKINDEX_DESERIALIZE
- try
- {
- CDiskBlockIndex dbi;
- ds >> dbi;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ CDiskBlockIndex dbi;
+ ds >> dbi;
+ } catch (const std::ios_base::failure&) {
+ }
#elif TXOUTCOMPRESSOR_DESERIALIZE
- CTxOut to;
- CTxOutCompressor toc(to);
- try
- {
- ds >> toc;
- } catch (const std::ios_base::failure& e) {return;}
+ CTxOut to;
+ CTxOutCompressor toc(to);
+ try {
+ ds >> toc;
+ } catch (const std::ios_base::failure&) {
+ }
#elif BLOCKTRANSACTIONS_DESERIALIZE
- try
- {
- BlockTransactions bt;
- ds >> bt;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ BlockTransactions bt;
+ ds >> bt;
+ } catch (const std::ios_base::failure&) {
+ }
#elif BLOCKTRANSACTIONSREQUEST_DESERIALIZE
- try
- {
- BlockTransactionsRequest btr;
- ds >> btr;
- } catch (const std::ios_base::failure& e) {return;}
+ try {
+ BlockTransactionsRequest btr;
+ ds >> btr;
+ } catch (const std::ios_base::failure&) {
+ }
#else
#error Need at least one fuzz target to compile
#endif
diff --git a/src/test/fuzz/transaction.cpp b/src/test/fuzz/transaction.cpp
index 76b230ef3c..fefafda36b 100644
--- a/src/test/fuzz/transaction.cpp
+++ b/src/test/fuzz/transaction.cpp
@@ -26,19 +26,31 @@ void test_one_input(const std::vector<uint8_t>& buffer)
int nVersion;
ds >> nVersion;
ds.SetVersion(nVersion);
- } catch (const std::ios_base::failure& e) {
+ } catch (const std::ios_base::failure&) {
return;
}
- bool valid = true;
+ bool valid_tx = true;
const CTransaction tx = [&] {
try {
return CTransaction(deserialize, ds);
- } catch (const std::ios_base::failure& e) {
- valid = false;
+ } catch (const std::ios_base::failure&) {
+ valid_tx = false;
return CTransaction();
}
}();
- if (!valid) {
+ bool valid_mutable_tx = true;
+ CDataStream ds_mtx(buffer, SER_NETWORK, INIT_PROTO_VERSION);
+ CMutableTransaction mutable_tx;
+ try {
+ int nVersion;
+ ds_mtx >> nVersion;
+ ds_mtx.SetVersion(nVersion);
+ ds_mtx >> mutable_tx;
+ } catch (const std::ios_base::failure&) {
+ valid_mutable_tx = false;
+ }
+ assert(valid_tx == valid_mutable_tx);
+ if (!valid_tx) {
return;
}
diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp
index 3eaaf3786c..2b9e8fbf2a 100644
--- a/src/wallet/scriptpubkeyman.cpp
+++ b/src/wallet/scriptpubkeyman.cpp
@@ -18,7 +18,7 @@ bool LegacyScriptPubKeyMan::GetNewDestination(const OutputType type, CTxDestinat
// Generate a new key that is added to wallet
CPubKey new_key;
- if (!GetKeyFromPool(new_key)) {
+ if (!GetKeyFromPool(new_key, type)) {
error = "Error: Keypool ran out, please call keypoolrefill first";
return false;
}
@@ -262,24 +262,19 @@ bool LegacyScriptPubKeyMan::EncryptKeys(CKeyingMaterial& vMasterKeyIn)
return true;
}
-bool LegacyScriptPubKeyMan::GetReservedDestination(const OutputType type, bool internal, int64_t& index, CKeyPool& keypool)
+bool LegacyScriptPubKeyMan::GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool)
{
+ if (!CanGetAddresses(internal)) {
+ return false;
+ }
+
if (!ReserveKeyFromKeyPool(index, keypool, internal)) {
return false;
}
+ address = GetDestinationForKey(keypool.vchPubKey, type);
return true;
}
-void LegacyScriptPubKeyMan::KeepDestination(int64_t index)
-{
- KeepKey(index);
-}
-
-void LegacyScriptPubKeyMan::ReturnDestination(int64_t index, bool internal, const CPubKey& pubkey)
-{
- ReturnKey(index, internal, pubkey);
-}
-
void LegacyScriptPubKeyMan::MarkUnusedAddresses(const CScript& script)
{
AssertLockHeld(cs_wallet);
@@ -460,7 +455,7 @@ size_t LegacyScriptPubKeyMan::KeypoolCountExternalKeys()
unsigned int LegacyScriptPubKeyMan::GetKeyPoolSize() const
{
AssertLockHeld(cs_wallet);
- return setInternalKeyPool.size() + setExternalKeyPool.size();
+ return setInternalKeyPool.size() + setExternalKeyPool.size() + set_pre_split_keypool.size();
}
int64_t LegacyScriptPubKeyMan::GetTimeFirstKey() const
@@ -1092,15 +1087,20 @@ void LegacyScriptPubKeyMan::AddKeypoolPubkeyWithDB(const CPubKey& pubkey, const
m_pool_key_to_index[pubkey.GetID()] = index;
}
-void LegacyScriptPubKeyMan::KeepKey(int64_t nIndex)
+void LegacyScriptPubKeyMan::KeepDestination(int64_t nIndex, const OutputType& type)
{
// Remove from key pool
WalletBatch batch(m_storage.GetDatabase());
batch.ErasePool(nIndex);
+ CPubKey pubkey;
+ bool have_pk = GetPubKey(m_index_to_reserved_key.at(nIndex), pubkey);
+ assert(have_pk);
+ LearnRelatedScripts(pubkey, type);
+ m_index_to_reserved_key.erase(nIndex);
WalletLogPrintf("keypool keep %d\n", nIndex);
}
-void LegacyScriptPubKeyMan::ReturnKey(int64_t nIndex, bool fInternal, const CPubKey& pubkey)
+void LegacyScriptPubKeyMan::ReturnDestination(int64_t nIndex, bool fInternal, const CTxDestination&)
{
// Return to key pool
{
@@ -1112,13 +1112,15 @@ void LegacyScriptPubKeyMan::ReturnKey(int64_t nIndex, bool fInternal, const CPub
} else {
setExternalKeyPool.insert(nIndex);
}
- m_pool_key_to_index[pubkey.GetID()] = nIndex;
+ CKeyID& pubkey_id = m_index_to_reserved_key.at(nIndex);
+ m_pool_key_to_index[pubkey_id] = nIndex;
+ m_index_to_reserved_key.erase(nIndex);
NotifyCanGetAddressesChanged();
}
WalletLogPrintf("keypool return %d\n", nIndex);
}
-bool LegacyScriptPubKeyMan::GetKeyFromPool(CPubKey& result, bool internal)
+bool LegacyScriptPubKeyMan::GetKeyFromPool(CPubKey& result, const OutputType type, bool internal)
{
if (!CanGetAddresses(internal)) {
return false;
@@ -1134,7 +1136,7 @@ bool LegacyScriptPubKeyMan::GetKeyFromPool(CPubKey& result, bool internal)
result = GenerateNewKey(batch, internal);
return true;
}
- KeepKey(nIndex);
+ KeepDestination(nIndex, type);
result = keypool.vchPubKey;
}
return true;
@@ -1179,6 +1181,8 @@ bool LegacyScriptPubKeyMan::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& key
throw std::runtime_error(std::string(__func__) + ": keypool entry invalid");
}
+ assert(m_index_to_reserved_key.count(nIndex) == 0);
+ m_index_to_reserved_key[nIndex] = keypool.vchPubKey.GetID();
m_pool_key_to_index.erase(keypool.vchPubKey.GetID());
WalletLogPrintf("keypool reserve %d\n", nIndex);
}
diff --git a/src/wallet/scriptpubkeyman.h b/src/wallet/scriptpubkeyman.h
index 4f17156792..6ed9a4787a 100644
--- a/src/wallet/scriptpubkeyman.h
+++ b/src/wallet/scriptpubkeyman.h
@@ -150,9 +150,9 @@ public:
virtual bool GetNewDestination(const OutputType type, CTxDestination& dest, std::string& error) { return false; }
virtual isminetype IsMine(const CScript& script) const { return ISMINE_NO; }
- virtual bool GetReservedDestination(const OutputType type, bool internal, int64_t& index, CKeyPool& keypool) { return false; }
- virtual void KeepDestination(int64_t index) {}
- virtual void ReturnDestination(int64_t index, bool internal, const CPubKey& pubkey) {}
+ virtual bool GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool) { return false; }
+ virtual void KeepDestination(int64_t index, const OutputType& type) {}
+ virtual void ReturnDestination(int64_t index, bool internal, const CTxDestination& addr) {}
virtual bool TopUp(unsigned int size = 0) { return false; }
@@ -246,9 +246,11 @@ private:
std::set<int64_t> set_pre_split_keypool GUARDED_BY(cs_wallet);
int64_t m_max_keypool_index GUARDED_BY(cs_wallet) = 0;
std::map<CKeyID, int64_t> m_pool_key_to_index;
+ // Tracks keypool indexes to CKeyIDs of keys that have been taken out of the keypool but may be returned to it
+ std::map<int64_t, CKeyID> m_index_to_reserved_key;
//! Fetches a key from the keypool
- bool GetKeyFromPool(CPubKey &key, bool internal = false);
+ bool GetKeyFromPool(CPubKey &key, const OutputType type, bool internal = false);
/**
* Reserves a key from the keypool and sets nIndex to its index
@@ -266,9 +268,6 @@ private:
*/
bool ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool fRequestedInternal);
- void KeepKey(int64_t nIndex);
- void ReturnKey(int64_t nIndex, bool fInternal, const CPubKey& pubkey);
-
public:
bool GetNewDestination(const OutputType type, CTxDestination& dest, std::string& error) override;
isminetype IsMine(const CScript& script) const override;
@@ -276,9 +275,9 @@ public:
//! will encrypt previously unencrypted keys
bool EncryptKeys(CKeyingMaterial& vMasterKeyIn);
- bool GetReservedDestination(const OutputType type, bool internal, int64_t& index, CKeyPool& keypool) override;
- void KeepDestination(int64_t index) override;
- void ReturnDestination(int64_t index, bool internal, const CPubKey& pubkey) override;
+ bool GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool) override;
+ void KeepDestination(int64_t index, const OutputType& type) override;
+ void ReturnDestination(int64_t index, bool internal, const CTxDestination&) override;
bool TopUp(unsigned int size = 0) override;
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 0a8ce7caf1..abee497c1d 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -3295,21 +3295,15 @@ bool ReserveDestination::GetReservedDestination(CTxDestination& dest, bool inter
return false;
}
- if (!pwallet->CanGetAddresses(internal)) {
- return false;
- }
if (nIndex == -1)
{
CKeyPool keypool;
- if (!m_spk_man->GetReservedDestination(type, internal, nIndex, keypool)) {
+ if (!m_spk_man->GetReservedDestination(type, internal, address, nIndex, keypool)) {
return false;
}
- vchPubKey = keypool.vchPubKey;
fInternal = keypool.fInternal;
}
- assert(vchPubKey.IsValid());
- address = GetDestinationForKey(vchPubKey, type);
dest = address;
return true;
}
@@ -3317,21 +3311,18 @@ bool ReserveDestination::GetReservedDestination(CTxDestination& dest, bool inter
void ReserveDestination::KeepDestination()
{
if (nIndex != -1) {
- m_spk_man->KeepDestination(nIndex);
- m_spk_man->LearnRelatedScripts(vchPubKey, type);
+ m_spk_man->KeepDestination(nIndex, type);
}
nIndex = -1;
- vchPubKey = CPubKey();
address = CNoDestination();
}
void ReserveDestination::ReturnDestination()
{
if (nIndex != -1) {
- m_spk_man->ReturnDestination(nIndex, fInternal, vchPubKey);
+ m_spk_man->ReturnDestination(nIndex, fInternal, address);
}
nIndex = -1;
- vchPubKey = CPubKey();
address = CNoDestination();
}
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index 51df4a9a8b..b02e092f0a 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -139,12 +139,11 @@ class ReserveDestination
protected:
//! The wallet to reserve from
CWallet* const pwallet;
- LegacyScriptPubKeyMan* m_spk_man{nullptr};
+ //! The ScriptPubKeyMan to reserve from. Based on type when GetReservedDestination is called
+ ScriptPubKeyMan* m_spk_man{nullptr};
OutputType const type;
//! The index of the address's key in the keypool
int64_t nIndex{-1};
- //! The public key for the address
- CPubKey vchPubKey;
//! The destination
CTxDestination address;
//! Whether this is from the internal (change output) keypool
diff --git a/test/functional/wallet_abandonconflict.py b/test/functional/wallet_abandonconflict.py
index e86679bc31..1122daaf83 100755
--- a/test/functional/wallet_abandonconflict.py
+++ b/test/functional/wallet_abandonconflict.py
@@ -18,6 +18,7 @@ from test_framework.util import (
assert_raises_rpc_error,
connect_nodes,
disconnect_nodes,
+ wait_until,
)
@@ -97,6 +98,7 @@ class AbandonConflictTest(BitcoinTestFramework):
# TODO: redo with eviction
self.stop_node(0)
self.start_node(0, extra_args=["-minrelaytxfee=0.0001"])
+ wait_until(lambda: self.nodes[0].getmempoolinfo()['loaded'])
# Verify txs no longer in either node's mempool
assert_equal(len(self.nodes[0].getrawmempool()), 0)
@@ -124,6 +126,8 @@ class AbandonConflictTest(BitcoinTestFramework):
# Verify that even with a low min relay fee, the tx is not reaccepted from wallet on startup once abandoned
self.stop_node(0)
self.start_node(0, extra_args=["-minrelaytxfee=0.00001"])
+ wait_until(lambda: self.nodes[0].getmempoolinfo()['loaded'])
+
assert_equal(len(self.nodes[0].getrawmempool()), 0)
assert_equal(self.nodes[0].getbalance(), balance)
@@ -144,6 +148,7 @@ class AbandonConflictTest(BitcoinTestFramework):
# Remove using high relay fee again
self.stop_node(0)
self.start_node(0, extra_args=["-minrelaytxfee=0.0001"])
+ wait_until(lambda: self.nodes[0].getmempoolinfo()['loaded'])
assert_equal(len(self.nodes[0].getrawmempool()), 0)
newbalance = self.nodes[0].getbalance()
assert_equal(newbalance, balance - Decimal("24.9996"))
diff --git a/test/fuzz/test_runner.py b/test/fuzz/test_runner.py
index fde99fe496..ffebb579e7 100755
--- a/test/fuzz/test_runner.py
+++ b/test/fuzz/test_runner.py
@@ -12,6 +12,27 @@ import sys
import subprocess
import logging
+# Fuzzers known to lack a seed corpus in https://github.com/bitcoin-core/qa-assets/tree/master/fuzz_seed_corpus
+FUZZERS_MISSING_CORPORA = [
+ "addr_info_deserialize",
+ "block_file_info_deserialize",
+ "block_filter_deserialize",
+ "block_header_and_short_txids_deserialize",
+ "fee_rate_deserialize",
+ "flat_file_pos_deserialize",
+ "key_origin_info_deserialize",
+ "merkle_block_deserialize",
+ "out_point_deserialize",
+ "partial_merkle_tree_deserialize",
+ "partially_signed_transaction_deserialize",
+ "prefilled_transaction_deserialize",
+ "psbt_input_deserialize",
+ "psbt_output_deserialize",
+ "pub_key_deserialize",
+ "script_deserialize",
+ "sub_net_deserialize",
+ "tx_in_deserialize",
+]
def main():
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
@@ -100,10 +121,14 @@ def main():
def run_once(*, corpus, test_list, build_dir, export_coverage):
for t in test_list:
+ corpus_path = os.path.join(corpus, t)
+ if t in FUZZERS_MISSING_CORPORA:
+ os.makedirs(corpus_path, exist_ok=True)
args = [
os.path.join(build_dir, 'src', 'test', 'fuzz', t),
'-runs=1',
- os.path.join(corpus, t),
+ '-detect_leaks=0',
+ corpus_path,
]
logging.debug('Run {} with args {}'.format(t, args))
result = subprocess.run(args, stderr=subprocess.PIPE, universal_newlines=True)