aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml8
-rw-r--r--ci/test/00_setup_env_native_valgrind.sh15
-rw-r--r--ci/test/00_setup_env_s390x.sh8
-rwxr-xr-xci/test/04_install.sh2
-rwxr-xr-xci/test/06_script_b.sh7
-rwxr-xr-xci/test/wrap-valgrind.sh18
-rw-r--r--contrib/valgrind.supp80
-rw-r--r--src/Makefile.bench.include4
-rw-r--r--src/Makefile.test.include14
-rw-r--r--src/Makefile.test_util.include7
-rw-r--r--src/bench/block_assemble.cpp3
-rw-r--r--src/bench/wallet_balance.cpp3
-rw-r--r--src/interfaces/chain.cpp2
-rw-r--r--src/interfaces/node.cpp6
-rw-r--r--src/interfaces/node.h2
-rw-r--r--src/netaddress.h2
-rw-r--r--src/node/coin.cpp8
-rw-r--r--src/node/coin.h4
-rw-r--r--src/node/transaction.cpp5
-rw-r--r--src/qt/bitcoin.cpp6
-rw-r--r--src/qt/clientmodel.cpp2
-rw-r--r--src/qt/test/wallettests.cpp1
-rw-r--r--src/rest.cpp39
-rw-r--r--src/rpc/blockchain.cpp22
-rw-r--r--src/rpc/mining.cpp8
-rw-r--r--src/rpc/net.cpp2
-rw-r--r--src/rpc/rawtransaction.cpp5
-rw-r--r--src/test/fuzz/base_encode_decode.cpp47
-rw-r--r--src/test/fuzz/hex.cpp22
-rw-r--r--src/test/netbase_tests.cpp2
-rw-r--r--src/test/rpc_tests.cpp4
-rw-r--r--src/test/settings_tests.cpp3
-rw-r--r--src/test/timedata_tests.cpp2
-rw-r--r--src/test/util.h70
-rw-r--r--src/test/util/mining.cpp (renamed from src/test/util.cpp)35
-rw-r--r--src/test/util/mining.h24
-rw-r--r--src/test/util/str.h33
-rw-r--r--src/test/util/wallet.cpp40
-rw-r--r--src/test/util/wallet.h24
-rw-r--r--src/test/util_tests.cpp2
-rw-r--r--src/util/string.h10
-rw-r--r--src/util/system.cpp11
-rw-r--r--src/wallet/scriptpubkeyman.cpp3
-rw-r--r--src/wallet/scriptpubkeyman.h4
-rw-r--r--src/wallet/wallet.cpp5
-rw-r--r--src/warnings.cpp43
-rw-r--r--src/warnings.h10
-rwxr-xr-xtest/fuzz/test_runner.py2
48 files changed, 471 insertions, 208 deletions
diff --git a/.travis.yml b/.travis.yml
index 4f9dbeded4..38ad79af29 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -93,6 +93,7 @@ jobs:
arch: s390x
env: >-
FILE_ENV="./ci/test/00_setup_env_s390x.sh"
+ QEMU_USER_CMD="" # Can run the tests natively without qemu
- stage: test
name: 'Win64 [GOAL: deploy] [unit tests, no gui, no functional tests]'
@@ -110,7 +111,7 @@ jobs:
FILE_ENV="./ci/test/00_setup_env_native_centos.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] [bionic] [uses qt5 dev package and some depends packages] [unsigned char]'
env: >-
FILE_ENV="./ci/test/00_setup_env_native_qt5.sh"
@@ -126,6 +127,11 @@ jobs:
FILE_ENV="./ci/test/00_setup_env_native_asan.sh"
- stage: test
+ name: 'x86_64 Linux [GOAL: install] [bionic] [no depends, only system libs, valgrind]'
+ env: >-
+ FILE_ENV="./ci/test/00_setup_env_native_valgrind.sh"
+
+ - stage: test
name: 'x86_64 Linux [GOAL: install] [bionic] [no depends, only system libs, sanitizers: fuzzer,address,undefined]'
env: >-
FILE_ENV="./ci/test/00_setup_env_native_fuzz.sh"
diff --git a/ci/test/00_setup_env_native_valgrind.sh b/ci/test/00_setup_env_native_valgrind.sh
new file mode 100644
index 0000000000..906ffd7d79
--- /dev/null
+++ b/ci/test/00_setup_env_native_valgrind.sh
@@ -0,0 +1,15 @@
+#!/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 PACKAGES="valgrind clang llvm python3-zmq libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-test-dev libboost-thread-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev"
+export USE_VALGRIND=1
+export NO_DEPENDS=1
+export TEST_RUNNER_EXTRA="p2p_segwit.py" # Only run one test for now. TODO enable all and bump timeouts
+export RUN_FUNCTIONAL_TESTS=true
+export GOAL="install"
+export BITCOIN_CONFIG="--enable-zmq --with-incompatible-bdb --with-gui=no CC=clang CXX=clang++" # TODO enable GUI
diff --git a/ci/test/00_setup_env_s390x.sh b/ci/test/00_setup_env_s390x.sh
index 89660c7fa4..637d549553 100644
--- a/ci/test/00_setup_env_s390x.sh
+++ b/ci/test/00_setup_env_s390x.sh
@@ -6,9 +6,11 @@
export LC_ALL=C.UTF-8
-export HOST=s390x-unknown-linux-gnu
-export PACKAGES="clang llvm python3-zmq qtbase5-dev qttools5-dev-tools libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-test-dev libboost-thread-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev libqrencode-dev"
-export NO_DEPENDS=1
+export HOST=s390x-linux-gnu
+# The host arch is unknown, so we run the tests through qemu.
+# If the host is s390x and wants to run the tests natively, it can set QEMU_USER_CMD to the empty string.
+export QEMU_USER_CMD="${QEMU_USER_CMD:"qemu-s390x"}"
+export PACKAGES="python3-zmq bsdmainutils qemu-user"
export RUN_UNIT_TESTS=true
export RUN_FUNCTIONAL_TESTS=true
export GOAL="install"
diff --git a/ci/test/04_install.sh b/ci/test/04_install.sh
index c721345250..62f30535cb 100755
--- a/ci/test/04_install.sh
+++ b/ci/test/04_install.sh
@@ -41,7 +41,7 @@ export ASAN_OPTIONS="detect_stack_use_after_return=1:check_initialization_order=
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"
-env | grep -E '^(BITCOIN_CONFIG|CCACHE_|WINEDEBUG|LC_ALL|BOOST_TEST_RANDOM|CONFIG_SHELL|(ASAN|LSAN|TSAN|UBSAN)_OPTIONS)' | tee /tmp/env
+env | grep -E '^(BITCOIN_CONFIG|BASE_|CCACHE_|WINEDEBUG|LC_ALL|BOOST_TEST_RANDOM|CONFIG_SHELL|(ASAN|LSAN|TSAN|UBSAN)_OPTIONS)' | tee /tmp/env
if [[ $HOST = *-mingw32 ]]; then
DOCKER_ADMIN="--cap-add SYS_ADMIN"
elif [[ $BITCOIN_CONFIG = *--with-sanitizers=*address* ]]; then # If ran with (ASan + LSan), Docker needs access to ptrace (https://github.com/google/sanitizers/issues/764)
diff --git a/ci/test/06_script_b.sh b/ci/test/06_script_b.sh
index a8e0a50f36..e641cef279 100755
--- a/ci/test/06_script_b.sh
+++ b/ci/test/06_script_b.sh
@@ -8,7 +8,6 @@ export LC_ALL=C.UTF-8
if [ -n "$QEMU_USER_CMD" ]; then
BEGIN_FOLD wrap-qemu
- echo "Prepare to run functional tests for HOST=$HOST"
# Generate all binaries, so that they can be wrapped
DOCKER_EXEC make $MAKEJOBS -C src/secp256k1 VERBOSE=1
DOCKER_EXEC make $MAKEJOBS -C src/univalue VERBOSE=1
@@ -25,6 +24,12 @@ if [ -n "$QEMU_USER_CMD" ]; then
END_FOLD
fi
+if [ -n "$USE_VALGRIND" ]; then
+ BEGIN_FOLD wrap-valgrind
+ DOCKER_EXEC "${BASE_ROOT_DIR}/ci/test/wrap-valgrind.sh"
+ END_FOLD
+fi
+
if [ "$RUN_UNIT_TESTS" = "true" ]; then
BEGIN_FOLD unit-tests
bash -c "${CI_WAIT}" & # Print dots in case the unit tests take a long time to run
diff --git a/ci/test/wrap-valgrind.sh b/ci/test/wrap-valgrind.sh
new file mode 100755
index 0000000000..d2192061db
--- /dev/null
+++ b/ci/test/wrap-valgrind.sh
@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+#
+# Copyright (c) 2018 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
+
+for b_name in "${BASE_OUTDIR}/bin"/*; do
+ # shellcheck disable=SC2044
+ for b in $(find "${BASE_ROOT_DIR}" -executable -type f -name $(basename $b_name)); do
+ echo "Wrap $b ..."
+ mv "$b" "${b}_orig"
+ echo '#!/usr/bin/env bash' > "$b"
+ echo "valgrind --gen-suppressions=all --quiet --error-exitcode=1 --suppressions=${BASE_ROOT_DIR}/contrib/valgrind.supp \"${b}_orig\" \"\$@\"" >> "$b"
+ chmod +x "$b"
+ done
+done
diff --git a/contrib/valgrind.supp b/contrib/valgrind.supp
index 3c485c1df6..f232bb62c2 100644
--- a/contrib/valgrind.supp
+++ b/contrib/valgrind.supp
@@ -30,8 +30,6 @@
Memcheck:Cond
obj:*/libdb_cxx-*.so
fun:__log_put
- obj:*/libdb_cxx-*.so
- fun:__log_put_record
}
{
Suppress libdb warning
@@ -39,9 +37,52 @@
pwrite64(buf)
fun:pwrite
fun:__os_io
+}
+{
+ Suppress libdb warning
+ Memcheck:Cond
+ fun:__log_putr.isra.1
+}
+{
+ Suppress libdb warning
+ Memcheck:Param
+ pwrite64(buf)
+ fun:pwrite
+ fun:__os_io
+ obj:*/libdb_cxx-*.so
+}
+{
+ Suppress uninitialized bytes warning in compat code
+ Memcheck:Param
+ ioctl(TCSET{S,SW,SF})
+ fun:tcsetattr
+}
+{
+ Suppress libdb warning
+ Memcheck:Leak
+ fun:malloc
+ ...
obj:*/libdb_cxx-*.so
}
{
+ Suppress leaks on init
+ Memcheck:Leak
+ ...
+ fun:_Z11AppInitMainR11NodeContext
+}
+{
+ Suppress leaks on shutdown
+ Memcheck:Leak
+ ...
+ fun:_Z8ShutdownR11NodeContext
+}
+{
+ Ignore GUI warning
+ Memcheck:Leak
+ ...
+ obj:/usr/lib64/libgdk-3.so.0.2404.7
+}
+{
Suppress leveldb warning (leveldb::InitModule()) - https://github.com/google/leveldb/issues/113
Memcheck:Leak
match-leak-kinds: reachable
@@ -57,16 +98,48 @@
fun:_ZN7leveldbL14InitDefaultEnvEv
}
{
+ Suppress leveldb leak
+ Memcheck:Leak
+ match-leak-kinds: reachable
+ fun:_Znwm
+ ...
+ fun:_ZN7leveldb6DBImpl14BackgroundCallEv
+}
+{
+ Suppress leveldb leak
+ Memcheck:Leak
+ fun:_Znwm
+ ...
+ fun:GetCoin
+}
+{
Suppress wcsnrtombs glibc SSE4 warning (could be related: https://stroika.atlassian.net/browse/STK-626)
Memcheck:Addr16
fun:__wcsnlen_sse4_1
fun:wcsnrtombs
}
{
+ Suppress wcsnrtombs warning (remove after removing boost::fs)
+ Memcheck:Cond
+ ...
+ fun:_ZN5boost10filesystem6detail11unique_pathERKNS0_4pathEPNS_6system10error_codeE
+ fun:unique_path
+}
+{
+ Suppress boost warning
+ Memcheck:Leak
+ fun:_Znwm
+ ...
+ fun:_ZN5boost9unit_test9framework5state17execute_test_treeEmjPKNS2_23random_generator_helperE
+ fun:_ZN5boost9unit_test9framework3runEmb
+ fun:_ZN5boost9unit_test14unit_test_mainEPFbvEiPPc
+ fun:main
+}
+{
Suppress boost::filesystem warning (fixed in boost 1.70: https://github.com/boostorg/filesystem/commit/bbe9d1771e5d679b3f10c42a58fc81f7e8c024a9)
Memcheck:Cond
fun:_ZN5boost10filesystem6detail28directory_iterator_incrementERNS0_18directory_iteratorEPNS_6system10error_codeE
- fun:_ZN5boost10filesystem6detail28directory_iterator_constructERNS0_18directory_iteratorERKNS0_4pathEPNS_6system10error_codeE
+ ...
obj:*/libboost_filesystem.so.*
}
{
@@ -74,6 +147,7 @@
Memcheck:Leak
match-leak-kinds: reachable
fun:_Znwm
+ ...
fun:_ZN5boost10filesystem8absoluteERKNS0_4pathES3_
}
{
diff --git a/src/Makefile.bench.include b/src/Makefile.bench.include
index 9e70db116b..1c97e22de8 100644
--- a/src/Makefile.bench.include
+++ b/src/Makefile.bench.include
@@ -39,9 +39,7 @@ bench_bench_bitcoin_SOURCES = \
bench/bech32.cpp \
bench/lockedpool.cpp \
bench/poly1305.cpp \
- bench/prevector.cpp \
- test/util.h \
- test/util.cpp
+ bench/prevector.cpp
nodist_bench_bench_bitcoin_SOURCES = $(GENERATED_BENCH_FILES)
diff --git a/src/Makefile.test.include b/src/Makefile.test.include
index a8845b4c7d..091ef50349 100644
--- a/src/Makefile.test.include
+++ b/src/Makefile.test.include
@@ -8,6 +8,7 @@ FUZZ_TARGETS = \
test/fuzz/address_deserialize \
test/fuzz/addrman_deserialize \
test/fuzz/banentry_deserialize \
+ test/fuzz/base_encode_decode \
test/fuzz/bech32 \
test/fuzz/block \
test/fuzz/block_deserialize \
@@ -27,6 +28,7 @@ FUZZ_TARGETS = \
test/fuzz/eval_script \
test/fuzz/fee_rate_deserialize \
test/fuzz/flat_file_pos_deserialize \
+ test/fuzz/hex \
test/fuzz/integer \
test/fuzz/inv_deserialize \
test/fuzz/key_origin_info_deserialize \
@@ -278,6 +280,12 @@ test_fuzz_bech32_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
test_fuzz_bech32_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
test_fuzz_bech32_LDADD = $(FUZZ_SUITE_LD_COMMON)
+test_fuzz_base_encode_decode_SOURCES = $(FUZZ_SUITE) test/fuzz/base_encode_decode.cpp
+test_fuzz_base_encode_decode_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
+test_fuzz_base_encode_decode_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
+test_fuzz_base_encode_decode_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
+test_fuzz_base_encode_decode_LDADD = $(FUZZ_SUITE_LD_COMMON)
+
test_fuzz_txundo_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp
test_fuzz_txundo_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DTXUNDO_DESERIALIZE=1
test_fuzz_txundo_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
@@ -356,6 +364,12 @@ test_fuzz_address_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
test_fuzz_address_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
test_fuzz_address_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
+test_fuzz_hex_SOURCES = $(FUZZ_SUITE) test/fuzz/hex.cpp
+test_fuzz_hex_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
+test_fuzz_hex_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
+test_fuzz_hex_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
+test_fuzz_hex_LDADD = $(FUZZ_SUITE_LD_COMMON)
+
test_fuzz_inv_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp
test_fuzz_inv_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DINV_DESERIALIZE=1
test_fuzz_inv_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
diff --git a/src/Makefile.test_util.include b/src/Makefile.test_util.include
index cf55d141b0..505d630b7d 100644
--- a/src/Makefile.test_util.include
+++ b/src/Makefile.test_util.include
@@ -10,22 +10,25 @@ EXTRA_LIBRARIES += \
TEST_UTIL_H = \
test/util/blockfilter.h \
test/util/logging.h \
+ test/util/mining.h \
test/util/setup_common.h \
test/util/str.h \
- test/util/transaction_utils.h
+ test/util/transaction_utils.h \
+ test/util/wallet.h
libtest_util_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(MINIUPNPC_CPPFLAGS) $(EVENT_CFLAGS) $(EVENT_PTHREADS_CFLAGS)
libtest_util_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
libtest_util_a_SOURCES = \
test/util/blockfilter.cpp \
test/util/logging.cpp \
+ test/util/mining.cpp \
test/util/setup_common.cpp \
test/util/str.cpp \
test/util/transaction_utils.cpp \
+ test/util/wallet.cpp \
$(TEST_UTIL_H)
LIBTEST_UTIL += $(LIBBITCOIN_SERVER)
LIBTEST_UTIL += $(LIBBITCOIN_COMMON)
LIBTEST_UTIL += $(LIBBITCOIN_UTIL)
LIBTEST_UTIL += $(LIBBITCOIN_CRYPTO_BASE)
-
diff --git a/src/bench/block_assemble.cpp b/src/bench/block_assemble.cpp
index 2f47398d99..184367e1e5 100644
--- a/src/bench/block_assemble.cpp
+++ b/src/bench/block_assemble.cpp
@@ -5,7 +5,8 @@
#include <bench/bench.h>
#include <consensus/validation.h>
#include <crypto/sha256.h>
-#include <test/util.h>
+#include <test/util/mining.h>
+#include <test/util/wallet.h>
#include <txmempool.h>
#include <validation.h>
diff --git a/src/bench/wallet_balance.cpp b/src/bench/wallet_balance.cpp
index 0e660d6bcd..f39dcc0b71 100644
--- a/src/bench/wallet_balance.cpp
+++ b/src/bench/wallet_balance.cpp
@@ -6,7 +6,8 @@
#include <interfaces/chain.h>
#include <node/context.h>
#include <optional.h>
-#include <test/util.h>
+#include <test/util/mining.h>
+#include <test/util/wallet.h>
#include <validationinterface.h>
#include <wallet/wallet.h>
diff --git a/src/interfaces/chain.cpp b/src/interfaces/chain.cpp
index 26856a00d3..ac640aa35a 100644
--- a/src/interfaces/chain.cpp
+++ b/src/interfaces/chain.cpp
@@ -263,7 +263,7 @@ public:
}
return true;
}
- void findCoins(std::map<COutPoint, Coin>& coins) override { return FindCoins(coins); }
+ void findCoins(std::map<COutPoint, Coin>& coins) override { return FindCoins(m_node, coins); }
double guessVerificationProgress(const uint256& block_hash) override
{
LOCK(cs_main);
diff --git a/src/interfaces/node.cpp b/src/interfaces/node.cpp
index 1877c92178..529fa793dd 100644
--- a/src/interfaces/node.cpp
+++ b/src/interfaces/node.cpp
@@ -68,7 +68,7 @@ public:
std::string getNetwork() override { return Params().NetworkIDString(); }
void initLogging() override { InitLogging(); }
void initParameterInteraction() override { InitParameterInteraction(); }
- std::string getWarnings(const std::string& type) override { return GetWarnings(type); }
+ std::string getWarnings() override { return GetWarnings(true); }
uint32_t getLogCategories() override { return LogInstance().GetCategoryMask(); }
bool baseInitialize() override
{
@@ -167,8 +167,8 @@ public:
}
int64_t getTotalBytesRecv() override { return m_context.connman ? m_context.connman->GetTotalBytesRecv() : 0; }
int64_t getTotalBytesSent() override { return m_context.connman ? m_context.connman->GetTotalBytesSent() : 0; }
- size_t getMempoolSize() override { return ::mempool.size(); }
- size_t getMempoolDynamicUsage() override { return ::mempool.DynamicMemoryUsage(); }
+ size_t getMempoolSize() override { return m_context.mempool ? m_context.mempool->size() : 0; }
+ size_t getMempoolDynamicUsage() override { return m_context.mempool ? m_context.mempool->DynamicMemoryUsage() : 0; }
bool getHeaderTip(int& height, int64_t& block_time) override
{
LOCK(::cs_main);
diff --git a/src/interfaces/node.h b/src/interfaces/node.h
index adf3de7b07..6bc4668beb 100644
--- a/src/interfaces/node.h
+++ b/src/interfaces/node.h
@@ -78,7 +78,7 @@ public:
virtual void initParameterInteraction() = 0;
//! Get warnings.
- virtual std::string getWarnings(const std::string& type) = 0;
+ virtual std::string getWarnings() = 0;
// Get log flags.
virtual uint32_t getLogCategories() = 0;
diff --git a/src/netaddress.h b/src/netaddress.h
index fbb1553338..32f4476fac 100644
--- a/src/netaddress.h
+++ b/src/netaddress.h
@@ -54,7 +54,7 @@ class CNetAddr
bool IsIPv4() const; // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0)
bool IsIPv6() const; // IPv6 address (not mapped IPv4, not Tor)
bool IsRFC1918() const; // IPv4 private networks (10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12)
- bool IsRFC2544() const; // IPv4 inter-network communications (192.18.0.0/15)
+ bool IsRFC2544() const; // IPv4 inter-network communications (198.18.0.0/15)
bool IsRFC6598() const; // IPv4 ISP-level NAT (100.64.0.0/10)
bool IsRFC5737() const; // IPv4 documentation addresses (192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24)
bool IsRFC3849() const; // IPv6 documentation address (2001:0DB8::/32)
diff --git a/src/node/coin.cpp b/src/node/coin.cpp
index ad8d1d3af4..f4f86cdbe9 100644
--- a/src/node/coin.cpp
+++ b/src/node/coin.cpp
@@ -4,14 +4,16 @@
#include <node/coin.h>
+#include <node/context.h>
#include <txmempool.h>
#include <validation.h>
-void FindCoins(std::map<COutPoint, Coin>& coins)
+void FindCoins(const NodeContext& node, std::map<COutPoint, Coin>& coins)
{
- LOCK2(cs_main, ::mempool.cs);
+ assert(node.mempool);
+ LOCK2(cs_main, node.mempool->cs);
CCoinsViewCache& chain_view = ::ChainstateActive().CoinsTip();
- CCoinsViewMemPool mempool_view(&chain_view, ::mempool);
+ CCoinsViewMemPool mempool_view(&chain_view, *node.mempool);
for (auto& coin : coins) {
if (!mempool_view.GetCoin(coin.first, coin.second)) {
// Either the coin is not in the CCoinsViewCache or is spent. Clear it.
diff --git a/src/node/coin.h b/src/node/coin.h
index eb95b75cfb..908850e2a5 100644
--- a/src/node/coin.h
+++ b/src/node/coin.h
@@ -9,14 +9,16 @@
class COutPoint;
class Coin;
+struct NodeContext;
/**
* Look up unspent output information. Returns coins in the mempool and in the
* current chain UTXO set. Iterates through all the keys in the map and
* populates the values.
*
+ * @param[in] node The node context to use for lookup
* @param[in,out] coins map to fill
*/
-void FindCoins(std::map<COutPoint, Coin>& coins);
+void FindCoins(const NodeContext& node, std::map<COutPoint, Coin>& coins);
#endif // BITCOIN_NODE_COIN_H
diff --git a/src/node/transaction.cpp b/src/node/transaction.cpp
index 3c0df2b26e..5e2e502015 100644
--- a/src/node/transaction.cpp
+++ b/src/node/transaction.cpp
@@ -20,6 +20,7 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t
// node.connman is assigned both before chain clients and before RPC server is accepting calls,
// and reset after chain clients and RPC sever are stopped. node.connman should never be null here.
assert(node.connman);
+ assert(node.mempool);
std::promise<void> promise;
uint256 hashTx = tx->GetHash();
bool callback_set = false;
@@ -35,10 +36,10 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t
// So if the output does exist, then this transaction exists in the chain.
if (!existingCoin.IsSpent()) return TransactionError::ALREADY_IN_CHAIN;
}
- if (!mempool.exists(hashTx)) {
+ if (!node.mempool->exists(hashTx)) {
// Transaction is not already in the mempool. Submit it.
TxValidationState state;
- if (!AcceptToMemoryPool(mempool, state, std::move(tx),
+ if (!AcceptToMemoryPool(*node.mempool, state, std::move(tx),
nullptr /* plTxnReplaced */, false /* bypass_limits */, max_tx_fee)) {
err_string = FormatStateMessage(state);
if (state.IsInvalid()) {
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index 676c15ea43..0021c3dbc7 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -135,7 +135,7 @@ BitcoinCore::BitcoinCore(interfaces::Node& node) :
void BitcoinCore::handleRunawayException(const std::exception *e)
{
PrintExceptionContinue(e, "Runaway exception");
- Q_EMIT runawayException(QString::fromStdString(m_node.getWarnings("gui")));
+ Q_EMIT runawayException(QString::fromStdString(m_node.getWarnings()));
}
void BitcoinCore::initialize()
@@ -589,10 +589,10 @@ int GuiMain(int argc, char* argv[])
}
} catch (const std::exception& e) {
PrintExceptionContinue(&e, "Runaway exception");
- app.handleRunawayException(QString::fromStdString(node->getWarnings("gui")));
+ app.handleRunawayException(QString::fromStdString(node->getWarnings()));
} catch (...) {
PrintExceptionContinue(nullptr, "Runaway exception");
- app.handleRunawayException(QString::fromStdString(node->getWarnings("gui")));
+ app.handleRunawayException(QString::fromStdString(node->getWarnings()));
}
return rv;
}
diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp
index 5b216b2705..b84587a99b 100644
--- a/src/qt/clientmodel.cpp
+++ b/src/qt/clientmodel.cpp
@@ -134,7 +134,7 @@ enum BlockSource ClientModel::getBlockSource() const
QString ClientModel::getStatusBarWarnings() const
{
- return QString::fromStdString(m_node.getWarnings("gui"));
+ return QString::fromStdString(m_node.getWarnings());
}
OptionsModel *ClientModel::getOptionsModel()
diff --git a/src/qt/test/wallettests.cpp b/src/qt/test/wallettests.cpp
index dfd56511ea..f6d2816ff8 100644
--- a/src/qt/test/wallettests.cpp
+++ b/src/qt/test/wallettests.cpp
@@ -134,6 +134,7 @@ void TestGUI(interfaces::Node& node)
test.CreateAndProcessBlock({}, GetScriptForRawPubKey(test.coinbaseKey.GetPubKey()));
}
node.context()->connman = std::move(test.m_node.connman);
+ node.context()->mempool = std::move(test.m_node.mempool);
std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>(node.context()->chain.get(), WalletLocation(), WalletDatabase::CreateMock());
bool firstRun;
wallet->LoadWallet(firstRun);
diff --git a/src/rest.cpp b/src/rest.cpp
index 228c122de3..55756ecfdf 100644
--- a/src/rest.cpp
+++ b/src/rest.cpp
@@ -8,6 +8,7 @@
#include <core_io.h>
#include <httpserver.h>
#include <index/txindex.h>
+#include <node/context.h>
#include <primitives/block.h>
#include <primitives/transaction.h>
#include <rpc/blockchain.h>
@@ -16,6 +17,7 @@
#include <streams.h>
#include <sync.h>
#include <txmempool.h>
+#include <util/check.h>
#include <util/strencodings.h>
#include <validation.h>
#include <version.h>
@@ -69,6 +71,24 @@ static bool RESTERR(HTTPRequest* req, enum HTTPStatusCode status, std::string me
return false;
}
+/**
+ * Get the node context mempool.
+ *
+ * Set the HTTP error and return nullptr if node context
+ * mempool is not found.
+ *
+ * @param[in] req the HTTP request
+ * return pointer to the mempool or nullptr if no mempool found
+ */
+static CTxMemPool* GetMemPool(HTTPRequest* req)
+{
+ if (!g_rpc_node || !g_rpc_node->mempool) {
+ RESTERR(req, HTTP_NOT_FOUND, "Mempool disabled or instance not found");
+ return nullptr;
+ }
+ return g_rpc_node->mempool;
+}
+
static RetFormat ParseDataFormat(std::string& param, const std::string& strReq)
{
const std::string::size_type pos = strReq.rfind('.');
@@ -295,12 +315,14 @@ static bool rest_mempool_info(HTTPRequest* req, const std::string& strURIPart)
{
if (!CheckWarmup(req))
return false;
+ const CTxMemPool* mempool = GetMemPool(req);
+ if (!mempool) return false;
std::string param;
const RetFormat rf = ParseDataFormat(param, strURIPart);
switch (rf) {
case RetFormat::JSON: {
- UniValue mempoolInfoObject = MempoolInfoToJSON(::mempool);
+ UniValue mempoolInfoObject = MempoolInfoToJSON(*mempool);
std::string strJSON = mempoolInfoObject.write() + "\n";
req->WriteHeader("Content-Type", "application/json");
@@ -315,14 +337,15 @@ static bool rest_mempool_info(HTTPRequest* req, const std::string& strURIPart)
static bool rest_mempool_contents(HTTPRequest* req, const std::string& strURIPart)
{
- if (!CheckWarmup(req))
- return false;
+ if (!CheckWarmup(req)) return false;
+ const CTxMemPool* mempool = GetMemPool(req);
+ if (!mempool) return false;
std::string param;
const RetFormat rf = ParseDataFormat(param, strURIPart);
switch (rf) {
case RetFormat::JSON: {
- UniValue mempoolObject = MempoolToJSON(::mempool, true);
+ UniValue mempoolObject = MempoolToJSON(*mempool, true);
std::string strJSON = mempoolObject.write() + "\n";
req->WriteHeader("Content-Type", "application/json");
@@ -500,11 +523,13 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart)
};
if (fCheckMemPool) {
+ const CTxMemPool* mempool = GetMemPool(req);
+ if (!mempool) return false;
// use db+mempool as cache backend in case user likes to query mempool
- LOCK2(cs_main, mempool.cs);
+ LOCK2(cs_main, mempool->cs);
CCoinsViewCache& viewChain = ::ChainstateActive().CoinsTip();
- CCoinsViewMemPool viewMempool(&viewChain, mempool);
- process_utxos(viewMempool, mempool);
+ CCoinsViewMemPool viewMempool(&viewChain, *mempool);
+ process_utxos(viewMempool, *mempool);
} else {
LOCK(cs_main); // no need to lock mempool!
process_utxos(::ChainstateActive().CoinsTip(), CTxMemPool());
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index 44f5326b3c..eb5148eebd 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -528,7 +528,7 @@ static UniValue getrawmempool(const JSONRPCRequest& request)
if (!request.params[0].isNull())
fVerbose = request.params[0].get_bool();
- return MempoolToJSON(::mempool, fVerbose);
+ return MempoolToJSON(EnsureMemPool(), fVerbose);
}
static UniValue getmempoolancestors(const JSONRPCRequest& request)
@@ -566,6 +566,7 @@ static UniValue getmempoolancestors(const JSONRPCRequest& request)
uint256 hash = ParseHashV(request.params[0], "parameter 1");
+ const CTxMemPool& mempool = EnsureMemPool();
LOCK(mempool.cs);
CTxMemPool::txiter it = mempool.mapTx.find(hash);
@@ -591,7 +592,7 @@ static UniValue getmempoolancestors(const JSONRPCRequest& request)
const CTxMemPoolEntry &e = *ancestorIt;
const uint256& _hash = e.GetTx().GetHash();
UniValue info(UniValue::VOBJ);
- entryToJSON(::mempool, info, e);
+ entryToJSON(mempool, info, e);
o.pushKV(_hash.ToString(), info);
}
return o;
@@ -633,6 +634,7 @@ static UniValue getmempooldescendants(const JSONRPCRequest& request)
uint256 hash = ParseHashV(request.params[0], "parameter 1");
+ const CTxMemPool& mempool = EnsureMemPool();
LOCK(mempool.cs);
CTxMemPool::txiter it = mempool.mapTx.find(hash);
@@ -658,7 +660,7 @@ static UniValue getmempooldescendants(const JSONRPCRequest& request)
const CTxMemPoolEntry &e = *descendantIt;
const uint256& _hash = e.GetTx().GetHash();
UniValue info(UniValue::VOBJ);
- entryToJSON(::mempool, info, e);
+ entryToJSON(mempool, info, e);
o.pushKV(_hash.ToString(), info);
}
return o;
@@ -685,6 +687,7 @@ static UniValue getmempoolentry(const JSONRPCRequest& request)
uint256 hash = ParseHashV(request.params[0], "parameter 1");
+ const CTxMemPool& mempool = EnsureMemPool();
LOCK(mempool.cs);
CTxMemPool::txiter it = mempool.mapTx.find(hash);
@@ -694,7 +697,7 @@ static UniValue getmempoolentry(const JSONRPCRequest& request)
const CTxMemPoolEntry &e = *it;
UniValue info(UniValue::VOBJ);
- entryToJSON(::mempool, info, e);
+ entryToJSON(mempool, info, e);
return info;
}
@@ -1070,6 +1073,7 @@ UniValue gettxout(const JSONRPCRequest& request)
CCoinsViewCache* coins_view = &::ChainstateActive().CoinsTip();
if (fMempool) {
+ const CTxMemPool& mempool = EnsureMemPool();
LOCK(mempool.cs);
CCoinsViewMemPool view(coins_view, mempool);
if (!view.GetCoin(out, coin) || mempool.isSpent(out)) {
@@ -1286,7 +1290,7 @@ UniValue getblockchaininfo(const JSONRPCRequest& request)
BIP9SoftForkDescPushBack(softforks, "testdummy", consensusParams, Consensus::DEPLOYMENT_TESTDUMMY);
obj.pushKV("softforks", softforks);
- obj.pushKV("warnings", GetWarnings("statusbar"));
+ obj.pushKV("warnings", GetWarnings(false));
return obj;
}
@@ -1448,7 +1452,7 @@ static UniValue getmempoolinfo(const JSONRPCRequest& request)
},
}.Check(request);
- return MempoolInfoToJSON(::mempool);
+ return MempoolInfoToJSON(EnsureMemPool());
}
static UniValue preciousblock(const JSONRPCRequest& request)
@@ -1964,11 +1968,13 @@ static UniValue savemempool(const JSONRPCRequest& request)
},
}.Check(request);
- if (!::mempool.IsLoaded()) {
+ const CTxMemPool& mempool = EnsureMemPool();
+
+ if (!mempool.IsLoaded()) {
throw JSONRPCError(RPC_MISC_ERROR, "The mempool was not loaded yet");
}
- if (!DumpMempool(::mempool)) {
+ if (!DumpMempool(mempool)) {
throw JSONRPCError(RPC_MISC_ERROR, "Unable to dump mempool to disk");
}
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
index fc16a31423..9f7f7837d3 100644
--- a/src/rpc/mining.cpp
+++ b/src/rpc/mining.cpp
@@ -244,6 +244,7 @@ static UniValue getmininginfo(const JSONRPCRequest& request)
}.Check(request);
LOCK(cs_main);
+ const CTxMemPool& mempool = EnsureMemPool();
UniValue obj(UniValue::VOBJ);
obj.pushKV("blocks", (int)::ChainActive().Height());
@@ -253,7 +254,7 @@ static UniValue getmininginfo(const JSONRPCRequest& request)
obj.pushKV("networkhashps", getnetworkhashps(request));
obj.pushKV("pooledtx", (uint64_t)mempool.size());
obj.pushKV("chain", Params().NetworkIDString());
- obj.pushKV("warnings", GetWarnings("statusbar"));
+ obj.pushKV("warnings", GetWarnings(false));
return obj;
}
@@ -290,7 +291,7 @@ static UniValue prioritisetransaction(const JSONRPCRequest& request)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Priority is no longer supported, dummy argument to prioritisetransaction must be 0.");
}
- mempool.PrioritiseTransaction(hash, nAmount);
+ EnsureMemPool().PrioritiseTransaction(hash, nAmount);
return true;
}
@@ -476,6 +477,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, PACKAGE_NAME " is in initial sync and waiting for blocks...");
static unsigned int nTransactionsUpdatedLast;
+ const CTxMemPool& mempool = EnsureMemPool();
if (!lpval.isNull())
{
@@ -510,7 +512,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
if (g_best_block_cv.wait_until(lock, checktxtime) == std::cv_status::timeout)
{
// Timeout: Check transactions for update
- // without holding ::mempool.cs to avoid deadlocks
+ // without holding the mempool lock to avoid deadlocks
if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLastLP)
break;
checktxtime += std::chrono::seconds(10);
diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp
index 6ee91f139d..5e53fa5f5d 100644
--- a/src/rpc/net.cpp
+++ b/src/rpc/net.cpp
@@ -522,7 +522,7 @@ static UniValue getnetworkinfo(const JSONRPCRequest& request)
}
}
obj.pushKV("localaddresses", localAddresses);
- obj.pushKV("warnings", GetWarnings("statusbar"));
+ obj.pushKV("warnings", GetWarnings(false));
return obj;
}
diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp
index b816a54d2f..5be7acce1c 100644
--- a/src/rpc/rawtransaction.cpp
+++ b/src/rpc/rawtransaction.cpp
@@ -636,6 +636,7 @@ static UniValue combinerawtransaction(const JSONRPCRequest& request)
CCoinsView viewDummy;
CCoinsViewCache view(&viewDummy);
{
+ const CTxMemPool& mempool = EnsureMemPool();
LOCK(cs_main);
LOCK(mempool.cs);
CCoinsViewCache &viewChain = ::ChainstateActive().CoinsTip();
@@ -758,7 +759,7 @@ static UniValue signrawtransactionwithkey(const JSONRPCRequest& request)
for (const CTxIn& txin : mtx.vin) {
coins[txin.prevout]; // Create empty map entry keyed by prevout.
}
- FindCoins(coins);
+ FindCoins(*g_rpc_node, coins);
// Parse the prevtxs array
ParsePrevouts(request.params[2], &keystore, coins);
@@ -890,6 +891,7 @@ static UniValue testmempoolaccept(const JSONRPCRequest& request)
max_raw_tx_fee_rate = CFeeRate(AmountFromValue(request.params[1]));
}
+ CTxMemPool& mempool = EnsureMemPool();
int64_t virtual_size = GetVirtualTransactionSize(*tx);
CAmount max_raw_tx_fee = max_raw_tx_fee_rate.GetFee(virtual_size);
@@ -1508,6 +1510,7 @@ UniValue utxoupdatepsbt(const JSONRPCRequest& request)
CCoinsView viewDummy;
CCoinsViewCache view(&viewDummy);
{
+ const CTxMemPool& mempool = EnsureMemPool();
LOCK2(cs_main, mempool.cs);
CCoinsViewCache &viewChain = ::ChainstateActive().CoinsTip();
CCoinsViewMemPool viewMempool(&viewChain, mempool);
diff --git a/src/test/fuzz/base_encode_decode.cpp b/src/test/fuzz/base_encode_decode.cpp
new file mode 100644
index 0000000000..cb0fbdf76f
--- /dev/null
+++ b/src/test/fuzz/base_encode_decode.cpp
@@ -0,0 +1,47 @@
+// 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.
+
+#include <test/fuzz/fuzz.h>
+
+#include <base58.h>
+#include <util/string.h>
+#include <util/strencodings.h>
+
+#include <cassert>
+#include <cstdint>
+#include <string>
+#include <vector>
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ const std::string random_encoded_string(buffer.begin(), buffer.end());
+
+ std::vector<unsigned char> decoded;
+ if (DecodeBase58(random_encoded_string, decoded, 100)) {
+ const std::string encoded_string = EncodeBase58(decoded);
+ assert(encoded_string == TrimString(encoded_string));
+ assert(ToLower(encoded_string) == ToLower(TrimString(random_encoded_string)));
+ }
+
+ if (DecodeBase58Check(random_encoded_string, decoded, 100)) {
+ const std::string encoded_string = EncodeBase58Check(decoded);
+ assert(encoded_string == TrimString(encoded_string));
+ assert(ToLower(encoded_string) == ToLower(TrimString(random_encoded_string)));
+ }
+
+ bool pf_invalid;
+ std::string decoded_string = DecodeBase32(random_encoded_string, &pf_invalid);
+ if (!pf_invalid) {
+ const std::string encoded_string = EncodeBase32(decoded_string);
+ assert(encoded_string == TrimString(encoded_string));
+ assert(ToLower(encoded_string) == ToLower(TrimString(random_encoded_string)));
+ }
+
+ decoded_string = DecodeBase64(random_encoded_string, &pf_invalid);
+ if (!pf_invalid) {
+ const std::string encoded_string = EncodeBase64(decoded_string);
+ assert(encoded_string == TrimString(encoded_string));
+ assert(ToLower(encoded_string) == ToLower(TrimString(random_encoded_string)));
+ }
+}
diff --git a/src/test/fuzz/hex.cpp b/src/test/fuzz/hex.cpp
new file mode 100644
index 0000000000..54693180be
--- /dev/null
+++ b/src/test/fuzz/hex.cpp
@@ -0,0 +1,22 @@
+// 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.
+
+#include <test/fuzz/fuzz.h>
+
+#include <util/strencodings.h>
+
+#include <cassert>
+#include <cstdint>
+#include <string>
+#include <vector>
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ const std::string random_hex_string(buffer.begin(), buffer.end());
+ const std::vector<unsigned char> data = ParseHex(random_hex_string);
+ const std::string hex_data = HexStr(data);
+ if (IsHex(random_hex_string)) {
+ assert(ToLower(random_hex_string) == hex_data);
+ }
+}
diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp
index 78c11ff202..481dedc356 100644
--- a/src/test/netbase_tests.cpp
+++ b/src/test/netbase_tests.cpp
@@ -54,6 +54,8 @@ BOOST_AUTO_TEST_CASE(netbase_properties)
BOOST_CHECK(ResolveIP("10.0.0.1").IsRFC1918());
BOOST_CHECK(ResolveIP("192.168.1.1").IsRFC1918());
BOOST_CHECK(ResolveIP("172.31.255.255").IsRFC1918());
+ BOOST_CHECK(ResolveIP("198.18.0.0").IsRFC2544());
+ BOOST_CHECK(ResolveIP("198.19.255.255").IsRFC2544());
BOOST_CHECK(ResolveIP("2001:0DB8::").IsRFC3849());
BOOST_CHECK(ResolveIP("169.254.1.1").IsRFC3927());
BOOST_CHECK(ResolveIP("2002::1").IsRFC3964());
diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp
index 52dd22de7e..84a3980b19 100644
--- a/src/test/rpc_tests.cpp
+++ b/src/test/rpc_tests.cpp
@@ -112,14 +112,10 @@ BOOST_AUTO_TEST_CASE(rpc_rawsign)
std::string notsigned = r.get_str();
std::string privkey1 = "\"KzsXybp9jX64P5ekX1KUxRQ79Jht9uzW7LorgwE65i5rWACL6LQe\"";
std::string privkey2 = "\"Kyhdf5LuKTRx4ge69ybABsiUAWjVRK4XGxAKk2FQLp2HjGMy87Z4\"";
- NodeContext node;
- node.chain = interfaces::MakeChain(node);
- g_rpc_node = &node;
r = CallRPC(std::string("signrawtransactionwithkey ")+notsigned+" [] "+prevout);
BOOST_CHECK(find_value(r.get_obj(), "complete").get_bool() == false);
r = CallRPC(std::string("signrawtransactionwithkey ")+notsigned+" ["+privkey1+","+privkey2+"] "+prevout);
BOOST_CHECK(find_value(r.get_obj(), "complete").get_bool() == true);
- g_rpc_node = nullptr;
}
BOOST_AUTO_TEST_CASE(rpc_createraw_op_return)
diff --git a/src/test/settings_tests.cpp b/src/test/settings_tests.cpp
index b0ee76ea6b..235420e6ac 100644
--- a/src/test/settings_tests.cpp
+++ b/src/test/settings_tests.cpp
@@ -4,8 +4,9 @@
#include <util/settings.h>
-#include <test/util.h>
#include <test/util/setup_common.h>
+#include <test/util/str.h>
+
#include <boost/test/unit_test.hpp>
#include <univalue.h>
diff --git a/src/test/timedata_tests.cpp b/src/test/timedata_tests.cpp
index 4721151197..19bd0d142f 100644
--- a/src/test/timedata_tests.cpp
+++ b/src/test/timedata_tests.cpp
@@ -65,7 +65,7 @@ BOOST_AUTO_TEST_CASE(addtimedata)
MultiAddTimeData(1, DEFAULT_MAX_TIME_ADJUSTMENT + 1); //filter size 5
}
- BOOST_CHECK(GetWarnings("gui").find("clock is wrong") != std::string::npos);
+ BOOST_CHECK(GetWarnings(true).find("clock is wrong") != std::string::npos);
// nTimeOffset is not changed if the median of offsets exceeds DEFAULT_MAX_TIME_ADJUSTMENT
BOOST_CHECK_EQUAL(GetTimeOffset(), 0);
diff --git a/src/test/util.h b/src/test/util.h
deleted file mode 100644
index f90cb0d623..0000000000
--- a/src/test/util.h
+++ /dev/null
@@ -1,70 +0,0 @@
-// 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.
-
-#ifndef BITCOIN_TEST_UTIL_H
-#define BITCOIN_TEST_UTIL_H
-
-#include <memory>
-#include <string>
-
-class CBlock;
-class CScript;
-class CTxIn;
-class CWallet;
-
-// Constants //
-
-extern const std::string ADDRESS_BCRT1_UNSPENDABLE;
-
-// Lower-level utils //
-
-/** Returns the generated coin */
-CTxIn MineBlock(const CScript& coinbase_scriptPubKey);
-/** Prepare a block to be mined */
-std::shared_ptr<CBlock> PrepareBlock(const CScript& coinbase_scriptPubKey);
-
-
-// RPC-like //
-
-/** Import the address to the wallet */
-void importaddress(CWallet& wallet, const std::string& address);
-/** Returns a new address from the wallet */
-std::string getnewaddress(CWallet& w);
-/** Returns the generated coin */
-CTxIn generatetoaddress(const std::string& address);
-
-/**
- * Increment a string. Useful to enumerate all fixed length strings with
- * characters in [min_char, max_char].
- */
-template <typename CharType, size_t StringLength>
-bool NextString(CharType (&string)[StringLength], CharType min_char, CharType max_char)
-{
- for (CharType& elem : string) {
- bool has_next = elem != max_char;
- elem = elem < min_char || elem >= max_char ? min_char : CharType(elem + 1);
- if (has_next) return true;
- }
- return false;
-}
-
-/**
- * Iterate over string values and call function for each string without
- * successive duplicate characters.
- */
-template <typename CharType, size_t StringLength, typename Fn>
-void ForEachNoDup(CharType (&string)[StringLength], CharType min_char, CharType max_char, Fn&& fn) {
- for (bool has_next = true; has_next; has_next = NextString(string, min_char, max_char)) {
- int prev = -1;
- bool skip_string = false;
- for (CharType c : string) {
- if (c == prev) skip_string = true;
- if (skip_string || c < min_char || c > max_char) break;
- prev = c;
- }
- if (!skip_string) fn();
- }
-}
-
-#endif // BITCOIN_TEST_UTIL_H
diff --git a/src/test/util.cpp b/src/test/util/mining.cpp
index ed031270f2..30f0f5d7e6 100644
--- a/src/test/util.cpp
+++ b/src/test/util/mining.cpp
@@ -2,48 +2,15 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <test/util.h>
+#include <test/util/mining.h>
#include <chainparams.h>
#include <consensus/merkle.h>
#include <key_io.h>
#include <miner.h>
-#include <outputtype.h>
#include <pow.h>
#include <script/standard.h>
#include <validation.h>
-#include <validationinterface.h>
-#ifdef ENABLE_WALLET
-#include <wallet/wallet.h>
-#endif
-
-const std::string ADDRESS_BCRT1_UNSPENDABLE = "bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3xueyj";
-
-#ifdef ENABLE_WALLET
-std::string getnewaddress(CWallet& w)
-{
- constexpr auto output_type = OutputType::BECH32;
- CTxDestination dest;
- std::string error;
- if (!w.GetNewDestination(output_type, "", dest, error)) assert(false);
-
- return EncodeDestination(dest);
-}
-
-void importaddress(CWallet& wallet, const std::string& address)
-{
- auto spk_man = wallet.GetLegacyScriptPubKeyMan();
- LOCK(wallet.cs_wallet);
- AssertLockHeld(spk_man->cs_wallet);
- const auto dest = DecodeDestination(address);
- assert(IsValidDestination(dest));
- const auto script = GetScriptForDestination(dest);
- wallet.MarkDirty();
- assert(!spk_man->HaveWatchOnly(script));
- if (!spk_man->AddWatchOnly(script, 0 /* nCreateTime */)) assert(false);
- wallet.SetAddressBook(dest, /* label */ "", "receive");
-}
-#endif // ENABLE_WALLET
CTxIn generatetoaddress(const std::string& address)
{
diff --git a/src/test/util/mining.h b/src/test/util/mining.h
new file mode 100644
index 0000000000..afe4de684f
--- /dev/null
+++ b/src/test/util/mining.h
@@ -0,0 +1,24 @@
+// 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.
+
+#ifndef BITCOIN_TEST_UTIL_MINING_H
+#define BITCOIN_TEST_UTIL_MINING_H
+
+#include <memory>
+#include <string>
+
+class CBlock;
+class CScript;
+class CTxIn;
+
+/** Returns the generated coin */
+CTxIn MineBlock(const CScript& coinbase_scriptPubKey);
+
+/** Prepare a block to be mined */
+std::shared_ptr<CBlock> PrepareBlock(const CScript& coinbase_scriptPubKey);
+
+/** RPC-like helper function, returns the generated coin */
+CTxIn generatetoaddress(const std::string& address);
+
+#endif // BITCOIN_TEST_UTIL_MINING_H
diff --git a/src/test/util/str.h b/src/test/util/str.h
index 63629501e8..ef94692df0 100644
--- a/src/test/util/str.h
+++ b/src/test/util/str.h
@@ -9,4 +9,37 @@
bool CaseInsensitiveEqual(const std::string& s1, const std::string& s2);
+/**
+ * Increment a string. Useful to enumerate all fixed length strings with
+ * characters in [min_char, max_char].
+ */
+template <typename CharType, size_t StringLength>
+bool NextString(CharType (&string)[StringLength], CharType min_char, CharType max_char)
+{
+ for (CharType& elem : string) {
+ bool has_next = elem != max_char;
+ elem = elem < min_char || elem >= max_char ? min_char : CharType(elem + 1);
+ if (has_next) return true;
+ }
+ return false;
+}
+
+/**
+ * Iterate over string values and call function for each string without
+ * successive duplicate characters.
+ */
+template <typename CharType, size_t StringLength, typename Fn>
+void ForEachNoDup(CharType (&string)[StringLength], CharType min_char, CharType max_char, Fn&& fn) {
+ for (bool has_next = true; has_next; has_next = NextString(string, min_char, max_char)) {
+ int prev = -1;
+ bool skip_string = false;
+ for (CharType c : string) {
+ if (c == prev) skip_string = true;
+ if (skip_string || c < min_char || c > max_char) break;
+ prev = c;
+ }
+ if (!skip_string) fn();
+ }
+}
+
#endif // BITCOIN_TEST_UTIL_STR_H
diff --git a/src/test/util/wallet.cpp b/src/test/util/wallet.cpp
new file mode 100644
index 0000000000..226d2df6e4
--- /dev/null
+++ b/src/test/util/wallet.cpp
@@ -0,0 +1,40 @@
+// 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.
+
+#include <test/util/wallet.h>
+
+#include <key_io.h>
+#include <outputtype.h>
+#include <script/standard.h>
+#ifdef ENABLE_WALLET
+#include <wallet/wallet.h>
+#endif
+
+const std::string ADDRESS_BCRT1_UNSPENDABLE = "bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3xueyj";
+
+#ifdef ENABLE_WALLET
+std::string getnewaddress(CWallet& w)
+{
+ constexpr auto output_type = OutputType::BECH32;
+ CTxDestination dest;
+ std::string error;
+ if (!w.GetNewDestination(output_type, "", dest, error)) assert(false);
+
+ return EncodeDestination(dest);
+}
+
+void importaddress(CWallet& wallet, const std::string& address)
+{
+ auto spk_man = wallet.GetLegacyScriptPubKeyMan();
+ LOCK(wallet.cs_wallet);
+ AssertLockHeld(spk_man->cs_wallet);
+ const auto dest = DecodeDestination(address);
+ assert(IsValidDestination(dest));
+ const auto script = GetScriptForDestination(dest);
+ wallet.MarkDirty();
+ assert(!spk_man->HaveWatchOnly(script));
+ if (!spk_man->AddWatchOnly(script, 0 /* nCreateTime */)) assert(false);
+ wallet.SetAddressBook(dest, /* label */ "", "receive");
+}
+#endif // ENABLE_WALLET
diff --git a/src/test/util/wallet.h b/src/test/util/wallet.h
new file mode 100644
index 0000000000..565ef1756a
--- /dev/null
+++ b/src/test/util/wallet.h
@@ -0,0 +1,24 @@
+// 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.
+
+#ifndef BITCOIN_TEST_UTIL_WALLET_H
+#define BITCOIN_TEST_UTIL_WALLET_H
+
+#include <string>
+
+class CWallet;
+
+// Constants //
+
+extern const std::string ADDRESS_BCRT1_UNSPENDABLE;
+
+// RPC-like //
+
+/** Import the address to the wallet */
+void importaddress(CWallet& wallet, const std::string& address);
+/** Returns a new address from the wallet */
+std::string getnewaddress(CWallet& w);
+
+
+#endif // BITCOIN_TEST_UTIL_WALLET_H
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
index a5cbae89b4..c45426a631 100644
--- a/src/test/util_tests.cpp
+++ b/src/test/util_tests.cpp
@@ -7,7 +7,7 @@
#include <clientversion.h>
#include <sync.h>
#include <test/util/setup_common.h>
-#include <test/util.h>
+#include <test/util/str.h>
#include <util/moneystr.h>
#include <util/strencodings.h>
#include <util/string.h>
diff --git a/src/util/string.h b/src/util/string.h
index c6fa08e5b3..3db8fc8b98 100644
--- a/src/util/string.h
+++ b/src/util/string.h
@@ -11,6 +11,16 @@
#include <string>
#include <vector>
+NODISCARD inline std::string TrimString(const std::string& str, const std::string& pattern = " \f\n\r\t\v")
+{
+ std::string::size_type front = str.find_first_not_of(pattern);
+ if (front == std::string::npos) {
+ return std::string();
+ }
+ std::string::size_type end = str.find_last_not_of(pattern);
+ return str.substr(front, end - front + 1);
+}
+
/**
* Join a list of items
*
diff --git a/src/util/system.cpp b/src/util/system.cpp
index 563ff6a54b..95458672ed 100644
--- a/src/util/system.cpp
+++ b/src/util/system.cpp
@@ -7,6 +7,7 @@
#include <chainparamsbase.h>
#include <util/strencodings.h>
+#include <util/string.h>
#include <util/translation.h>
@@ -679,16 +680,6 @@ fs::path GetConfigFile(const std::string& confPath)
return AbsPathForConfigVal(fs::path(confPath), false);
}
-static std::string TrimString(const std::string& str, const std::string& pattern)
-{
- std::string::size_type front = str.find_first_not_of(pattern);
- if (front == std::string::npos) {
- return std::string();
- }
- std::string::size_type end = str.find_last_not_of(pattern);
- return str.substr(front, end - front + 1);
-}
-
static bool GetConfigOptions(std::istream& stream, const std::string& filepath, std::string& error, std::vector<std::pair<std::string, std::string>>& options, std::list<SectionInfo>& sections)
{
std::string str, prefix;
diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp
index b4315014cb..be8a71da97 100644
--- a/src/wallet/scriptpubkeyman.cpp
+++ b/src/wallet/scriptpubkeyman.cpp
@@ -14,7 +14,6 @@
bool LegacyScriptPubKeyMan::GetNewDestination(const OutputType type, CTxDestination& dest, std::string& error)
{
error.clear();
- TopUp();
// Generate a new key that is added to wallet
CPubKey new_key;
@@ -1153,8 +1152,6 @@ bool LegacyScriptPubKeyMan::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& key
{
LOCK(cs_wallet);
- TopUp();
-
bool fReturningInternal = fRequestedInternal;
fReturningInternal &= (IsHDEnabled() && m_storage.CanSupportFeature(FEATURE_HD_SPLIT)) || m_storage.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS);
bool use_split_keypool = set_pre_split_keypool.empty();
diff --git a/src/wallet/scriptpubkeyman.h b/src/wallet/scriptpubkeyman.h
index aa5eac3a85..b78494921c 100644
--- a/src/wallet/scriptpubkeyman.h
+++ b/src/wallet/scriptpubkeyman.h
@@ -160,6 +160,10 @@ public:
virtual void KeepDestination(int64_t index, const OutputType& type) {}
virtual void ReturnDestination(int64_t index, bool internal, const CTxDestination& addr) {}
+ /** Fills internal address pool. Use within ScriptPubKeyMan implementations should be used sparingly and only
+ * when something from the address pool is removed, excluding GetNewDestination and GetReservedDestination.
+ * External wallet code is primarily responsible for topping up prior to fetching new addresses
+ */
virtual bool TopUp(unsigned int size = 0) { return false; }
//! Mark unused addresses as being used
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 41a816312a..3954f66267 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -3105,6 +3105,7 @@ bool CWallet::GetNewDestination(const OutputType type, const std::string label,
bool result = false;
auto spk_man = m_spk_man.get();
if (spk_man) {
+ spk_man->TopUp();
result = spk_man->GetNewDestination(type, dest, error);
}
if (result) {
@@ -3118,8 +3119,6 @@ bool CWallet::GetNewChangeDestination(const OutputType type, CTxDestination& des
{
error.clear();
- m_spk_man->TopUp();
-
ReserveDestination reservedest(this, type);
if (!reservedest.GetReservedDestination(dest, true)) {
error = "Error: Keypool ran out, please call keypoolrefill first";
@@ -3297,6 +3296,8 @@ bool ReserveDestination::GetReservedDestination(CTxDestination& dest, bool inter
if (nIndex == -1)
{
+ m_spk_man->TopUp();
+
CKeyPool keypool;
if (!m_spk_man->GetReservedDestination(type, internal, address, nIndex, keypool)) {
return false;
diff --git a/src/warnings.cpp b/src/warnings.cpp
index 35d2033ba8..8df77096f1 100644
--- a/src/warnings.cpp
+++ b/src/warnings.cpp
@@ -38,41 +38,34 @@ void SetfLargeWorkInvalidChainFound(bool flag)
fLargeWorkInvalidChainFound = flag;
}
-std::string GetWarnings(const std::string& strFor)
+std::string GetWarnings(bool verbose)
{
- std::string strStatusBar;
- std::string strGUI;
- const std::string uiAlertSeperator = "<hr />";
+ std::string warnings_concise;
+ std::string warnings_verbose;
+ const std::string warning_separator = "<hr />";
LOCK(cs_warnings);
+ // Pre-release build warning
if (!CLIENT_VERSION_IS_RELEASE) {
- strStatusBar = "This is a pre-release test build - use at your own risk - do not use for mining or merchant applications";
- strGUI = _("This is a pre-release test build - use at your own risk - do not use for mining or merchant applications").translated;
+ warnings_concise = "This is a pre-release test build - use at your own risk - do not use for mining or merchant applications";
+ warnings_verbose = _("This is a pre-release test build - use at your own risk - do not use for mining or merchant applications").translated;
}
// Misc warnings like out of disk space and clock is wrong
- if (strMiscWarning != "")
- {
- strStatusBar = strMiscWarning;
- strGUI += (strGUI.empty() ? "" : uiAlertSeperator) + strMiscWarning;
+ if (strMiscWarning != "") {
+ warnings_concise = strMiscWarning;
+ warnings_verbose += (warnings_verbose.empty() ? "" : warning_separator) + strMiscWarning;
}
- if (fLargeWorkForkFound)
- {
- strStatusBar = "Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.";
- strGUI += (strGUI.empty() ? "" : uiAlertSeperator) + _("Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.").translated;
- }
- else if (fLargeWorkInvalidChainFound)
- {
- strStatusBar = "Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.";
- strGUI += (strGUI.empty() ? "" : uiAlertSeperator) + _("Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.").translated;
+ if (fLargeWorkForkFound) {
+ warnings_concise = "Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.";
+ warnings_verbose += (warnings_verbose.empty() ? "" : warning_separator) + _("Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.").translated;
+ } else if (fLargeWorkInvalidChainFound) {
+ warnings_concise = "Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.";
+ warnings_verbose += (warnings_verbose.empty() ? "" : warning_separator) + _("Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.").translated;
}
- if (strFor == "gui")
- return strGUI;
- else if (strFor == "statusbar")
- return strStatusBar;
- assert(!"GetWarnings(): invalid parameter");
- return "error";
+ if (verbose) return warnings_verbose;
+ else return warnings_concise;
}
diff --git a/src/warnings.h b/src/warnings.h
index e6701ebd9e..58e5e4cd19 100644
--- a/src/warnings.h
+++ b/src/warnings.h
@@ -13,11 +13,11 @@ void SetfLargeWorkForkFound(bool flag);
bool GetfLargeWorkForkFound();
void SetfLargeWorkInvalidChainFound(bool flag);
/** Format a string that describes several potential problems detected by the core.
- * @param[in] strFor can have the following values:
- * - "statusbar": get the most important warning
- * - "gui": get all warnings, translated (where possible) for GUI, separated by <hr />
- * @returns the warning string selected by strFor
+ * @param[in] verbose bool
+ * - if true, get all warnings, translated (where possible), separated by <hr />
+ * - if false, get the most important warning
+ * @returns the warning string
*/
-std::string GetWarnings(const std::string& strFor);
+std::string GetWarnings(bool verbose);
#endif // BITCOIN_WARNINGS_H
diff --git a/test/fuzz/test_runner.py b/test/fuzz/test_runner.py
index 8b503d83bf..bbdd047465 100755
--- a/test/fuzz/test_runner.py
+++ b/test/fuzz/test_runner.py
@@ -15,12 +15,14 @@ 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",
+ "base_encode_decode",
"block",
"block_file_info_deserialize",
"block_filter_deserialize",
"block_header_and_short_txids_deserialize",
"fee_rate_deserialize",
"flat_file_pos_deserialize",
+ "hex",
"integer",
"key_origin_info_deserialize",
"merkle_block_deserialize",