diff options
103 files changed, 479 insertions, 338 deletions
diff --git a/ci/test/00_setup_env_i686_centos.sh b/ci/test/00_setup_env_i686_centos.sh index e8f963c8a9..8a931d44e5 100755 --- a/ci/test/00_setup_env_i686_centos.sh +++ b/ci/test/00_setup_env_i686_centos.sh @@ -12,6 +12,7 @@ export CI_IMAGE_NAME_TAG=quay.io/centos/centos:stream8 export CI_BASE_PACKAGES="gcc-c++ glibc-devel.x86_64 libstdc++-devel.x86_64 glibc-devel.i686 libstdc++-devel.i686 ccache libtool make git python38 python38-pip which patch lbzip2 xz procps-ng dash rsync coreutils bison" export PIP_PACKAGES="pyzmq" export GOAL="install" +export NO_WERROR=1 # GCC 8 export BITCOIN_CONFIG="--enable-zmq --with-gui=qt5 --enable-reduce-exports" export CONFIG_SHELL="/bin/dash" export TEST_RUNNER_ENV="LC_ALL=en_US.UTF-8" diff --git a/ci/test/00_setup_env_native_nowallet_libbitcoinkernel.sh b/ci/test/00_setup_env_native_nowallet_libbitcoinkernel.sh index 08bb5d1eab..06bc2401c5 100755 --- a/ci/test/00_setup_env_native_nowallet_libbitcoinkernel.sh +++ b/ci/test/00_setup_env_native_nowallet_libbitcoinkernel.sh @@ -13,4 +13,5 @@ export PACKAGES="-t buster-backports python3-zmq clang-8 llvm-8 libc++abi-8-dev export APPEND_APT_SOURCES_LIST="deb http://deb.debian.org/debian buster-backports main" export DEP_OPTS="NO_WALLET=1 CC=clang-8 CXX='clang++-8 -stdlib=libc++'" export GOAL="install" +export NO_WERROR=1 export BITCOIN_CONFIG="--enable-reduce-exports CC=clang-8 CXX='clang++-8 -stdlib=libc++' --enable-experimental-util-chainstate --with-experimental-kernel-lib --enable-shared" diff --git a/ci/test/00_setup_env_native_qt5.sh b/ci/test/00_setup_env_native_qt5.sh index 3f39185ae8..5cc0addd33 100755 --- a/ci/test/00_setup_env_native_qt5.sh +++ b/ci/test/00_setup_env_native_qt5.sh @@ -15,6 +15,7 @@ export TEST_RUNNER_EXTRA="--previous-releases --coverage --extended --exclude fe export RUN_UNIT_TESTS_SEQUENTIAL="true" export RUN_UNIT_TESTS="false" export GOAL="install" +export NO_WERROR=1 export DOWNLOAD_PREVIOUS_RELEASES="true" export BITCOIN_CONFIG="--enable-zmq --with-libs=no --with-gui=qt5 --enable-reduce-exports \ --enable-debug CFLAGS=\"-g0 -O2 -funsigned-char\" CXXFLAGS=\"-g0 -O2 -funsigned-char\" CC=gcc-8 CXX=g++-8" diff --git a/ci/test/01_base_install.sh b/ci/test/01_base_install.sh new file mode 100755 index 0000000000..c2469d7ca9 --- /dev/null +++ b/ci/test/01_base_install.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2018-2022 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 + +CI_EXEC_ROOT () { bash -c "$*"; } +export -f CI_EXEC_ROOT + +if [ -n "$DPKG_ADD_ARCH" ]; then + CI_EXEC_ROOT dpkg --add-architecture "$DPKG_ADD_ARCH" +fi + +if [[ $CI_IMAGE_NAME_TAG == *centos* ]]; then + ${CI_RETRY_EXE} CI_EXEC_ROOT dnf -y install epel-release + ${CI_RETRY_EXE} CI_EXEC_ROOT dnf -y --allowerasing install "$CI_BASE_PACKAGES" "$PACKAGES" +elif [ "$CI_USE_APT_INSTALL" != "no" ]; then + if [[ "${ADD_UNTRUSTED_BPFCC_PPA}" == "true" ]]; then + # Ubuntu 22.04 LTS and Debian 11 both have an outdated bpfcc-tools packages. + # The iovisor PPA is outdated as well. The next Ubuntu and Debian releases will contain updated + # packages. Meanwhile, use an untrusted PPA to install an up-to-date version of the bpfcc-tools + # package. + # TODO: drop this once we can use newer images in GCE + CI_EXEC_ROOT add-apt-repository ppa:hadret/bpfcc + fi + if [[ -n "${APPEND_APT_SOURCES_LIST}" ]]; then + CI_EXEC_ROOT echo "${APPEND_APT_SOURCES_LIST}" \>\> /etc/apt/sources.list + fi + ${CI_RETRY_EXE} CI_EXEC_ROOT apt-get update + ${CI_RETRY_EXE} CI_EXEC_ROOT apt-get install --no-install-recommends --no-upgrade -y "$PACKAGES" "$CI_BASE_PACKAGES" +fi diff --git a/ci/test/04_install.sh b/ci/test/04_install.sh index 53fe6d961f..05bef79a3d 100755 --- a/ci/test/04_install.sh +++ b/ci/test/04_install.sh @@ -33,7 +33,12 @@ if [ -z "$DANGER_RUN_CI_ON_HOST" ]; then # the name isn't important, so long as we use the same UID LOCAL_USER=nonroot - ${CI_RETRY_EXE} docker pull "$CI_IMAGE_NAME_TAG" + DOCKER_BUILDKIT=1 ${CI_RETRY_EXE} docker build \ + --file "${BASE_ROOT_DIR}/ci/test_imagefile" \ + --build-arg "CI_IMAGE_NAME_TAG=${CI_IMAGE_NAME_TAG}" \ + --build-arg "FILE_ENV=${FILE_ENV}" \ + --tag="${CONTAINER_NAME}" \ + "${BASE_ROOT_DIR}" if [ -n "${RESTART_CI_DOCKER_BEFORE_RUN}" ] ; then echo "Restart docker before run to stop and clear all containers started with --rm" @@ -49,7 +54,7 @@ if [ -z "$DANGER_RUN_CI_ON_HOST" ]; then -w $BASE_ROOT_DIR \ --env-file /tmp/env \ --name $CONTAINER_NAME \ - $CI_IMAGE_NAME_TAG) + $CONTAINER_NAME) export CI_CONTAINER_ID # Create a non-root user inside the container which matches the local user. @@ -63,6 +68,7 @@ if [ -z "$DANGER_RUN_CI_ON_HOST" ]; then export CI_EXEC_CMD_PREFIX="docker exec -u $LOCAL_UID $CI_CONTAINER_ID" else echo "Running on host system without docker wrapper" + "${BASE_ROOT_DIR}/ci/test/01_base_install.sh" fi CI_EXEC () { @@ -76,29 +82,6 @@ export -f CI_EXEC_ROOT CI_EXEC mkdir -p "${BINS_SCRATCH_DIR}" -if [ -n "$DPKG_ADD_ARCH" ]; then - CI_EXEC_ROOT dpkg --add-architecture "$DPKG_ADD_ARCH" -fi - -if [[ $CI_IMAGE_NAME_TAG == *centos* ]]; then - ${CI_RETRY_EXE} CI_EXEC_ROOT dnf -y install epel-release - ${CI_RETRY_EXE} CI_EXEC_ROOT dnf -y --allowerasing install "$CI_BASE_PACKAGES" "$PACKAGES" -elif [ "$CI_USE_APT_INSTALL" != "no" ]; then - if [[ "${ADD_UNTRUSTED_BPFCC_PPA}" == "true" ]]; then - # Ubuntu 22.04 LTS and Debian 11 both have an outdated bpfcc-tools packages. - # The iovisor PPA is outdated as well. The next Ubuntu and Debian releases will contain updated - # packages. Meanwhile, use an untrusted PPA to install an up-to-date version of the bpfcc-tools - # package. - # TODO: drop this once we can use newer images in GCE - CI_EXEC_ROOT add-apt-repository ppa:hadret/bpfcc - fi - if [[ -n "${APPEND_APT_SOURCES_LIST}" ]]; then - CI_EXEC_ROOT echo "${APPEND_APT_SOURCES_LIST}" \>\> /etc/apt/sources.list - fi - ${CI_RETRY_EXE} CI_EXEC_ROOT apt-get update - ${CI_RETRY_EXE} CI_EXEC_ROOT apt-get install --no-install-recommends --no-upgrade -y "$PACKAGES" "$CI_BASE_PACKAGES" -fi - if [ -n "$PIP_PACKAGES" ]; then if [ "$CI_OS_NAME" == "macos" ]; then sudo -H pip3 install --upgrade pip diff --git a/ci/test/06_script_b.sh b/ci/test/06_script_b.sh index f94af0cd79..49cc48aa15 100755 --- a/ci/test/06_script_b.sh +++ b/ci/test/06_script_b.sh @@ -9,12 +9,14 @@ export LC_ALL=C.UTF-8 if [[ $HOST = *-mingw32 ]]; then # Generate all binaries, so that they can be wrapped CI_EXEC make "$MAKEJOBS" -C src/secp256k1 VERBOSE=1 + CI_EXEC make "$MAKEJOBS" -C src minisketch/test.exe VERBOSE=1 CI_EXEC "${BASE_ROOT_DIR}/ci/test/wrap-wine.sh" fi if [ -n "$QEMU_USER_CMD" ]; then # Generate all binaries, so that they can be wrapped CI_EXEC make "$MAKEJOBS" -C src/secp256k1 VERBOSE=1 + CI_EXEC make "$MAKEJOBS" -C src minisketch/test VERBOSE=1 CI_EXEC "${BASE_ROOT_DIR}/ci/test/wrap-qemu.sh" fi @@ -73,7 +75,12 @@ if [ "${RUN_TIDY}" = "true" ]; then " src/util/syserror.cpp"\ " src/util/threadinterrupt.cpp"\ " src/zmq"\ - " -p . ${MAKEJOBS} -- -Xiwyu --cxx17ns -Xiwyu --mapping_file=${BASE_BUILD_DIR}/bitcoin-$HOST/contrib/devtools/iwyu/bitcoin.core.imp" + " -p . ${MAKEJOBS}"\ + " -- -Xiwyu --cxx17ns -Xiwyu --mapping_file=${BASE_BUILD_DIR}/bitcoin-$HOST/contrib/devtools/iwyu/bitcoin.core.imp"\ + " |& tee /tmp/iwyu_ci.out" + export P_CI_DIR="${BASE_ROOT_DIR}/src" + CI_EXEC "python3 ${DIR_IWYU}/include-what-you-use/fix_includes.py --nosafe_headers < /tmp/iwyu_ci.out" + CI_EXEC "git --no-pager diff" fi if [ "$RUN_SECURITY_TESTS" = "true" ]; then diff --git a/ci/test_imagefile b/ci/test_imagefile new file mode 100644 index 0000000000..4854708d1a --- /dev/null +++ b/ci/test_imagefile @@ -0,0 +1,10 @@ +ARG CI_IMAGE_NAME_TAG +FROM ${CI_IMAGE_NAME_TAG} + +ARG FILE_ENV +ENV FILE_ENV=${FILE_ENV} + +COPY ./ci/retry/retry /usr/bin/retry +COPY ./ci/test/00_setup_env.sh ./${FILE_ENV} ./ci/test/01_base_install.sh /ci_base_install/ci/test/ + +RUN ["bash", "-c", "cd /ci_base_install/ && set -o errexit && source ./ci/test/00_setup_env.sh && ./ci/test/01_base_install.sh"] diff --git a/configure.ac b/configure.ac index e8414a48ba..aa1a45c527 100644 --- a/configure.ac +++ b/configure.ac @@ -1467,9 +1467,11 @@ if test "$use_boost" = "yes"; then BOOST_CPPFLAGS="$BOOST_CPPFLAGS -DBOOST_MULTI_INDEX_DISABLE_SERIALIZATION" dnl Prevent use of std::unary_function, which was removed in C++17, - dnl and will generate warnings with newer compilers. - dnl See: https://github.com/boostorg/container_hash/issues/22. - BOOST_CPPFLAGS="$BOOST_CPPFLAGS -DBOOST_NO_CXX98_FUNCTION_BASE" + dnl and will generate warnings with newer compilers for Boost + dnl older than 1.80. + dnl See: https://github.com/boostorg/config/pull/430. + AX_CHECK_PREPROC_FLAG([-DBOOST_NO_CXX98_FUNCTION_BASE], [BOOST_CPPFLAGS="$BOOST_CPPFLAGS -DBOOST_NO_CXX98_FUNCTION_BASE"], [], [$CXXFLAG_WERROR], + [AC_LANG_PROGRAM([[#include <boost/config.hpp>]])]) if test "$enable_debug" = "yes" || test "$enable_fuzz" = "yes"; then BOOST_CPPFLAGS="$BOOST_CPPFLAGS -DBOOST_MULTI_INDEX_ENABLE_SAFE_MODE" diff --git a/doc/reduce-memory.md b/doc/reduce-memory.md index 097cc9f001..25205258b8 100644 --- a/doc/reduce-memory.md +++ b/doc/reduce-memory.md @@ -18,7 +18,7 @@ The size of some in-memory caches can be reduced. As caches trade off memory usa - Since `0.14.0`, unused memory allocated to the mempool (default: 300MB) is shared with the UTXO cache, so when trying to reduce memory usage you should limit the mempool, with the `-maxmempool` command line argument. -- To disable most of the mempool functionality there is the `-blocksonly` option. This will reduce the default memory usage to 5MB and make the client opt out of receiving (and thus relaying) transactions, except from whitelisted peers and as part of blocks. +- To disable most of the mempool functionality there is the `-blocksonly` option. This will reduce the default memory usage to 5MB and make the client opt out of receiving (and thus relaying) transactions, except from peers who have the `relay` permission set (e.g. whitelisted peers), and as part of blocks. - Do not use this when using the client to broadcast transactions as any transaction sent will stick out like a sore thumb, affecting privacy. When used with the wallet it should be combined with `-walletbroadcast=0` and `-spendzeroconfchange=0`. Another mechanism for broadcasting outgoing transactions (if any) should be used. diff --git a/src/.clang-tidy b/src/.clang-tidy index b2e6914548..b2c1b49588 100644 --- a/src/.clang-tidy +++ b/src/.clang-tidy @@ -9,6 +9,7 @@ performance-for-range-copy, performance-move-const-arg, performance-no-automatic-move, performance-unnecessary-copy-initialization, +readability-const-return-type, readability-redundant-declaration, readability-redundant-string-init, ' @@ -16,4 +17,4 @@ WarningsAsErrors: '*' CheckOptions: - key: performance-move-const-arg.CheckTriviallyCopyableMove value: false -HeaderFilterRegex: './qt' +HeaderFilterRegex: '.' diff --git a/src/Makefile.am b/src/Makefile.am index 35b0ad24c3..5830090ada 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -20,6 +20,7 @@ noinst_LTLIBRARIES = bin_PROGRAMS = noinst_PROGRAMS = +check_PROGRAMS = TESTS = BENCHMARKS = diff --git a/src/Makefile.minisketch.include b/src/Makefile.minisketch.include index b337f48349..1363bec34e 100644 --- a/src/Makefile.minisketch.include +++ b/src/Makefile.minisketch.include @@ -31,7 +31,7 @@ if ENABLE_TESTS if !ENABLE_FUZZ MINISKETCH_TEST = minisketch/test TESTS += $(MINISKETCH_TEST) -noinst_PROGRAMS += $(MINISKETCH_TEST) +check_PROGRAMS += $(MINISKETCH_TEST) minisketch_test_SOURCES = $(MINISKETCH_TEST_SOURCES_INT) minisketch_test_CPPFLAGS = $(AM_CPPFLAGS) $(LIBMINISKETCH_CPPFLAGS) diff --git a/src/Makefile.test_util.include b/src/Makefile.test_util.include index a4e8b3f842..8496b3698a 100644 --- a/src/Makefile.test_util.include +++ b/src/Makefile.test_util.include @@ -10,6 +10,7 @@ EXTRA_LIBRARIES += \ TEST_UTIL_H = \ test/util/blockfilter.h \ test/util/chainstate.h \ + test/util/json.h \ test/util/logging.h \ test/util/mining.h \ test/util/net.h \ @@ -28,6 +29,7 @@ libtest_util_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BOOST_CPPFLAGS) libtest_util_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libtest_util_a_SOURCES = \ test/util/blockfilter.cpp \ + test/util/json.cpp \ test/util/logging.cpp \ test/util/mining.cpp \ test/util/net.cpp \ diff --git a/src/addrdb.cpp b/src/addrdb.cpp index 7c954dbf3a..7be13c8f1e 100644 --- a/src/addrdb.cpp +++ b/src/addrdb.cpp @@ -190,7 +190,7 @@ std::optional<bilingual_str> LoadAddrman(const NetGroupManager& netgroupman, con const auto path_addr{args.GetDataDirNet() / "peers.dat"}; try { DeserializeFileDB(path_addr, *addrman, CLIENT_VERSION); - LogPrintf("Loaded %i addresses from peers.dat %dms\n", addrman->size(), Ticks<std::chrono::milliseconds>(SteadyClock::now() - start)); + LogPrintf("Loaded %i addresses from peers.dat %dms\n", addrman->Size(), Ticks<std::chrono::milliseconds>(SteadyClock::now() - start)); } catch (const DbNotFoundError&) { // Addrman can be in an inconsistent state after failure, reset it addrman = std::make_unique<AddrMan>(netgroupman, /*deterministic=*/false, /*consistency_check_ratio=*/check_addrman); diff --git a/src/addrman.cpp b/src/addrman.cpp index f86bdfa3df..a740760faf 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -291,6 +291,7 @@ void AddrManImpl::Unserialize(Stream& s_) mapAddr[info] = n; info.nRandomPos = vRandom.size(); vRandom.push_back(n); + m_network_counts[info.GetNetwork()].n_new++; } nIdCount = nNew; @@ -310,6 +311,7 @@ void AddrManImpl::Unserialize(Stream& s_) mapAddr[info] = nIdCount; vvTried[nKBucket][nKBucketPos] = nIdCount; nIdCount++; + m_network_counts[info.GetNetwork()].n_tried++; } else { nLost++; } @@ -425,6 +427,8 @@ AddrInfo* AddrManImpl::Create(const CAddress& addr, const CNetAddr& addrSource, mapAddr[addr] = nId; mapInfo[nId].nRandomPos = vRandom.size(); vRandom.push_back(nId); + nNew++; + m_network_counts[addr.GetNetwork()].n_new++; if (pnId) *pnId = nId; return &mapInfo[nId]; @@ -464,6 +468,7 @@ void AddrManImpl::Delete(int nId) assert(info.nRefCount == 0); SwapRandom(info.nRandomPos, vRandom.size() - 1); + m_network_counts[info.GetNetwork()].n_new--; vRandom.pop_back(); mapAddr.erase(info); mapInfo.erase(nId); @@ -504,6 +509,7 @@ void AddrManImpl::MakeTried(AddrInfo& info, int nId) } } nNew--; + m_network_counts[info.GetNetwork()].n_new--; assert(info.nRefCount == 0); @@ -522,6 +528,7 @@ void AddrManImpl::MakeTried(AddrInfo& info, int nId) infoOld.fInTried = false; vvTried[nKBucket][nKBucketPos] = -1; nTried--; + m_network_counts[infoOld.GetNetwork()].n_tried--; // find which new bucket it belongs to int nUBucket = infoOld.GetNewBucket(nKey, m_netgroupman); @@ -533,6 +540,7 @@ void AddrManImpl::MakeTried(AddrInfo& info, int nId) infoOld.nRefCount = 1; vvNew[nUBucket][nUBucketPos] = nIdEvict; nNew++; + m_network_counts[infoOld.GetNetwork()].n_new++; LogPrint(BCLog::ADDRMAN, "Moved %s from tried[%i][%i] to new[%i][%i] to make space\n", infoOld.ToString(), nKBucket, nKBucketPos, nUBucket, nUBucketPos); } @@ -541,6 +549,7 @@ void AddrManImpl::MakeTried(AddrInfo& info, int nId) vvTried[nKBucket][nKBucketPos] = nId; nTried++; info.fInTried = true; + m_network_counts[info.GetNetwork()].n_tried++; } bool AddrManImpl::AddSingle(const CAddress& addr, const CNetAddr& source, std::chrono::seconds time_penalty) @@ -591,7 +600,6 @@ bool AddrManImpl::AddSingle(const CAddress& addr, const CNetAddr& source, std::c } else { pinfo = Create(addr, source, &nId); pinfo->nTime = std::max(NodeSeconds{0s}, pinfo->nTime - time_penalty); - nNew++; } int nUBucket = pinfo->GetNewBucket(nKey, source, m_netgroupman); @@ -962,6 +970,28 @@ std::optional<AddressPosition> AddrManImpl::FindAddressEntry_(const CAddress& ad } } +size_t AddrManImpl::Size_(std::optional<Network> net, std::optional<bool> in_new) const +{ + AssertLockHeld(cs); + + if (!net.has_value()) { + if (in_new.has_value()) { + return *in_new ? nNew : nTried; + } else { + return vRandom.size(); + } + } + if (auto it = m_network_counts.find(*net); it != m_network_counts.end()) { + auto net_count = it->second; + if (in_new.has_value()) { + return *in_new ? net_count.n_new : net_count.n_tried; + } else { + return net_count.n_new + net_count.n_tried; + } + } + return 0; +} + void AddrManImpl::Check() const { AssertLockHeld(cs); @@ -986,6 +1016,7 @@ int AddrManImpl::CheckAddrman() const std::unordered_set<int> setTried; std::unordered_map<int, int> mapNew; + std::unordered_map<Network, NewTriedCount> local_counts; if (vRandom.size() != (size_t)(nTried + nNew)) return -7; @@ -1000,12 +1031,14 @@ int AddrManImpl::CheckAddrman() const if (info.nRefCount) return -2; setTried.insert(n); + local_counts[info.GetNetwork()].n_tried++; } else { if (info.nRefCount < 0 || info.nRefCount > ADDRMAN_NEW_BUCKETS_PER_ADDRESS) return -3; if (!info.nRefCount) return -4; mapNew[n] = info.nRefCount; + local_counts[info.GetNetwork()].n_new++; } const auto it{mapAddr.find(info)}; if (it == mapAddr.end() || it->second != n) { @@ -1065,13 +1098,27 @@ int AddrManImpl::CheckAddrman() const if (nKey.IsNull()) return -16; + // It's possible that m_network_counts may have all-zero entries that local_counts + // doesn't have if addrs from a network were being added and then removed again in the past. + if (m_network_counts.size() < local_counts.size()) { + return -20; + } + for (const auto& [net, count] : m_network_counts) { + if (local_counts[net].n_new != count.n_new || local_counts[net].n_tried != count.n_tried) { + return -21; + } + } + return 0; } -size_t AddrManImpl::size() const +size_t AddrManImpl::Size(std::optional<Network> net, std::optional<bool> in_new) const { - LOCK(cs); // TODO: Cache this in an atomic to avoid this overhead - return vRandom.size(); + LOCK(cs); + Check(); + auto ret = Size_(net, in_new); + Check(); + return ret; } bool AddrManImpl::Add(const std::vector<CAddress>& vAddr, const CNetAddr& source, std::chrono::seconds time_penalty) @@ -1185,9 +1232,9 @@ template void AddrMan::Unserialize(CHashVerifier<CAutoFile>& s); template void AddrMan::Unserialize(CDataStream& s); template void AddrMan::Unserialize(CHashVerifier<CDataStream>& s); -size_t AddrMan::size() const +size_t AddrMan::Size(std::optional<Network> net, std::optional<bool> in_new) const { - return m_impl->size(); + return m_impl->Size(net, in_new); } bool AddrMan::Add(const std::vector<CAddress>& vAddr, const CNetAddr& source, std::chrono::seconds time_penalty) diff --git a/src/addrman.h b/src/addrman.h index 0f1f808fa1..4985fc764c 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -99,8 +99,14 @@ public: template <typename Stream> void Unserialize(Stream& s_); - //! Return the number of (unique) addresses in all tables. - size_t size() const; + /** + * Return size information about addrman. + * + * @param[in] net Select addresses only from specified network (nullopt = all) + * @param[in] in_new Select addresses only from one table (true = new, false = tried, nullopt = both) + * @return Number of unique addresses that match specified options. + */ + size_t Size(std::optional<Network> net = std::nullopt, std::optional<bool> in_new = std::nullopt) const; /** * Attempt to add one or more addresses to addrman's new table. diff --git a/src/addrman_impl.h b/src/addrman_impl.h index 39754b673e..94fe81aca9 100644 --- a/src/addrman_impl.h +++ b/src/addrman_impl.h @@ -112,7 +112,7 @@ public: template <typename Stream> void Unserialize(Stream& s_) EXCLUSIVE_LOCKS_REQUIRED(!cs); - size_t size() const EXCLUSIVE_LOCKS_REQUIRED(!cs); + size_t Size(std::optional<Network> net, std::optional<bool> in_new) const EXCLUSIVE_LOCKS_REQUIRED(!cs); bool Add(const std::vector<CAddress>& vAddr, const CNetAddr& source, std::chrono::seconds time_penalty) EXCLUSIVE_LOCKS_REQUIRED(!cs); @@ -215,6 +215,14 @@ private: /** Reference to the netgroup manager. netgroupman must be constructed before addrman and destructed after. */ const NetGroupManager& m_netgroupman; + struct NewTriedCount { + size_t n_new; + size_t n_tried; + }; + + /** Number of entries in addrman per network and new/tried table. */ + std::unordered_map<Network, NewTriedCount> m_network_counts GUARDED_BY(cs); + //! Find an entry. AddrInfo* Find(const CService& addr, int* pnId = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs); @@ -257,6 +265,8 @@ private: std::optional<AddressPosition> FindAddressEntry_(const CAddress& addr) EXCLUSIVE_LOCKS_REQUIRED(cs); + size_t Size_(std::optional<Network> net, std::optional<bool> in_new) const EXCLUSIVE_LOCKS_REQUIRED(cs); + //! Consistency check, taking into account m_consistency_check_ratio. //! Will std::abort if an inconsistency is detected. void Check() const EXCLUSIVE_LOCKS_REQUIRED(cs); diff --git a/src/arith_uint256.h b/src/arith_uint256.h index a6065dd9bd..c710fe9471 100644 --- a/src/arith_uint256.h +++ b/src/arith_uint256.h @@ -58,7 +58,7 @@ public: explicit base_uint(const std::string& str); - const base_uint operator~() const + base_uint operator~() const { base_uint ret; for (int i = 0; i < WIDTH; i++) @@ -66,7 +66,7 @@ public: return ret; } - const base_uint operator-() const + base_uint operator-() const { base_uint ret; for (int i = 0; i < WIDTH; i++) @@ -171,7 +171,7 @@ public: return *this; } - const base_uint operator++(int) + base_uint operator++(int) { // postfix operator const base_uint ret = *this; @@ -188,7 +188,7 @@ public: return *this; } - const base_uint operator--(int) + base_uint operator--(int) { // postfix operator const base_uint ret = *this; @@ -199,16 +199,16 @@ public: int CompareTo(const base_uint& b) const; bool EqualTo(uint64_t b) const; - friend inline const base_uint operator+(const base_uint& a, const base_uint& b) { return base_uint(a) += b; } - friend inline const base_uint operator-(const base_uint& a, const base_uint& b) { return base_uint(a) -= b; } - friend inline const base_uint operator*(const base_uint& a, const base_uint& b) { return base_uint(a) *= b; } - friend inline const base_uint operator/(const base_uint& a, const base_uint& b) { return base_uint(a) /= b; } - friend inline const base_uint operator|(const base_uint& a, const base_uint& b) { return base_uint(a) |= b; } - friend inline const base_uint operator&(const base_uint& a, const base_uint& b) { return base_uint(a) &= b; } - friend inline const base_uint operator^(const base_uint& a, const base_uint& b) { return base_uint(a) ^= b; } - friend inline const base_uint operator>>(const base_uint& a, int shift) { return base_uint(a) >>= shift; } - friend inline const base_uint operator<<(const base_uint& a, int shift) { return base_uint(a) <<= shift; } - friend inline const base_uint operator*(const base_uint& a, uint32_t b) { return base_uint(a) *= b; } + friend inline base_uint operator+(const base_uint& a, const base_uint& b) { return base_uint(a) += b; } + friend inline base_uint operator-(const base_uint& a, const base_uint& b) { return base_uint(a) -= b; } + friend inline base_uint operator*(const base_uint& a, const base_uint& b) { return base_uint(a) *= b; } + friend inline base_uint operator/(const base_uint& a, const base_uint& b) { return base_uint(a) /= b; } + friend inline base_uint operator|(const base_uint& a, const base_uint& b) { return base_uint(a) |= b; } + friend inline base_uint operator&(const base_uint& a, const base_uint& b) { return base_uint(a) &= b; } + friend inline base_uint operator^(const base_uint& a, const base_uint& b) { return base_uint(a) ^= b; } + friend inline base_uint operator>>(const base_uint& a, int shift) { return base_uint(a) >>= shift; } + friend inline base_uint operator<<(const base_uint& a, int shift) { return base_uint(a) <<= shift; } + friend inline base_uint operator*(const base_uint& a, uint32_t b) { return base_uint(a) *= b; } friend inline bool operator==(const base_uint& a, const base_uint& b) { return memcmp(a.pn, b.pn, sizeof(a.pn)) == 0; } friend inline bool operator!=(const base_uint& a, const base_uint& b) { return memcmp(a.pn, b.pn, sizeof(a.pn)) != 0; } friend inline bool operator>(const base_uint& a, const base_uint& b) { return a.CompareTo(b) > 0; } diff --git a/src/bench/gcs_filter.cpp b/src/bench/gcs_filter.cpp index 51fbe15760..0af4ee98fe 100644 --- a/src/bench/gcs_filter.cpp +++ b/src/bench/gcs_filter.cpp @@ -5,7 +5,7 @@ #include <bench/bench.h> #include <blockfilter.h> -static const GCSFilter::ElementSet GenerateGCSTestElements() +static GCSFilter::ElementSet GenerateGCSTestElements() { GCSFilter::ElementSet elements; diff --git a/src/bench/wallet_loading.cpp b/src/bench/wallet_loading.cpp index 2f7dc53b0c..6b09adcc9d 100644 --- a/src/bench/wallet_loading.cpp +++ b/src/bench/wallet_loading.cpp @@ -24,7 +24,7 @@ using wallet::WALLET_FLAG_DESCRIPTORS; using wallet::WalletContext; using wallet::WalletDatabase; -static const std::shared_ptr<CWallet> BenchLoadWallet(std::unique_ptr<WalletDatabase> database, WalletContext& context, DatabaseOptions& options) +static std::shared_ptr<CWallet> BenchLoadWallet(std::unique_ptr<WalletDatabase> database, WalletContext& context, DatabaseOptions& options) { bilingual_str error; std::vector<bilingual_str> warnings; diff --git a/src/blockfilter.cpp b/src/blockfilter.cpp index fc6dde20f9..88c7526b9e 100644 --- a/src/blockfilter.cpp +++ b/src/blockfilter.cpp @@ -247,21 +247,10 @@ bool BlockFilter::BuildParams(GCSFilter::Params& params) const uint256 BlockFilter::GetHash() const { - const std::vector<unsigned char>& data = GetEncodedFilter(); - - uint256 result; - CHash256().Write(data).Finalize(result); - return result; + return Hash(GetEncodedFilter()); } uint256 BlockFilter::ComputeHeader(const uint256& prev_header) const { - const uint256& filter_hash = GetHash(); - - uint256 result; - CHash256() - .Write(filter_hash) - .Write(prev_header) - .Finalize(result); - return result; + return Hash(GetHash(), prev_header); } diff --git a/src/coins.cpp b/src/coins.cpp index 31ac67674a..e98bf816ab 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -32,7 +32,7 @@ bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, std::unique_ptr<CCoinsViewCursor> CCoinsViewBacked::Cursor() const { return base->Cursor(); } size_t CCoinsViewBacked::EstimateSize() const { return base->EstimateSize(); } -CCoinsViewCache::CCoinsViewCache(CCoinsView *baseIn) : CCoinsViewBacked(baseIn), cachedCoinsUsage(0) {} +CCoinsViewCache::CCoinsViewCache(CCoinsView* baseIn) : CCoinsViewBacked(baseIn) {} size_t CCoinsViewCache::DynamicMemoryUsage() const { return memusage::DynamicUsage(cacheCoins) + cachedCoinsUsage; diff --git a/src/coins.h b/src/coins.h index 4edc146a14..710b8c7c83 100644 --- a/src/coins.h +++ b/src/coins.h @@ -220,7 +220,7 @@ protected: mutable CCoinsMap cacheCoins; /* Cached dynamic memory usage for the inner Coin objects. */ - mutable size_t cachedCoinsUsage; + mutable size_t cachedCoinsUsage{0}; public: CCoinsViewCache(CCoinsView *baseIn); diff --git a/src/core_write.cpp b/src/core_write.cpp index 91a6eb2864..300bd30e43 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -170,6 +170,8 @@ void ScriptToUniv(const CScript& script, UniValue& out, bool include_hex, bool i void TxToUniv(const CTransaction& tx, const uint256& block_hash, UniValue& entry, bool include_hex, int serialize_flags, const CTxUndo* txundo, TxVerbosity verbosity) { + CHECK_NONFATAL(verbosity >= TxVerbosity::SHOW_DETAILS); + entry.pushKV("txid", tx.GetHash().GetHex()); entry.pushKV("hash", tx.GetWitnessHash().GetHex()); // Transaction version is actually unsigned in consensus checks, just signed in memory, diff --git a/src/crypto/ripemd160.cpp b/src/crypto/ripemd160.cpp index 29a4ad906f..a2f7c6e156 100644 --- a/src/crypto/ripemd160.cpp +++ b/src/crypto/ripemd160.cpp @@ -239,7 +239,7 @@ void Transform(uint32_t* s, const unsigned char* chunk) ////// RIPEMD160 -CRIPEMD160::CRIPEMD160() : bytes(0) +CRIPEMD160::CRIPEMD160() { ripemd160::Initialize(s); } diff --git a/src/crypto/ripemd160.h b/src/crypto/ripemd160.h index ae9c339181..fb631a66d2 100644 --- a/src/crypto/ripemd160.h +++ b/src/crypto/ripemd160.h @@ -14,7 +14,7 @@ class CRIPEMD160 private: uint32_t s[5]; unsigned char buf[64]; - uint64_t bytes; + uint64_t bytes{0}; public: static const size_t OUTPUT_SIZE = 20; diff --git a/src/crypto/sha1.cpp b/src/crypto/sha1.cpp index 1fb9bb2b72..2610108f60 100644 --- a/src/crypto/sha1.cpp +++ b/src/crypto/sha1.cpp @@ -146,7 +146,7 @@ void Transform(uint32_t* s, const unsigned char* chunk) ////// SHA1 -CSHA1::CSHA1() : bytes(0) +CSHA1::CSHA1() { sha1::Initialize(s); } diff --git a/src/crypto/sha1.h b/src/crypto/sha1.h index 4bd6c331a8..741cdaad58 100644 --- a/src/crypto/sha1.h +++ b/src/crypto/sha1.h @@ -14,7 +14,7 @@ class CSHA1 private: uint32_t s[5]; unsigned char buf[64]; - uint64_t bytes; + uint64_t bytes{0}; public: static const size_t OUTPUT_SIZE = 20; diff --git a/src/crypto/sha256.cpp b/src/crypto/sha256.cpp index 7cd5b3661b..a4eef36480 100644 --- a/src/crypto/sha256.cpp +++ b/src/crypto/sha256.cpp @@ -673,7 +673,7 @@ std::string SHA256AutoDetect() ////// SHA-256 -CSHA256::CSHA256() : bytes(0) +CSHA256::CSHA256() { sha256::Initialize(s); } diff --git a/src/crypto/sha256.h b/src/crypto/sha256.h index 9fd73becfd..7625508665 100644 --- a/src/crypto/sha256.h +++ b/src/crypto/sha256.h @@ -15,7 +15,7 @@ class CSHA256 private: uint32_t s[8]; unsigned char buf[64]; - uint64_t bytes; + uint64_t bytes{0}; public: static const size_t OUTPUT_SIZE = 32; diff --git a/src/crypto/sha512.cpp b/src/crypto/sha512.cpp index 8a822e0e7e..2713f06210 100644 --- a/src/crypto/sha512.cpp +++ b/src/crypto/sha512.cpp @@ -151,7 +151,7 @@ void Transform(uint64_t* s, const unsigned char* chunk) ////// SHA-512 -CSHA512::CSHA512() : bytes(0) +CSHA512::CSHA512() { sha512::Initialize(s); } diff --git a/src/crypto/sha512.h b/src/crypto/sha512.h index d8fa8d2e39..d2f7d6a05e 100644 --- a/src/crypto/sha512.h +++ b/src/crypto/sha512.h @@ -14,7 +14,7 @@ class CSHA512 private: uint64_t s[8]; unsigned char buf[128]; - uint64_t bytes; + uint64_t bytes{0}; public: static constexpr size_t OUTPUT_SIZE = 64; diff --git a/src/cuckoocache.h b/src/cuckoocache.h index 6adcc74516..cb0b362143 100644 --- a/src/cuckoocache.h +++ b/src/cuckoocache.h @@ -166,7 +166,7 @@ private: std::vector<Element> table; /** size stores the total available slots in the hash table */ - uint32_t size; + uint32_t size{0}; /** The bit_packed_atomic_flags array is marked mutable because we want * garbage collection to be allowed to occur from const methods */ @@ -183,7 +183,7 @@ private: * decremented on insert and reset to the new number of inserts which would * cause the epoch to reach epoch_size when it reaches zero. */ - uint32_t epoch_heuristic_counter; + uint32_t epoch_heuristic_counter{0}; /** epoch_size is set to be the number of elements supposed to be in a * epoch. When the number of non-erased elements in an epoch @@ -193,12 +193,12 @@ private: * one "dead" which has been erased, one "dying" which has been marked to be * erased next, and one "living" which new inserts add to. */ - uint32_t epoch_size; + uint32_t epoch_size{0}; /** depth_limit determines how many elements insert should try to replace. * Should be set to log2(n). */ - uint8_t depth_limit; + uint8_t depth_limit{0}; /** hash_function is a const instance of the hash function. It cannot be * static or initialized at call time as it may have internal state (such as @@ -322,8 +322,7 @@ public: /** You must always construct a cache with some elements via a subsequent * call to setup or setup_bytes, otherwise operations may segfault. */ - cache() : table(), size(), collection_flags(0), epoch_flags(), - epoch_heuristic_counter(), epoch_size(), depth_limit(0), hash_function() + cache() : table(), collection_flags(0), epoch_flags(), hash_function() { } diff --git a/src/dbwrapper.h b/src/dbwrapper.h index f47bd8188e..b389d039fb 100644 --- a/src/dbwrapper.h +++ b/src/dbwrapper.h @@ -71,13 +71,13 @@ private: DataStream ssKey{}; CDataStream ssValue; - size_t size_estimate; + size_t size_estimate{0}; public: /** * @param[in] _parent CDBWrapper that this batch is to be submitted to */ - explicit CDBBatch(const CDBWrapper& _parent) : parent(_parent), ssValue(SER_DISK, CLIENT_VERSION), size_estimate(0){}; + explicit CDBBatch(const CDBWrapper& _parent) : parent(_parent), ssValue(SER_DISK, CLIENT_VERSION){}; void Clear() { diff --git a/src/external_signer.cpp b/src/external_signer.cpp index 8a3e17a292..5524b943f4 100644 --- a/src/external_signer.cpp +++ b/src/external_signer.cpp @@ -16,7 +16,7 @@ ExternalSigner::ExternalSigner(const std::string& command, const std::string chain, const std::string& fingerprint, const std::string name): m_command(command), m_chain(chain), m_fingerprint(fingerprint), m_name(name) {} -const std::string ExternalSigner::NetworkArg() const +std::string ExternalSigner::NetworkArg() const { return " --chain " + m_chain; } diff --git a/src/external_signer.h b/src/external_signer.h index e40fd7f010..90f07478e3 100644 --- a/src/external_signer.h +++ b/src/external_signer.h @@ -24,7 +24,7 @@ private: //! Bitcoin mainnet, testnet, etc std::string m_chain; - const std::string NetworkArg() const; + std::string NetworkArg() const; public: //! @param[in] command the command which handles interaction with the external signer diff --git a/src/index/blockfilterindex.cpp b/src/index/blockfilterindex.cpp index 07b4cdc06b..59bf6d34cf 100644 --- a/src/index/blockfilterindex.cpp +++ b/src/index/blockfilterindex.cpp @@ -157,9 +157,7 @@ bool BlockFilterIndex::ReadFilterFromDisk(const FlatFilePos& pos, const uint256& std::vector<uint8_t> encoded_filter; try { filein >> block_hash >> encoded_filter; - uint256 result; - CHash256().Write(encoded_filter).Finalize(result); - if (result != hash) return error("Checksum mismatch in filter decode."); + if (Hash(encoded_filter) != hash) return error("Checksum mismatch in filter decode."); filter = BlockFilter(GetFilterType(), block_hash, std::move(encoded_filter), /*skip_decode_check=*/true); } catch (const std::exception& e) { diff --git a/src/kernel/mempool_options.h b/src/kernel/mempool_options.h index a5a0bae86d..beb5fca5e9 100644 --- a/src/kernel/mempool_options.h +++ b/src/kernel/mempool_options.h @@ -18,7 +18,7 @@ class CBlockPolicyEstimator; /** Default for -maxmempool, maximum megabytes of mempool memory usage */ static constexpr unsigned int DEFAULT_MAX_MEMPOOL_SIZE_MB{300}; -//** Default for -maxmempool when blocksonly is set */ +/** Default for -maxmempool when blocksonly is set */ static constexpr unsigned int DEFAULT_BLOCKSONLY_MAX_MEMPOOL_SIZE_MB{5}; /** Default for -mempoolexpiry, expiration time for mempool transactions in hours */ static constexpr unsigned int DEFAULT_MEMPOOL_EXPIRY_HOURS{336}; diff --git a/src/key.cpp b/src/key.cpp index 33913ed461..3a3f0b2bc2 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -245,8 +245,7 @@ bool CKey::VerifyPubKey(const CPubKey& pubkey) const { unsigned char rnd[8]; std::string str = "Bitcoin key verification\n"; GetRandBytes(rnd); - uint256 hash; - CHash256().Write(MakeUCharSpan(str)).Write(rnd).Finalize(hash); + uint256 hash{Hash(str, rnd)}; std::vector<unsigned char> vchSig; Sign(hash, vchSig); return pubkey.Verify(hash, vchSig); @@ -42,10 +42,10 @@ public: private: //! Whether this private key is valid. We check for correctness when modifying the key //! data, so fValid should always correspond to the actual state. - bool fValid; + bool fValid{false}; //! Whether the public key corresponding to this private key is (to be) compressed. - bool fCompressed; + bool fCompressed{false}; //! The actual byte data std::vector<unsigned char, secure_allocator<unsigned char> > keydata; @@ -55,7 +55,7 @@ private: public: //! Construct an invalid private key. - CKey() : fValid(false), fCompressed(false) + CKey() { // Important: vch must be 32 bytes in length to not break serialization keydata.resize(32); diff --git a/src/logging/timer.h b/src/logging/timer.h index ea0821dede..993ba99c25 100644 --- a/src/logging/timer.h +++ b/src/logging/timer.h @@ -12,6 +12,7 @@ #include <util/types.h> #include <chrono> +#include <optional> #include <string> @@ -28,14 +29,14 @@ public: std::string prefix, std::string end_msg, BCLog::LogFlags log_category = BCLog::LogFlags::ALL, - bool msg_on_completion = true) : - m_prefix(std::move(prefix)), - m_title(std::move(end_msg)), - m_log_category(log_category), - m_message_on_completion(msg_on_completion) + bool msg_on_completion = true) + : m_prefix(std::move(prefix)), + m_title(std::move(end_msg)), + m_log_category(log_category), + m_message_on_completion(msg_on_completion) { this->Log(strprintf("%s started", m_title)); - m_start_t = GetTime<std::chrono::microseconds>(); + m_start_t = std::chrono::steady_clock::now(); } ~Timer() @@ -60,24 +61,25 @@ public: std::string LogMsg(const std::string& msg) { - const auto end_time = GetTime<std::chrono::microseconds>() - m_start_t; - if (m_start_t.count() <= 0) { + const auto end_time{std::chrono::steady_clock::now()}; + if (!m_start_t) { return strprintf("%s: %s", m_prefix, msg); } + const auto duration{end_time - *m_start_t}; if constexpr (std::is_same<TimeType, std::chrono::microseconds>::value) { - return strprintf("%s: %s (%iμs)", m_prefix, msg, end_time.count()); + return strprintf("%s: %s (%iμs)", m_prefix, msg, Ticks<std::chrono::microseconds>(duration)); } else if constexpr (std::is_same<TimeType, std::chrono::milliseconds>::value) { - return strprintf("%s: %s (%.2fms)", m_prefix, msg, end_time.count() * 0.001); + return strprintf("%s: %s (%.2fms)", m_prefix, msg, Ticks<MillisecondsDouble>(duration)); } else if constexpr (std::is_same<TimeType, std::chrono::seconds>::value) { - return strprintf("%s: %s (%.2fs)", m_prefix, msg, end_time.count() * 0.000001); + return strprintf("%s: %s (%.2fs)", m_prefix, msg, Ticks<SecondsDouble>(duration)); } else { static_assert(ALWAYS_FALSE<TimeType>, "Error: unexpected time type"); } } private: - std::chrono::microseconds m_start_t{}; + std::optional<std::chrono::steady_clock::time_point> m_start_t{}; //! Log prefix; usually the name of the function this was created in. const std::string m_prefix; diff --git a/src/net.cpp b/src/net.cpp index 960d0ee841..98500bd30e 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1305,15 +1305,14 @@ void CConnman::SocketHandlerConnected(const std::vector<CNode*>& nodes, RecordBytesRecv(nBytes); if (notify) { size_t nSizeAdded = 0; - auto it(pnode->vRecvMsg.begin()); - for (; it != pnode->vRecvMsg.end(); ++it) { + for (const auto& msg : pnode->vRecvMsg) { // vRecvMsg contains only completed CNetMessage // the single possible partially deserialized message are held by TransportDeserializer - nSizeAdded += it->m_raw_message_size; + nSizeAdded += msg.m_raw_message_size; } { LOCK(pnode->cs_vProcessMsg); - pnode->vProcessMsg.splice(pnode->vProcessMsg.end(), pnode->vRecvMsg, pnode->vRecvMsg.begin(), it); + pnode->vProcessMsg.splice(pnode->vProcessMsg.end(), pnode->vRecvMsg); pnode->nProcessQueueSize += nSizeAdded; pnode->fPauseRecv = pnode->nProcessQueueSize > nReceiveFloodSize; } @@ -1399,7 +1398,7 @@ void CConnman::ThreadDNSAddressSeed() if (gArgs.GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED)) { // When -forcednsseed is provided, query all. seeds_right_now = seeds.size(); - } else if (addrman.size() == 0) { + } else if (addrman.Size() == 0) { // If we have no known peers, query all. // This will occur on the first run, or if peers.dat has been // deleted. @@ -1418,13 +1417,13 @@ void CConnman::ThreadDNSAddressSeed() // * If we continue having problems, eventually query all the // DNS seeds, and if that fails too, also try the fixed seeds. // (done in ThreadOpenConnections) - const std::chrono::seconds seeds_wait_time = (addrman.size() >= DNSSEEDS_DELAY_PEER_THRESHOLD ? DNSSEEDS_DELAY_MANY_PEERS : DNSSEEDS_DELAY_FEW_PEERS); + const std::chrono::seconds seeds_wait_time = (addrman.Size() >= DNSSEEDS_DELAY_PEER_THRESHOLD ? DNSSEEDS_DELAY_MANY_PEERS : DNSSEEDS_DELAY_FEW_PEERS); for (const std::string& seed : seeds) { if (seeds_right_now == 0) { seeds_right_now += DNSSEEDS_TO_QUERY_AT_ONCE; - if (addrman.size() > 0) { + if (addrman.Size() > 0) { LogPrintf("Waiting %d seconds before querying DNS seeds.\n", seeds_wait_time.count()); std::chrono::seconds to_wait = seeds_wait_time; while (to_wait.count() > 0) { @@ -1504,7 +1503,7 @@ void CConnman::DumpAddresses() DumpPeerAddresses(::gArgs, addrman); LogPrint(BCLog::NET, "Flushed %d addresses to peers.dat %dms\n", - addrman.size(), Ticks<std::chrono::milliseconds>(SteadyClock::now() - start)); + addrman.Size(), Ticks<std::chrono::milliseconds>(SteadyClock::now() - start)); } void CConnman::ProcessAddrFetch() @@ -1575,6 +1574,19 @@ int CConnman::GetExtraBlockRelayCount() const return std::max(block_relay_peers - m_max_outbound_block_relay, 0); } +std::unordered_set<Network> CConnman::GetReachableEmptyNetworks() const +{ + std::unordered_set<Network> networks{}; + for (int n = 0; n < NET_MAX; n++) { + enum Network net = (enum Network)n; + if (net == NET_UNROUTABLE || net == NET_INTERNAL) continue; + if (IsReachable(net) && addrman.Size(net, std::nullopt) == 0) { + networks.insert(net); + } + } + return networks; +} + void CConnman::ThreadOpenConnections(const std::vector<std::string> connect) { SetSyscallSandboxPolicy(SyscallSandboxPolicy::NET_OPEN_CONNECTION); @@ -1624,7 +1636,8 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect) if (interruptNet) return; - if (add_fixed_seeds && addrman.size() == 0) { + const std::unordered_set<Network> fixed_seed_networks{GetReachableEmptyNetworks()}; + if (add_fixed_seeds && !fixed_seed_networks.empty()) { // When the node starts with an empty peers.dat, there are a few other sources of peers before // we fallback on to fixed seeds: -dnsseed, -seednode, -addnode // If none of those are available, we fallback on to fixed seeds immediately, else we allow @@ -1633,7 +1646,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect) // It is cheapest to check if enough time has passed first. if (GetTime<std::chrono::seconds>() > start + std::chrono::minutes{1}) { add_fixed_seeds_now = true; - LogPrintf("Adding fixed seeds as 60 seconds have passed and addrman is empty\n"); + LogPrintf("Adding fixed seeds as 60 seconds have passed and addrman is empty for at least one reachable network\n"); } // Checking !dnsseed is cheaper before locking 2 mutexes. @@ -1650,14 +1663,12 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect) // We will not make outgoing connections to peers that are unreachable // (e.g. because of -onlynet configuration). // Therefore, we do not add them to addrman in the first place. - // Note that if you change -onlynet setting from one network to another, - // peers.dat will contain only peers of unreachable networks and - // manual intervention will be needed (either delete peers.dat after - // configuration change or manually add some reachable peer using addnode), - // see <https://github.com/bitcoin/bitcoin/issues/26035> for details. + // In case previously unreachable networks become reachable + // (e.g. in case of -onlynet changes by the user), fixed seeds will + // be loaded only for networks for which we have no addressses. seed_addrs.erase(std::remove_if(seed_addrs.begin(), seed_addrs.end(), - [](const CAddress& addr) { return !IsReachable(addr); }), - seed_addrs.end()); + [&fixed_seed_networks](const CAddress& addr) { return fixed_seed_networks.count(addr.GetNetwork()) == 0; }), + seed_addrs.end()); CNetAddr local; local.SetInternal("fixedseeds"); addrman.Add(seed_addrs, local); @@ -39,6 +39,7 @@ #include <memory> #include <optional> #include <thread> +#include <unordered_set> #include <vector> class AddrMan; @@ -970,6 +971,12 @@ private: void RecordBytesSent(uint64_t bytes) EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex); /** + Return reachable networks for which we have no addresses in addrman and therefore + may require loading fixed seeds. + */ + std::unordered_set<Network> GetReachableEmptyNetworks() const; + + /** * Return vector of current BLOCK_RELAY peers. */ std::vector<CAddress> GetCurrentBlockRelayOnlyConns() const; diff --git a/src/policy/fees.cpp b/src/policy/fees.cpp index e4eb932e5c..d244de1bb2 100644 --- a/src/policy/fees.cpp +++ b/src/policy/fees.cpp @@ -528,7 +528,7 @@ bool CBlockPolicyEstimator::_removeTx(const uint256& hash, bool inBlock) } CBlockPolicyEstimator::CBlockPolicyEstimator(const fs::path& estimation_filepath) - : m_estimation_filepath{estimation_filepath}, nBestSeenHeight{0}, firstRecordedHeight{0}, historicalFirst{0}, historicalBest{0}, trackedTxs{0}, untrackedTxs{0} + : m_estimation_filepath{estimation_filepath} { static_assert(MIN_BUCKET_FEERATE > 0, "Min feerate must be nonzero"); size_t bucketIndex = 0; diff --git a/src/policy/fees.h b/src/policy/fees.h index dd4f031180..1c24b8c7c3 100644 --- a/src/policy/fees.h +++ b/src/policy/fees.h @@ -242,16 +242,16 @@ public: private: mutable Mutex m_cs_fee_estimator; - unsigned int nBestSeenHeight GUARDED_BY(m_cs_fee_estimator); - unsigned int firstRecordedHeight GUARDED_BY(m_cs_fee_estimator); - unsigned int historicalFirst GUARDED_BY(m_cs_fee_estimator); - unsigned int historicalBest GUARDED_BY(m_cs_fee_estimator); + unsigned int nBestSeenHeight GUARDED_BY(m_cs_fee_estimator){0}; + unsigned int firstRecordedHeight GUARDED_BY(m_cs_fee_estimator){0}; + unsigned int historicalFirst GUARDED_BY(m_cs_fee_estimator){0}; + unsigned int historicalBest GUARDED_BY(m_cs_fee_estimator){0}; struct TxStatsInfo { - unsigned int blockHeight; - unsigned int bucketIndex; - TxStatsInfo() : blockHeight(0), bucketIndex(0) {} + unsigned int blockHeight{0}; + unsigned int bucketIndex{0}; + TxStatsInfo() {} }; // map of txids to information about that transaction @@ -262,8 +262,8 @@ private: std::unique_ptr<TxConfirmStats> shortStats PT_GUARDED_BY(m_cs_fee_estimator); std::unique_ptr<TxConfirmStats> longStats PT_GUARDED_BY(m_cs_fee_estimator); - unsigned int trackedTxs GUARDED_BY(m_cs_fee_estimator); - unsigned int untrackedTxs GUARDED_BY(m_cs_fee_estimator); + unsigned int trackedTxs GUARDED_BY(m_cs_fee_estimator){0}; + unsigned int untrackedTxs GUARDED_BY(m_cs_fee_estimator){0}; std::vector<double> buckets GUARDED_BY(m_cs_fee_estimator); // The upper-bound of the range for the bucket (inclusive) std::map<double, unsigned int> bucketMap GUARDED_BY(m_cs_fee_estimator); // Map of bucket upper-bound to index into all vectors by bucket diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index cd0a1a19ee..00b7952ca4 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -31,7 +31,7 @@ const char *DEFAULT_GUI_PROXY_HOST = "127.0.0.1"; -static const QString GetDefaultProxyAddress(); +static QString GetDefaultProxyAddress(); /** Map GUI option ID to node setting name. */ static const char* SettingName(OptionsModel::OptionID option) @@ -308,7 +308,7 @@ static std::string ProxyString(bool is_set, QString ip, QString port) return is_set ? QString(ip + ":" + port).toStdString() : ""; } -static const QString GetDefaultProxyAddress() +static QString GetDefaultProxyAddress() { return QString("%1:%2").arg(DEFAULT_GUI_PROXY_HOST).arg(DEFAULT_GUI_PROXY_PORT); } diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index c9caec39cf..3cd5f4061c 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -262,7 +262,6 @@ void OverviewPage::setWalletModel(WalletModel *model) // Set up transaction list filter.reset(new TransactionFilterProxy()); filter->setSourceModel(model->getTransactionTableModel()); - filter->setLimit(NUM_ITEMS); filter->setDynamicSortFilter(true); filter->setSortRole(Qt::EditRole); filter->setShowInactive(false); @@ -271,6 +270,10 @@ void OverviewPage::setWalletModel(WalletModel *model) ui->listTransactions->setModel(filter.get()); ui->listTransactions->setModelColumn(TransactionTableModel::ToAddress); + connect(filter.get(), &TransactionFilterProxy::rowsInserted, this, &OverviewPage::LimitTransactionRows); + connect(filter.get(), &TransactionFilterProxy::rowsRemoved, this, &OverviewPage::LimitTransactionRows); + connect(filter.get(), &TransactionFilterProxy::rowsMoved, this, &OverviewPage::LimitTransactionRows); + LimitTransactionRows(); // Keep up to date with wallet setBalance(model->getCachedBalance()); connect(model, &WalletModel::balanceChanged, this, &OverviewPage::setBalance); @@ -299,6 +302,16 @@ void OverviewPage::changeEvent(QEvent* e) QWidget::changeEvent(e); } +// Only show most recent NUM_ITEMS rows +void OverviewPage::LimitTransactionRows() +{ + if (filter && ui->listTransactions && ui->listTransactions->model() && filter.get() == ui->listTransactions->model()) { + for (int i = 0; i < filter->rowCount(); ++i) { + ui->listTransactions->setRowHidden(i, i >= NUM_ITEMS); + } + } +} + void OverviewPage::updateDisplayUnit() { if (walletModel && walletModel->getOptionsModel()) { diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h index 2ca38b78dd..5c487ee116 100644 --- a/src/qt/overviewpage.h +++ b/src/qt/overviewpage.h @@ -60,6 +60,7 @@ private: std::unique_ptr<TransactionFilterProxy> filter; private Q_SLOTS: + void LimitTransactionRows(); void updateDisplayUnit(); void handleTransactionClicked(const QModelIndex &index); void updateAlerts(const QString &warnings); diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 843cd46d13..b46a3c039b 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -780,8 +780,8 @@ void RPCConsole::addWallet(WalletModel * const walletModel) { // use name for text and wallet model for internal data object (to allow to move to a wallet id later) ui->WalletSelector->addItem(walletModel->getDisplayName(), QVariant::fromValue(walletModel)); - if (ui->WalletSelector->count() == 2 && !isVisible()) { - // First wallet added, set to default so long as the window isn't presently visible (and potentially in use) + if (ui->WalletSelector->count() == 2) { + // First wallet added, set to default to match wallet RPC behavior ui->WalletSelector->setCurrentIndex(1); } if (ui->WalletSelector->count() > 2) { diff --git a/src/qt/transactionfilterproxy.cpp b/src/qt/transactionfilterproxy.cpp index 3cc0cc839d..173fd326a3 100644 --- a/src/qt/transactionfilterproxy.cpp +++ b/src/qt/transactionfilterproxy.cpp @@ -88,25 +88,8 @@ void TransactionFilterProxy::setWatchOnlyFilter(WatchOnlyFilter filter) invalidateFilter(); } -void TransactionFilterProxy::setLimit(int limit) -{ - this->limitRows = limit; -} - void TransactionFilterProxy::setShowInactive(bool _showInactive) { this->showInactive = _showInactive; invalidateFilter(); } - -int TransactionFilterProxy::rowCount(const QModelIndex &parent) const -{ - if(limitRows != -1) - { - return std::min(QSortFilterProxyModel::rowCount(parent), limitRows); - } - else - { - return QSortFilterProxyModel::rowCount(parent); - } -} diff --git a/src/qt/transactionfilterproxy.h b/src/qt/transactionfilterproxy.h index 8e5f72d764..73c4f21426 100644 --- a/src/qt/transactionfilterproxy.h +++ b/src/qt/transactionfilterproxy.h @@ -42,14 +42,9 @@ public: void setMinAmount(const CAmount& minimum); void setWatchOnlyFilter(WatchOnlyFilter filter); - /** Set maximum number of rows returned, -1 if unlimited. */ - void setLimit(int limit); - /** Set whether to show conflicted transactions. */ void setShowInactive(bool showInactive); - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - protected: bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const override; @@ -60,7 +55,6 @@ private: quint32 typeFilter; WatchOnlyFilter watchOnlyFilter{WatchOnlyFilter_All}; CAmount minAmount{0}; - int limitRows{-1}; bool showInactive{true}; }; diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 39f3260ca6..7704496c10 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -54,8 +54,11 @@ using node::PSBTAnalysis; using node::ReadBlockFromDisk; using node::UndoReadFromDisk; -static void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry, Chainstate& active_chainstate, const CTxUndo* txundo = nullptr, TxVerbosity verbosity = TxVerbosity::SHOW_TXID) +static void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry, + Chainstate& active_chainstate, const CTxUndo* txundo = nullptr, + TxVerbosity verbosity = TxVerbosity::SHOW_DETAILS) { + CHECK_NONFATAL(verbosity >= TxVerbosity::SHOW_DETAILS); // Call into TxToUniv() in bitcoin-common to decode the transaction hex. // // Blockchain contextual information (confirmations and blocktime) is not diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp index 72b9f2230e..8991bda340 100644 --- a/src/script/descriptor.cpp +++ b/src/script/descriptor.cpp @@ -1833,17 +1833,17 @@ DescriptorCache DescriptorCache::MergeAndDiff(const DescriptorCache& other) return diff; } -const ExtPubKeyMap DescriptorCache::GetCachedParentExtPubKeys() const +ExtPubKeyMap DescriptorCache::GetCachedParentExtPubKeys() const { return m_parent_xpubs; } -const std::unordered_map<uint32_t, ExtPubKeyMap> DescriptorCache::GetCachedDerivedExtPubKeys() const +std::unordered_map<uint32_t, ExtPubKeyMap> DescriptorCache::GetCachedDerivedExtPubKeys() const { return m_derived_xpubs; } -const ExtPubKeyMap DescriptorCache::GetCachedLastHardenedExtPubKeys() const +ExtPubKeyMap DescriptorCache::GetCachedLastHardenedExtPubKeys() const { return m_last_hardened_xpubs; } diff --git a/src/script/descriptor.h b/src/script/descriptor.h index 16ee2f6d97..cb3b366acf 100644 --- a/src/script/descriptor.h +++ b/src/script/descriptor.h @@ -66,11 +66,11 @@ public: bool GetCachedLastHardenedExtPubKey(uint32_t key_exp_pos, CExtPubKey& xpub) const; /** Retrieve all cached parent xpubs */ - const ExtPubKeyMap GetCachedParentExtPubKeys() const; + ExtPubKeyMap GetCachedParentExtPubKeys() const; /** Retrieve all cached derived xpubs */ - const std::unordered_map<uint32_t, ExtPubKeyMap> GetCachedDerivedExtPubKeys() const; + std::unordered_map<uint32_t, ExtPubKeyMap> GetCachedDerivedExtPubKeys() const; /** Retrieve all cached last hardened xpubs */ - const ExtPubKeyMap GetCachedLastHardenedExtPubKeys() const; + ExtPubKeyMap GetCachedLastHardenedExtPubKeys() const; /** Combine another DescriptorCache into this one. * Returns a cache containing the items from the other cache unknown to current cache diff --git a/src/serialize.h b/src/serialize.h index f1edc54031..7bc7b10779 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -1005,11 +1005,11 @@ struct CSerActionUnserialize class CSizeComputer { protected: - size_t nSize; + size_t nSize{0}; const int nVersion; public: - explicit CSizeComputer(int nVersionIn) : nSize(0), nVersion(nVersionIn) {} + explicit CSizeComputer(int nVersionIn) : nVersion(nVersionIn) {} void write(Span<const std::byte> src) { diff --git a/src/span.h b/src/span.h index 4d00bbc244..4692eca7fb 100644 --- a/src/span.h +++ b/src/span.h @@ -96,7 +96,7 @@ template<typename C> class Span { C* m_data; - std::size_t m_size; + std::size_t m_size{0}; template <class T> struct is_Span_int : public std::false_type {}; @@ -107,7 +107,7 @@ class Span public: - constexpr Span() noexcept : m_data(nullptr), m_size(0) {} + constexpr Span() noexcept : m_data(nullptr) {} /** Construct a span from a begin pointer and a size. * diff --git a/src/streams.h b/src/streams.h index c12ba8777a..8788343809 100644 --- a/src/streams.h +++ b/src/streams.h @@ -358,14 +358,6 @@ public: nType{nTypeIn}, nVersion{nVersionIn} {} - template <typename... Args> - CDataStream(int nTypeIn, int nVersionIn, Args&&... args) - : nType{nTypeIn}, - nVersion{nVersionIn} - { - ::SerializeMany(*this, std::forward<Args>(args)...); - } - int GetType() const { return nType; } void SetVersion(int n) { nVersion = n; } int GetVersion() const { return nVersion; } @@ -628,8 +620,8 @@ private: const int nVersion; FILE *src; //!< source file - uint64_t nSrcPos; //!< how many bytes have been read from source - uint64_t m_read_pos; //!< how many bytes have been read from this + uint64_t nSrcPos{0}; //!< how many bytes have been read from source + uint64_t m_read_pos{0}; //!< how many bytes have been read from this uint64_t nReadLimit; //!< up to which position we're allowed to read uint64_t nRewind; //!< how many bytes we guarantee to rewind std::vector<std::byte> vchBuf; //!< the buffer @@ -675,7 +667,7 @@ private: public: CBufferedFile(FILE* fileIn, uint64_t nBufSize, uint64_t nRewindIn, int nTypeIn, int nVersionIn) - : nType(nTypeIn), nVersion(nVersionIn), nSrcPos(0), m_read_pos(0), nReadLimit(std::numeric_limits<uint64_t>::max()), nRewind(nRewindIn), vchBuf(nBufSize, std::byte{0}) + : nType(nTypeIn), nVersion(nVersionIn), nReadLimit(std::numeric_limits<uint64_t>::max()), nRewind(nRewindIn), vchBuf(nBufSize, std::byte{0}) { if (nRewindIn >= nBufSize) throw std::ios_base::failure("Rewind limit must be less than buffer size"); diff --git a/src/support/lockedpool.cpp b/src/support/lockedpool.cpp index 8b05743330..24ae4bdd1e 100644 --- a/src/support/lockedpool.cpp +++ b/src/support/lockedpool.cpp @@ -280,8 +280,8 @@ size_t PosixLockedPageAllocator::GetLimit() /*******************************************************************************/ // Implementation: LockedPool -LockedPool::LockedPool(std::unique_ptr<LockedPageAllocator> allocator_in, LockingFailed_Callback lf_cb_in): - allocator(std::move(allocator_in)), lf_cb(lf_cb_in), cumulative_bytes_locked(0) +LockedPool::LockedPool(std::unique_ptr<LockedPageAllocator> allocator_in, LockingFailed_Callback lf_cb_in) + : allocator(std::move(allocator_in)), lf_cb(lf_cb_in) { } diff --git a/src/support/lockedpool.h b/src/support/lockedpool.h index 66fbc218ab..1bba459377 100644 --- a/src/support/lockedpool.h +++ b/src/support/lockedpool.h @@ -198,7 +198,7 @@ private: std::list<LockedPageArena> arenas; LockingFailed_Callback lf_cb; - size_t cumulative_bytes_locked; + size_t cumulative_bytes_locked{0}; /** Mutex protects access to this pool's data structures, including arenas. */ mutable std::mutex mutex; diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp index b15df43e8c..586cec4081 100644 --- a/src/test/addrman_tests.cpp +++ b/src/test/addrman_tests.cpp @@ -67,14 +67,14 @@ BOOST_AUTO_TEST_CASE(addrman_simple) CNetAddr source = ResolveIP("252.2.2.2"); // Test: Does Addrman respond correctly when empty. - BOOST_CHECK_EQUAL(addrman->size(), 0U); + BOOST_CHECK_EQUAL(addrman->Size(), 0U); auto addr_null = addrman->Select().first; BOOST_CHECK_EQUAL(addr_null.ToString(), "[::]:0"); // Test: Does Addrman::Add work as expected. CService addr1 = ResolveService("250.1.1.1", 8333); BOOST_CHECK(addrman->Add({CAddress(addr1, NODE_NONE)}, source)); - BOOST_CHECK_EQUAL(addrman->size(), 1U); + BOOST_CHECK_EQUAL(addrman->Size(), 1U); auto addr_ret1 = addrman->Select().first; BOOST_CHECK_EQUAL(addr_ret1.ToString(), "250.1.1.1:8333"); @@ -82,7 +82,7 @@ BOOST_AUTO_TEST_CASE(addrman_simple) // Expected dup IP should not be added. CService addr1_dup = ResolveService("250.1.1.1", 8333); BOOST_CHECK(!addrman->Add({CAddress(addr1_dup, NODE_NONE)}, source)); - BOOST_CHECK_EQUAL(addrman->size(), 1U); + BOOST_CHECK_EQUAL(addrman->Size(), 1U); // Test: New table has one addr and we add a diff addr we should @@ -93,7 +93,7 @@ BOOST_AUTO_TEST_CASE(addrman_simple) CService addr2 = ResolveService("250.1.1.2", 8333); BOOST_CHECK(addrman->Add({CAddress(addr2, NODE_NONE)}, source)); - BOOST_CHECK(addrman->size() >= 1); + BOOST_CHECK(addrman->Size() >= 1); // Test: reset addrman and test AddrMan::Add multiple addresses works as expected addrman = std::make_unique<AddrMan>(EMPTY_NETGROUPMAN, DETERMINISTIC, GetCheckRatio(m_node)); @@ -101,7 +101,7 @@ BOOST_AUTO_TEST_CASE(addrman_simple) vAddr.push_back(CAddress(ResolveService("250.1.1.3", 8333), NODE_NONE)); vAddr.push_back(CAddress(ResolveService("250.1.1.4", 8333), NODE_NONE)); BOOST_CHECK(addrman->Add(vAddr, source)); - BOOST_CHECK(addrman->size() >= 1); + BOOST_CHECK(addrman->Size() >= 1); } BOOST_AUTO_TEST_CASE(addrman_ports) @@ -110,23 +110,23 @@ BOOST_AUTO_TEST_CASE(addrman_ports) CNetAddr source = ResolveIP("252.2.2.2"); - BOOST_CHECK_EQUAL(addrman->size(), 0U); + BOOST_CHECK_EQUAL(addrman->Size(), 0U); // Test 7; Addr with same IP but diff port does not replace existing addr. CService addr1 = ResolveService("250.1.1.1", 8333); BOOST_CHECK(addrman->Add({CAddress(addr1, NODE_NONE)}, source)); - BOOST_CHECK_EQUAL(addrman->size(), 1U); + BOOST_CHECK_EQUAL(addrman->Size(), 1U); CService addr1_port = ResolveService("250.1.1.1", 8334); BOOST_CHECK(addrman->Add({CAddress(addr1_port, NODE_NONE)}, source)); - BOOST_CHECK_EQUAL(addrman->size(), 2U); + BOOST_CHECK_EQUAL(addrman->Size(), 2U); auto addr_ret2 = addrman->Select().first; BOOST_CHECK(addr_ret2.ToString() == "250.1.1.1:8333" || addr_ret2.ToString() == "250.1.1.1:8334"); // Test: Add same IP but diff port to tried table; this converts the entry with // the specified port to tried, but not the other. addrman->Good(CAddress(addr1_port, NODE_NONE)); - BOOST_CHECK_EQUAL(addrman->size(), 2U); + BOOST_CHECK_EQUAL(addrman->Size(), 2U); bool newOnly = true; auto addr_ret3 = addrman->Select(newOnly).first; BOOST_CHECK_EQUAL(addr_ret3.ToString(), "250.1.1.1:8333"); @@ -142,7 +142,7 @@ BOOST_AUTO_TEST_CASE(addrman_select) // Test: Select from new with 1 addr in new. CService addr1 = ResolveService("250.1.1.1", 8333); BOOST_CHECK(addrman->Add({CAddress(addr1, NODE_NONE)}, source)); - BOOST_CHECK_EQUAL(addrman->size(), 1U); + BOOST_CHECK_EQUAL(addrman->Size(), 1U); bool newOnly = true; auto addr_ret1 = addrman->Select(newOnly).first; @@ -150,14 +150,14 @@ BOOST_AUTO_TEST_CASE(addrman_select) // Test: move addr to tried, select from new expected nothing returned. BOOST_CHECK(addrman->Good(CAddress(addr1, NODE_NONE))); - BOOST_CHECK_EQUAL(addrman->size(), 1U); + BOOST_CHECK_EQUAL(addrman->Size(), 1U); auto addr_ret2 = addrman->Select(newOnly).first; BOOST_CHECK_EQUAL(addr_ret2.ToString(), "[::]:0"); auto addr_ret3 = addrman->Select().first; BOOST_CHECK_EQUAL(addr_ret3.ToString(), "250.1.1.1:8333"); - BOOST_CHECK_EQUAL(addrman->size(), 1U); + BOOST_CHECK_EQUAL(addrman->Size(), 1U); // Add three addresses to new table. @@ -182,7 +182,7 @@ BOOST_AUTO_TEST_CASE(addrman_select) BOOST_CHECK(addrman->Good(CAddress(addr7, NODE_NONE))); // Test: 6 addrs + 1 addr from last test = 7. - BOOST_CHECK_EQUAL(addrman->size(), 7U); + BOOST_CHECK_EQUAL(addrman->Size(), 7U); // Test: Select pulls from new and tried regardless of port number. std::set<uint16_t> ports; @@ -200,25 +200,25 @@ BOOST_AUTO_TEST_CASE(addrman_new_collisions) uint32_t num_addrs{0}; - BOOST_CHECK_EQUAL(addrman->size(), num_addrs); + BOOST_CHECK_EQUAL(addrman->Size(), num_addrs); while (num_addrs < 22) { // Magic number! 250.1.1.1 - 250.1.1.22 do not collide with deterministic key = 1 CService addr = ResolveService("250.1.1." + ToString(++num_addrs)); BOOST_CHECK(addrman->Add({CAddress(addr, NODE_NONE)}, source)); // Test: No collision in new table yet. - BOOST_CHECK_EQUAL(addrman->size(), num_addrs); + BOOST_CHECK_EQUAL(addrman->Size(), num_addrs); } // Test: new table collision! CService addr1 = ResolveService("250.1.1." + ToString(++num_addrs)); uint32_t collisions{1}; BOOST_CHECK(addrman->Add({CAddress(addr1, NODE_NONE)}, source)); - BOOST_CHECK_EQUAL(addrman->size(), num_addrs - collisions); + BOOST_CHECK_EQUAL(addrman->Size(), num_addrs - collisions); CService addr2 = ResolveService("250.1.1." + ToString(++num_addrs)); BOOST_CHECK(addrman->Add({CAddress(addr2, NODE_NONE)}, source)); - BOOST_CHECK_EQUAL(addrman->size(), num_addrs - collisions); + BOOST_CHECK_EQUAL(addrman->Size(), num_addrs - collisions); } BOOST_AUTO_TEST_CASE(addrman_new_multiplicity) @@ -236,7 +236,7 @@ BOOST_AUTO_TEST_CASE(addrman_new_multiplicity) } AddressPosition addr_pos = addrman->FindAddressEntry(addr).value(); BOOST_CHECK_EQUAL(addr_pos.multiplicity, 1U); - BOOST_CHECK_EQUAL(addrman->size(), 1U); + BOOST_CHECK_EQUAL(addrman->Size(), 1U); // if nTime increases, an addr can occur in up to 8 buckets // The acceptance probability decreases exponentially with existing multiplicity - @@ -250,7 +250,7 @@ BOOST_AUTO_TEST_CASE(addrman_new_multiplicity) AddressPosition addr_pos_multi = addrman->FindAddressEntry(addr).value(); BOOST_CHECK_EQUAL(addr_pos_multi.multiplicity, 8U); // multiplicity doesn't affect size - BOOST_CHECK_EQUAL(addrman->size(), 1U); + BOOST_CHECK_EQUAL(addrman->Size(), 1U); } BOOST_AUTO_TEST_CASE(addrman_tried_collisions) @@ -261,7 +261,7 @@ BOOST_AUTO_TEST_CASE(addrman_tried_collisions) uint32_t num_addrs{0}; - BOOST_CHECK_EQUAL(addrman->size(), num_addrs); + BOOST_CHECK_EQUAL(addrman->Size(), num_addrs); while (num_addrs < 35) { // Magic number! 250.1.1.1 - 250.1.1.35 do not collide in tried with deterministic key = 1 CService addr = ResolveService("250.1.1." + ToString(++num_addrs)); @@ -290,7 +290,7 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) // Test: Sanity check, GetAddr should never return anything if addrman // is empty. - BOOST_CHECK_EQUAL(addrman->size(), 0U); + BOOST_CHECK_EQUAL(addrman->Size(), 0U); std::vector<CAddress> vAddr1 = addrman->GetAddr(/*max_addresses=*/0, /*max_pct=*/0, /*network=*/std::nullopt); BOOST_CHECK_EQUAL(vAddr1.size(), 0U); @@ -336,11 +336,11 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) } std::vector<CAddress> vAddr = addrman->GetAddr(/*max_addresses=*/2500, /*max_pct=*/23, /*network=*/std::nullopt); - size_t percent23 = (addrman->size() * 23) / 100; + size_t percent23 = (addrman->Size() * 23) / 100; BOOST_CHECK_EQUAL(vAddr.size(), percent23); BOOST_CHECK_EQUAL(vAddr.size(), 461U); - // (Addrman.size() < number of addresses added) due to address collisions. - BOOST_CHECK_EQUAL(addrman->size(), 2006U); + // (addrman.Size() < number of addresses added) due to address collisions. + BOOST_CHECK_EQUAL(addrman->Size(), 2006U); } @@ -681,7 +681,7 @@ BOOST_AUTO_TEST_CASE(remove_invalid) addrman->Add({new1, tried1, new2, tried2}, CNetAddr{}); addrman->Good(tried1); addrman->Good(tried2); - BOOST_REQUIRE_EQUAL(addrman->size(), 4); + BOOST_REQUIRE_EQUAL(addrman->Size(), 4); stream << *addrman; @@ -704,14 +704,14 @@ BOOST_AUTO_TEST_CASE(remove_invalid) addrman = std::make_unique<AddrMan>(EMPTY_NETGROUPMAN, DETERMINISTIC, GetCheckRatio(m_node)); stream >> *addrman; - BOOST_CHECK_EQUAL(addrman->size(), 2); + BOOST_CHECK_EQUAL(addrman->Size(), 2); } BOOST_AUTO_TEST_CASE(addrman_selecttriedcollision) { auto addrman = std::make_unique<AddrMan>(EMPTY_NETGROUPMAN, DETERMINISTIC, GetCheckRatio(m_node)); - BOOST_CHECK(addrman->size() == 0); + BOOST_CHECK(addrman->Size() == 0); // Empty addrman should return blank addrman info. BOOST_CHECK(addrman->SelectTriedCollision().first.ToString() == "[::]:0"); @@ -796,7 +796,7 @@ BOOST_AUTO_TEST_CASE(addrman_evictionworks) { auto addrman = std::make_unique<AddrMan>(EMPTY_NETGROUPMAN, DETERMINISTIC, GetCheckRatio(m_node)); - BOOST_CHECK(addrman->size() == 0); + BOOST_CHECK(addrman->Size() == 0); // Empty addrman should return blank addrman info. BOOST_CHECK(addrman->SelectTriedCollision().first.ToString() == "[::]:0"); @@ -878,14 +878,14 @@ BOOST_AUTO_TEST_CASE(load_addrman) BOOST_CHECK(Lookup("252.5.1.1", source, 8333, false)); std::vector<CAddress> addresses{CAddress(addr1, NODE_NONE), CAddress(addr2, NODE_NONE), CAddress(addr3, NODE_NONE)}; BOOST_CHECK(addrman.Add(addresses, source)); - BOOST_CHECK(addrman.size() == 3); + BOOST_CHECK(addrman.Size() == 3); // Test that the de-serialization does not throw an exception. CDataStream ssPeers1 = AddrmanToStream(addrman); bool exceptionThrown = false; AddrMan addrman1{EMPTY_NETGROUPMAN, !DETERMINISTIC, GetCheckRatio(m_node)}; - BOOST_CHECK(addrman1.size() == 0); + BOOST_CHECK(addrman1.Size() == 0); try { unsigned char pchMsgTmp[4]; ssPeers1 >> pchMsgTmp; @@ -894,16 +894,16 @@ BOOST_AUTO_TEST_CASE(load_addrman) exceptionThrown = true; } - BOOST_CHECK(addrman1.size() == 3); + BOOST_CHECK(addrman1.Size() == 3); BOOST_CHECK(exceptionThrown == false); // Test that ReadFromStream creates an addrman with the correct number of addrs. CDataStream ssPeers2 = AddrmanToStream(addrman); AddrMan addrman2{EMPTY_NETGROUPMAN, !DETERMINISTIC, GetCheckRatio(m_node)}; - BOOST_CHECK(addrman2.size() == 0); + BOOST_CHECK(addrman2.Size() == 0); ReadFromStream(addrman2, ssPeers2); - BOOST_CHECK(addrman2.size() == 3); + BOOST_CHECK(addrman2.Size() == 3); } // Produce a corrupt peers.dat that claims 20 addrs when it only has one addr. @@ -939,7 +939,7 @@ BOOST_AUTO_TEST_CASE(load_addrman_corrupted) CDataStream ssPeers1 = MakeCorruptPeersDat(); bool exceptionThrown = false; AddrMan addrman1{EMPTY_NETGROUPMAN, !DETERMINISTIC, GetCheckRatio(m_node)}; - BOOST_CHECK(addrman1.size() == 0); + BOOST_CHECK(addrman1.Size() == 0); try { unsigned char pchMsgTmp[4]; ssPeers1 >> pchMsgTmp; @@ -947,15 +947,13 @@ BOOST_AUTO_TEST_CASE(load_addrman_corrupted) } catch (const std::exception&) { exceptionThrown = true; } - // Even though de-serialization failed addrman is not left in a clean state. - BOOST_CHECK(addrman1.size() == 1); BOOST_CHECK(exceptionThrown); // Test that ReadFromStream fails if peers.dat is corrupt CDataStream ssPeers2 = MakeCorruptPeersDat(); AddrMan addrman2{EMPTY_NETGROUPMAN, !DETERMINISTIC, GetCheckRatio(m_node)}; - BOOST_CHECK(addrman2.size() == 0); + BOOST_CHECK(addrman2.Size() == 0); BOOST_CHECK_THROW(ReadFromStream(addrman2, ssPeers2), std::ios_base::failure); } @@ -969,7 +967,7 @@ BOOST_AUTO_TEST_CASE(addrman_update_address) const auto start_time{Now<NodeSeconds>() - 10000s}; addr.nTime = start_time; BOOST_CHECK(addrman->Add({addr}, source)); - BOOST_CHECK_EQUAL(addrman->size(), 1U); + BOOST_CHECK_EQUAL(addrman->Size(), 1U); // Updating an addrman entry with a different port doesn't change it CAddress addr_diff_port{CAddress(ResolveService("250.1.1.1", 8334), NODE_NONE)}; @@ -990,4 +988,42 @@ BOOST_AUTO_TEST_CASE(addrman_update_address) BOOST_CHECK_EQUAL(vAddr2.at(0).nServices, NODE_NETWORK_LIMITED); } +BOOST_AUTO_TEST_CASE(addrman_size) +{ + auto addrman = std::make_unique<AddrMan>(EMPTY_NETGROUPMAN, DETERMINISTIC, GetCheckRatio(m_node)); + const CNetAddr source = ResolveIP("252.2.2.2"); + + // empty addrman + BOOST_CHECK_EQUAL(addrman->Size(/*net=*/std::nullopt, /*in_new=*/std::nullopt), 0U); + BOOST_CHECK_EQUAL(addrman->Size(/*net=*/NET_IPV4, /*in_new=*/std::nullopt), 0U); + BOOST_CHECK_EQUAL(addrman->Size(/*net=*/std::nullopt, /*in_new=*/true), 0U); + BOOST_CHECK_EQUAL(addrman->Size(/*net=*/NET_IPV4, /*in_new=*/false), 0U); + + // add two ipv4 addresses, one to tried and new + const CAddress addr1{ResolveService("250.1.1.1", 8333), NODE_NONE}; + BOOST_CHECK(addrman->Add({addr1}, source)); + BOOST_CHECK(addrman->Good(addr1)); + const CAddress addr2{ResolveService("250.1.1.2", 8333), NODE_NONE}; + BOOST_CHECK(addrman->Add({addr2}, source)); + + BOOST_CHECK_EQUAL(addrman->Size(/*net=*/std::nullopt, /*in_new=*/std::nullopt), 2U); + BOOST_CHECK_EQUAL(addrman->Size(/*net=*/NET_IPV4, /*in_new=*/std::nullopt), 2U); + BOOST_CHECK_EQUAL(addrman->Size(/*net=*/std::nullopt, /*in_new=*/true), 1U); + BOOST_CHECK_EQUAL(addrman->Size(/*net=*/std::nullopt, /*in_new=*/false), 1U); + BOOST_CHECK_EQUAL(addrman->Size(/*net=*/NET_IPV4, /*in_new=*/true), 1U); + BOOST_CHECK_EQUAL(addrman->Size(/*net=*/NET_IPV4, /*in_new=*/false), 1U); + + // add one i2p address to new + CService i2p_addr; + i2p_addr.SetSpecial("UDHDrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna.b32.I2P"); + const CAddress addr3{i2p_addr, NODE_NONE}; + BOOST_CHECK(addrman->Add({addr3}, source)); + BOOST_CHECK_EQUAL(addrman->Size(/*net=*/std::nullopt, /*in_new=*/std::nullopt), 3U); + BOOST_CHECK_EQUAL(addrman->Size(/*net=*/NET_IPV4, /*in_new=*/std::nullopt), 2U); + BOOST_CHECK_EQUAL(addrman->Size(/*net=*/NET_I2P, /*in_new=*/std::nullopt), 1U); + BOOST_CHECK_EQUAL(addrman->Size(/*net=*/NET_I2P, /*in_new=*/true), 1U); + BOOST_CHECK_EQUAL(addrman->Size(/*net=*/std::nullopt, /*in_new=*/true), 2U); + BOOST_CHECK_EQUAL(addrman->Size(/*net=*/std::nullopt, /*in_new=*/false), 1U); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp index 0101bcc372..601caf8102 100644 --- a/src/test/base58_tests.cpp +++ b/src/test/base58_tests.cpp @@ -5,6 +5,7 @@ #include <test/data/base58_encode_decode.json.h> #include <base58.h> +#include <test/util/json.h> #include <test/util/setup_common.h> #include <util/strencodings.h> #include <util/vector.h> @@ -16,8 +17,6 @@ using namespace std::literals; -UniValue read_json(const std::string& jsondata); - BOOST_FIXTURE_TEST_SUITE(base58_tests, BasicTestingSetup) // Goal: test low-level base58 encoding functionality diff --git a/src/test/fuzz/addrman.cpp b/src/test/fuzz/addrman.cpp index 2953cf149d..a59e41dbb5 100644 --- a/src/test/fuzz/addrman.cpp +++ b/src/test/fuzz/addrman.cpp @@ -117,7 +117,7 @@ void FillAddrman(AddrMan& addrman, FuzzedDataProvider& fuzzed_data_provider) const std::chrono::seconds time_penalty{fast_random_context.randrange(100000001)}; addrman.Add({addr}, source, time_penalty); - if (n > 0 && addrman.size() % n == 0) { + if (n > 0 && addrman.Size() % n == 0) { addrman.Good(addr, Now<NodeSeconds>()); } @@ -304,7 +304,7 @@ FUZZ_TARGET_INIT(addrman, initialize_addrman) /*max_pct=*/fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096), /*network=*/std::nullopt); (void)const_addr_man.Select(fuzzed_data_provider.ConsumeBool()); - (void)const_addr_man.size(); + (void)const_addr_man.Size(); CDataStream data_stream(SER_NETWORK, PROTOCOL_VERSION); data_stream << const_addr_man; } diff --git a/src/test/fuzz/miniscript.cpp b/src/test/fuzz/miniscript.cpp index 1d6a8d89e4..d5667e0cf3 100644 --- a/src/test/fuzz/miniscript.cpp +++ b/src/test/fuzz/miniscript.cpp @@ -104,7 +104,7 @@ struct ScriptParserContext { return key.data; } - const std::vector<unsigned char> ToPKHBytes(const Key& key) const + std::vector<unsigned char> ToPKHBytes(const Key& key) const { if (key.is_hash) return key.data; const auto h = Hash160(key.data); diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h index af1d65cd38..c14f633029 100644 --- a/src/test/fuzz/util.h +++ b/src/test/fuzz/util.h @@ -47,7 +47,7 @@ size_t CallOneOf(FuzzedDataProvider& fuzzed_data_provider, Callables... callable template <typename Collection> auto& PickValue(FuzzedDataProvider& fuzzed_data_provider, Collection& col) { - const auto sz = col.size(); + auto sz{col.size()}; assert(sz >= 1); auto it = col.begin(); std::advance(it, fuzzed_data_provider.ConsumeIntegralInRange<decltype(sz)>(0, sz - 1)); diff --git a/src/test/key_io_tests.cpp b/src/test/key_io_tests.cpp index fb0a07934d..a400afee71 100644 --- a/src/test/key_io_tests.cpp +++ b/src/test/key_io_tests.cpp @@ -8,6 +8,7 @@ #include <key.h> #include <key_io.h> #include <script/script.h> +#include <test/util/json.h> #include <test/util/setup_common.h> #include <util/strencodings.h> @@ -15,8 +16,6 @@ #include <univalue.h> -UniValue read_json(const std::string& jsondata); - BOOST_FIXTURE_TEST_SUITE(key_io_tests, BasicTestingSetup) // Goal: check that parsed keys match test payload diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp index d14fda7351..edf28cfbfc 100644 --- a/src/test/key_tests.cpp +++ b/src/test/key_tests.cpp @@ -205,8 +205,7 @@ BOOST_AUTO_TEST_CASE(key_key_negation) unsigned char rnd[8]; std::string str = "Bitcoin key verification\n"; GetRandBytes(rnd); - uint256 hash; - CHash256().Write(MakeUCharSpan(str)).Write(rnd).Finalize(hash); + uint256 hash{Hash(str, rnd)}; // import the static test key CKey key = DecodeSecret(strSecret1C); diff --git a/src/test/logging_tests.cpp b/src/test/logging_tests.cpp index 022e33f99d..beb9398c74 100644 --- a/src/test/logging_tests.cpp +++ b/src/test/logging_tests.cpp @@ -75,20 +75,9 @@ struct LogSetup : public BasicTestingSetup { BOOST_AUTO_TEST_CASE(logging_timer) { - SetMockTime(1); auto micro_timer = BCLog::Timer<std::chrono::microseconds>("tests", "end_msg"); - SetMockTime(2); - BOOST_CHECK_EQUAL(micro_timer.LogMsg("test micros"), "tests: test micros (1000000μs)"); - - SetMockTime(1); - auto ms_timer = BCLog::Timer<std::chrono::milliseconds>("tests", "end_msg"); - SetMockTime(2); - BOOST_CHECK_EQUAL(ms_timer.LogMsg("test ms"), "tests: test ms (1000.00ms)"); - - SetMockTime(1); - auto sec_timer = BCLog::Timer<std::chrono::seconds>("tests", "end_msg"); - SetMockTime(2); - BOOST_CHECK_EQUAL(sec_timer.LogMsg("test secs"), "tests: test secs (1.00s)"); + const std::string_view result_prefix{"tests: msg ("}; + BOOST_CHECK_EQUAL(micro_timer.LogMsg("msg").substr(0, result_prefix.size()), result_prefix); } BOOST_FIXTURE_TEST_CASE(logging_LogPrintf_, LogSetup) diff --git a/src/test/merkle_tests.cpp b/src/test/merkle_tests.cpp index bba103d1b0..74e01fc2a5 100644 --- a/src/test/merkle_tests.cpp +++ b/src/test/merkle_tests.cpp @@ -60,7 +60,7 @@ static void MerkleComputation(const std::vector<uint256>& leaves, uint256* proot } } mutated |= (inner[level] == h); - CHash256().Write(inner[level]).Write(h).Finalize(h); + h = Hash(inner[level], h); } // Store the resulting hash at inner position level. inner[level] = h; @@ -86,7 +86,7 @@ static void MerkleComputation(const std::vector<uint256>& leaves, uint256* proot if (pbranch && matchh) { pbranch->push_back(h); } - CHash256().Write(h).Write(h).Finalize(h); + h = Hash(h, h); // Increment count to the value it would have if two entries at this // level had existed. count += ((uint32_t{1}) << level); @@ -101,7 +101,7 @@ static void MerkleComputation(const std::vector<uint256>& leaves, uint256* proot matchh = true; } } - CHash256().Write(inner[level]).Write(h).Finalize(h); + h = Hash(inner[level], h); level++; } } diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index d4cede8f7c..22f6cfd164 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -15,6 +15,7 @@ #include <script/sign.h> #include <script/signingprovider.h> #include <streams.h> +#include <test/util/json.h> #include <test/util/setup_common.h> #include <test/util/transaction_utils.h> #include <util/strencodings.h> @@ -41,18 +42,6 @@ static const unsigned int gFlags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC; unsigned int ParseScriptFlags(std::string strFlags); std::string FormatScriptFlags(unsigned int flags); -UniValue read_json(const std::string& jsondata) -{ - UniValue v; - - if (!v.read(jsondata) || !v.isArray()) - { - BOOST_ERROR("Parse error."); - return UniValue(UniValue::VARR); - } - return v.get_array(); -} - struct ScriptErrorDesc { ScriptError_t err; diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp index f583109e16..09f77d2b61 100644 --- a/src/test/serialize_tests.cpp +++ b/src/test/serialize_tests.cpp @@ -237,7 +237,8 @@ BOOST_AUTO_TEST_CASE(class_methods) BOOST_CHECK(methodtest2 == methodtest3); BOOST_CHECK(methodtest3 == methodtest4); - CDataStream ss2(SER_DISK, PROTOCOL_VERSION, intval, boolval, stringval, charstrval, txval); + CDataStream ss2{SER_DISK, PROTOCOL_VERSION}; + ss2 << intval << boolval << stringval << charstrval << txval; ss2 >> methodtest3; BOOST_CHECK(methodtest3 == methodtest4); } diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index 1ce694b8c6..368f9e6047 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -10,6 +10,7 @@ #include <serialize.h> #include <streams.h> #include <test/data/sighash.json.h> +#include <test/util/json.h> #include <test/util/setup_common.h> #include <util/strencodings.h> #include <util/system.h> @@ -21,8 +22,6 @@ #include <univalue.h> -UniValue read_json(const std::string& jsondata); - // Old script.cpp SignatureHash function uint256 static SignatureHashOld(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType) { diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 69b03e07bf..d00de9df9b 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -21,6 +21,7 @@ #include <script/signingprovider.h> #include <script/standard.h> #include <streams.h> +#include <test/util/json.h> #include <test/util/script.h> #include <test/util/transaction_utils.h> #include <util/strencodings.h> @@ -37,9 +38,6 @@ typedef std::vector<unsigned char> valtype; -// In script_tests.cpp -UniValue read_json(const std::string& jsondata); - static CFeeRate g_dust{DUST_RELAY_TX_FEE}; static bool g_bare_multi{DEFAULT_PERMIT_BAREMULTISIG}; diff --git a/src/test/util/json.cpp b/src/test/util/json.cpp new file mode 100644 index 0000000000..ad3c346c84 --- /dev/null +++ b/src/test/util/json.cpp @@ -0,0 +1,17 @@ +// Copyright (c) 2023 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/json.h> + +#include <string> +#include <util/check.h> + +#include <univalue.h> + +UniValue read_json(const std::string& jsondata) +{ + UniValue v; + Assert(v.read(jsondata) && v.isArray()); + return v.get_array(); +} diff --git a/src/test/util/json.h b/src/test/util/json.h new file mode 100644 index 0000000000..5b1026762e --- /dev/null +++ b/src/test/util/json.h @@ -0,0 +1,14 @@ +// Copyright (c) 2023 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_JSON_H +#define BITCOIN_TEST_UTIL_JSON_H + +#include <string> + +#include <univalue.h> + +UniValue read_json(const std::string& jsondata); + +#endif // BITCOIN_TEST_UTIL_JSON_H diff --git a/src/test/util/net.cpp b/src/test/util/net.cpp index 975aff13c0..ac5dfe9e73 100644 --- a/src/test/util/net.cpp +++ b/src/test/util/net.cpp @@ -67,15 +67,14 @@ void ConnmanTestMsg::NodeReceiveMsgBytes(CNode& node, Span<const uint8_t> msg_by assert(node.ReceiveMsgBytes(msg_bytes, complete)); if (complete) { size_t nSizeAdded = 0; - auto it(node.vRecvMsg.begin()); - for (; it != node.vRecvMsg.end(); ++it) { + for (const auto& msg : node.vRecvMsg) { // vRecvMsg contains only completed CNetMessage // the single possible partially deserialized message are held by TransportDeserializer - nSizeAdded += it->m_raw_message_size; + nSizeAdded += msg.m_raw_message_size; } { LOCK(node.cs_vProcessMsg); - node.vProcessMsg.splice(node.vProcessMsg.end(), node.vRecvMsg, node.vRecvMsg.begin(), it); + node.vProcessMsg.splice(node.vProcessMsg.end(), node.vRecvMsg); node.nProcessQueueSize += nSizeAdded; node.fPauseRecv = node.nProcessQueueSize > nReceiveFloodSize; } diff --git a/src/test/util/net.h b/src/test/util/net.h index 90c606306f..e6506b0d08 100644 --- a/src/test/util/net.h +++ b/src/test/util/net.h @@ -103,7 +103,7 @@ constexpr auto ALL_NETWORKS = std::array{ class StaticContentsSock : public Sock { public: - explicit StaticContentsSock(const std::string& contents) : m_contents{contents}, m_consumed{0} + explicit StaticContentsSock(const std::string& contents) : m_contents{contents} { // Just a dummy number that is not INVALID_SOCKET. m_socket = INVALID_SOCKET - 1; @@ -191,7 +191,7 @@ public: private: const std::string m_contents; - mutable size_t m_consumed; + mutable size_t m_consumed{0}; }; std::vector<NodeEvictionCandidate> GetRandomNodeEvictionCandidates(int n_candidates, FastRandomContext& random_context); diff --git a/src/test/versionbits_tests.cpp b/src/test/versionbits_tests.cpp index 4a42cec4af..91383ee4a5 100644 --- a/src/test/versionbits_tests.cpp +++ b/src/test/versionbits_tests.cpp @@ -13,7 +13,7 @@ /* Define a virtual block time, one block per 10 minutes after Nov 14 2014, 0:55:36am */ static int32_t TestTime(int nHeight) { return 1415926536 + 600 * nHeight; } -static const std::string StateName(ThresholdState state) +static std::string StateName(ThresholdState state) { switch (state) { case ThresholdState::DEFINED: return "DEFINED"; diff --git a/src/tinyformat.h b/src/tinyformat.h index 8eded00add..3ec385bc95 100644 --- a/src/tinyformat.h +++ b/src/tinyformat.h @@ -508,9 +508,6 @@ class FormatArg { public: FormatArg() - : m_value(nullptr), - m_formatImpl(nullptr), - m_toIntImpl(nullptr) { } template<typename T> @@ -549,10 +546,10 @@ class FormatArg return convertToInt<T>::invoke(*static_cast<const T*>(value)); } - const void* m_value; + const void* m_value{nullptr}; void (*m_formatImpl)(std::ostream& out, const char* fmtBegin, - const char* fmtEnd, int ntrunc, const void* value); - int (*m_toIntImpl)(const void* value); + const char* fmtEnd, int ntrunc, const void* value){nullptr}; + int (*m_toIntImpl)(const void* value){nullptr}; }; diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index b5f1fa7138..ece77f9023 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -53,8 +53,8 @@ static const uint16_t DEFAULT_TOR_SOCKS_PORT = 9050; /****** Low-level TorControlConnection ********/ -TorControlConnection::TorControlConnection(struct event_base *_base): - base(_base), b_conn(nullptr) +TorControlConnection::TorControlConnection(struct event_base* _base) + : base(_base) { } diff --git a/src/torcontrol.h b/src/torcontrol.h index 81475aee74..6563a2ef42 100644 --- a/src/torcontrol.h +++ b/src/torcontrol.h @@ -93,7 +93,7 @@ private: /** Libevent event base */ struct event_base *base; /** Connection to control socket */ - struct bufferevent *b_conn; + struct bufferevent* b_conn{nullptr}; /** Message being received */ TorControlReply message; /** Response handlers */ diff --git a/src/txmempool.cpp b/src/txmempool.cpp index aa04f8a4d0..378123ce0f 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -1128,7 +1128,7 @@ void CTxMemPool::SetLoadTried(bool load_tried) } -const std::string RemovalReasonToString(const MemPoolRemovalReason& r) noexcept +std::string RemovalReasonToString(const MemPoolRemovalReason& r) noexcept { switch (r) { case MemPoolRemovalReason::EXPIRY: return "expiry"; diff --git a/src/txmempool.h b/src/txmempool.h index 51b8af3286..2c3cb7e9db 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -237,7 +237,7 @@ enum class MemPoolRemovalReason { REPLACED, //!< Removed for replacement }; -const std::string RemovalReasonToString(const MemPoolRemovalReason& r) noexcept; +std::string RemovalReasonToString(const MemPoolRemovalReason& r) noexcept; /** * CTxMemPool stores valid-according-to-the-current-best-chain transactions diff --git a/src/univalue/include/univalue_utffilter.h b/src/univalue/include/univalue_utffilter.h index f688eaaa30..41d8e6bb05 100644 --- a/src/univalue/include/univalue_utffilter.h +++ b/src/univalue/include/univalue_utffilter.h @@ -13,8 +13,8 @@ class JSONUTF8StringFilter { public: - explicit JSONUTF8StringFilter(std::string &s): - str(s), is_valid(true), codepoint(0), state(0), surpair(0) + explicit JSONUTF8StringFilter(std::string& s) + : str(s) { } // Write single 8-bit char (may be part of UTF-8 sequence) @@ -79,10 +79,10 @@ public: } private: std::string &str; - bool is_valid; + bool is_valid{true}; // Current UTF-8 decoding state - unsigned int codepoint; - int state; // Top bit to be filled in for next UTF-8 byte, or 0 + unsigned int codepoint{0}; + int state{0}; // Top bit to be filled in for next UTF-8 byte, or 0 // Keep track of the following state to handle the following section of // RFC4627: @@ -94,7 +94,7 @@ private: // "\uD834\uDD1E". // // Two subsequent \u.... may have to be replaced with one actual codepoint. - unsigned int surpair; // First half of open UTF-16 surrogate pair, or 0 + unsigned int surpair{0}; // First half of open UTF-16 surrogate pair, or 0 void append_codepoint(unsigned int codepoint_) { diff --git a/src/util/fees.cpp b/src/util/fees.cpp index cbefe18dbb..8ada02ce54 100644 --- a/src/util/fees.cpp +++ b/src/util/fees.cpp @@ -49,7 +49,7 @@ std::string FeeModes(const std::string& delimiter) return Join(FeeModeMap(), delimiter, [&](const std::pair<std::string, FeeEstimateMode>& i) { return i.first; }); } -const std::string InvalidEstimateModeErrorMessage() +std::string InvalidEstimateModeErrorMessage() { return "Invalid estimate_mode parameter, must be one of: \"" + FeeModes("\", \"") + "\""; } diff --git a/src/util/fees.h b/src/util/fees.h index 9ef2389d3e..10ba1e4f85 100644 --- a/src/util/fees.h +++ b/src/util/fees.h @@ -13,6 +13,6 @@ enum class FeeReason; bool FeeModeFromString(const std::string& mode_string, FeeEstimateMode& fee_estimate_mode); std::string StringForFeeReason(FeeReason reason); std::string FeeModes(const std::string& delimiter); -const std::string InvalidEstimateModeErrorMessage(); +std::string InvalidEstimateModeErrorMessage(); #endif // BITCOIN_UTIL_FEES_H diff --git a/src/util/sock.h b/src/util/sock.h index adcca377e3..6bac2dfd34 100644 --- a/src/util/sock.h +++ b/src/util/sock.h @@ -181,9 +181,9 @@ public: * Auxiliary requested/occurred events to wait for in `WaitMany()`. */ struct Events { - explicit Events(Event req) : requested{req}, occurred{0} {} + explicit Events(Event req) : requested{req} {} Event requested; - Event occurred; + Event occurred{0}; }; struct HashSharedPtrSock { diff --git a/src/util/system.cpp b/src/util/system.cpp index 309595ff5b..0cea283ece 100644 --- a/src/util/system.cpp +++ b/src/util/system.cpp @@ -242,7 +242,7 @@ static std::optional<util::SettingsValue> InterpretValue(const KeyInfo& key, con ArgsManager::ArgsManager() = default; ArgsManager::~ArgsManager() = default; -const std::set<std::string> ArgsManager::GetUnsuitableSectionOnlyArgs() const +std::set<std::string> ArgsManager::GetUnsuitableSectionOnlyArgs() const { std::set<std::string> unsuitables; @@ -262,7 +262,7 @@ const std::set<std::string> ArgsManager::GetUnsuitableSectionOnlyArgs() const return unsuitables; } -const std::list<SectionInfo> ArgsManager::GetUnrecognizedSections() const +std::list<SectionInfo> ArgsManager::GetUnrecognizedSections() const { // Section names to be recognized in the config file. static const std::set<std::string> available_sections{ diff --git a/src/util/system.h b/src/util/system.h index 671491f2ff..c053adf8c3 100644 --- a/src/util/system.h +++ b/src/util/system.h @@ -250,12 +250,12 @@ protected: * on the command line or in a network-specific section in the * config file. */ - const std::set<std::string> GetUnsuitableSectionOnlyArgs() const; + std::set<std::string> GetUnsuitableSectionOnlyArgs() const; /** * Log warnings for unrecognized section names in the config file. */ - const std::list<SectionInfo> GetUnrecognizedSections() const; + std::list<SectionInfo> GetUnrecognizedSections() const; struct Command { /** The command (if one has been registered with AddCommand), or empty */ diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp index 900cb0474a..d344c8bfbd 100644 --- a/src/validationinterface.cpp +++ b/src/validationinterface.cpp @@ -17,7 +17,7 @@ #include <unordered_map> #include <utility> -const std::string RemovalReasonToString(const MemPoolRemovalReason& r) noexcept; +std::string RemovalReasonToString(const MemPoolRemovalReason& r) noexcept; /** * MainSignalsImpl manages a list of shared_ptr<CValidationInterface> callbacks. diff --git a/src/wallet/bdb.cpp b/src/wallet/bdb.cpp index c619222b3e..653115aa81 100644 --- a/src/wallet/bdb.cpp +++ b/src/wallet/bdb.cpp @@ -308,7 +308,7 @@ BerkeleyDatabase::~BerkeleyDatabase() } } -BerkeleyBatch::BerkeleyBatch(BerkeleyDatabase& database, const bool read_only, bool fFlushOnCloseIn) : pdb(nullptr), activeTxn(nullptr), m_database(database) +BerkeleyBatch::BerkeleyBatch(BerkeleyDatabase& database, const bool read_only, bool fFlushOnCloseIn) : m_database(database) { database.AddRef(); database.Open(); diff --git a/src/wallet/bdb.h b/src/wallet/bdb.h index 9d1d68ba43..06c98972b0 100644 --- a/src/wallet/bdb.h +++ b/src/wallet/bdb.h @@ -207,9 +207,9 @@ private: bool HasKey(DataStream&& key) override; protected: - Db* pdb; + Db* pdb{nullptr}; std::string strFile; - DbTxn* activeTxn; + DbTxn* activeTxn{nullptr}; bool fReadOnly; bool fFlushOnClose; BerkeleyEnvironment *env; diff --git a/src/wallet/db.h b/src/wallet/db.h index 287fb1d19e..d4c590fac7 100644 --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -123,7 +123,7 @@ class WalletDatabase { public: /** Create dummy DB handle */ - WalletDatabase() : nUpdateCounter(0), nLastSeen(0), nLastFlushed(0), nLastWalletUpdate(0) {} + WalletDatabase() : nUpdateCounter(0) {} virtual ~WalletDatabase() {}; /** Open the database if it is not already opened. */ @@ -165,9 +165,9 @@ public: virtual std::string Format() = 0; std::atomic<unsigned int> nUpdateCounter; - unsigned int nLastSeen; - unsigned int nLastFlushed; - int64_t nLastWalletUpdate; + unsigned int nLastSeen{0}; + unsigned int nLastFlushed{0}; + int64_t nLastWalletUpdate{0}; /** Make a DatabaseBatch connected to this database */ virtual std::unique_ptr<DatabaseBatch> MakeBatch(bool flush_on_close = true) = 0; diff --git a/src/wallet/rpc/transactions.cpp b/src/wallet/rpc/transactions.cpp index 4a076a7040..e590aa1f08 100644 --- a/src/wallet/rpc/transactions.cpp +++ b/src/wallet/rpc/transactions.cpp @@ -397,7 +397,7 @@ static void ListTransactions(const CWallet& wallet, const CWalletTx& wtx, int nM } -static const std::vector<RPCResult> TransactionDescriptionString() +static std::vector<RPCResult> TransactionDescriptionString() { return{{RPCResult::Type::NUM, "confirmations", "The number of confirmations for the transaction. Negative confirmations means the\n" "transaction conflicted that many blocks ago."}, diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp index d8fb926c9a..59cf87355b 100644 --- a/src/wallet/scriptpubkeyman.cpp +++ b/src/wallet/scriptpubkeyman.cpp @@ -1664,7 +1664,7 @@ std::set<CKeyID> LegacyScriptPubKeyMan::GetKeys() const return set_address; } -const std::unordered_set<CScript, SaltedSipHasher> LegacyScriptPubKeyMan::GetScriptPubKeys() const +std::unordered_set<CScript, SaltedSipHasher> LegacyScriptPubKeyMan::GetScriptPubKeys() const { LOCK(cs_KeyStore); std::unordered_set<CScript, SaltedSipHasher> spks; @@ -2650,17 +2650,17 @@ void DescriptorScriptPubKeyMan::WriteDescriptor() } } -const WalletDescriptor DescriptorScriptPubKeyMan::GetWalletDescriptor() const +WalletDescriptor DescriptorScriptPubKeyMan::GetWalletDescriptor() const { return m_wallet_descriptor; } -const std::unordered_set<CScript, SaltedSipHasher> DescriptorScriptPubKeyMan::GetScriptPubKeys() const +std::unordered_set<CScript, SaltedSipHasher> DescriptorScriptPubKeyMan::GetScriptPubKeys() const { return GetScriptPubKeys(0); } -const std::unordered_set<CScript, SaltedSipHasher> DescriptorScriptPubKeyMan::GetScriptPubKeys(int32_t minimum_index) const +std::unordered_set<CScript, SaltedSipHasher> DescriptorScriptPubKeyMan::GetScriptPubKeys(int32_t minimum_index) const { LOCK(cs_desc_man); std::unordered_set<CScript, SaltedSipHasher> script_pub_keys; diff --git a/src/wallet/scriptpubkeyman.h b/src/wallet/scriptpubkeyman.h index d74388b3e8..4399ac2087 100644 --- a/src/wallet/scriptpubkeyman.h +++ b/src/wallet/scriptpubkeyman.h @@ -36,7 +36,7 @@ class WalletStorage { public: virtual ~WalletStorage() = default; - virtual const std::string GetDisplayName() const = 0; + virtual std::string GetDisplayName() const = 0; virtual WalletDatabase& GetDatabase() const = 0; virtual bool IsWalletFlagSet(uint64_t) const = 0; virtual void UnsetBlankWalletFlag(WalletBatch&) = 0; @@ -243,7 +243,7 @@ public: virtual uint256 GetID() const { return uint256(); } /** Returns a set of all the scriptPubKeys that this ScriptPubKeyMan watches */ - virtual const std::unordered_set<CScript, SaltedSipHasher> GetScriptPubKeys() const { return {}; }; + virtual std::unordered_set<CScript, SaltedSipHasher> GetScriptPubKeys() const { return {}; }; /** Prepends the wallet name in logging output to ease debugging in multi-wallet use cases */ template<typename... Params> @@ -512,7 +512,7 @@ public: const std::map<CKeyID, int64_t>& GetAllReserveKeys() const { return m_pool_key_to_index; } std::set<CKeyID> GetKeys() const override; - const std::unordered_set<CScript, SaltedSipHasher> GetScriptPubKeys() const override; + std::unordered_set<CScript, SaltedSipHasher> GetScriptPubKeys() const override; /** Get the DescriptorScriptPubKeyMans (with private keys) that have the same scriptPubKeys as this LegacyScriptPubKeyMan. * Does not modify this ScriptPubKeyMan. */ @@ -641,9 +641,9 @@ public: void AddDescriptorKey(const CKey& key, const CPubKey &pubkey); void WriteDescriptor(); - const WalletDescriptor GetWalletDescriptor() const EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man); - const std::unordered_set<CScript, SaltedSipHasher> GetScriptPubKeys() const override; - const std::unordered_set<CScript, SaltedSipHasher> GetScriptPubKeys(int32_t minimum_index) const; + WalletDescriptor GetWalletDescriptor() const EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man); + std::unordered_set<CScript, SaltedSipHasher> GetScriptPubKeys() const override; + std::unordered_set<CScript, SaltedSipHasher> GetScriptPubKeys(int32_t minimum_index) const; int32_t GetEndRange() const; bool GetDescriptorString(std::string& out, const bool priv) const; diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index 53321e98ee..f056c54734 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -43,7 +43,7 @@ static_assert(WALLET_INCREMENTAL_RELAY_FEE >= DEFAULT_INCREMENTAL_RELAY_FEE, "wa BOOST_FIXTURE_TEST_SUITE(wallet_tests, WalletTestingSetup) -static const std::shared_ptr<CWallet> TestLoadWallet(WalletContext& context) +static std::shared_ptr<CWallet> TestLoadWallet(WalletContext& context) { DatabaseOptions options; options.create_flags = WALLET_FLAG_DESCRIPTORS; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index aadad258a9..5a92dbe428 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3871,10 +3871,7 @@ std::optional<MigrationData> CWallet::GetDescriptorsForLegacy(bilingual_str& err AssertLockHeld(cs_wallet); LegacyScriptPubKeyMan* legacy_spkm = GetLegacyScriptPubKeyMan(); - if (!legacy_spkm) { - error = _("Error: This wallet is already a descriptor wallet"); - return std::nullopt; - } + assert(legacy_spkm); std::optional<MigrationData> res = legacy_spkm->MigrateToDescriptor(); if (res == std::nullopt) { @@ -4170,6 +4167,11 @@ bool DoMigration(CWallet& wallet, WalletContext& context, bilingual_str& error, util::Result<MigrationResult> MigrateLegacyToDescriptor(std::shared_ptr<CWallet>&& wallet, WalletContext& context) { + // Before anything else, check if there is something to migrate. + if (!wallet->GetLegacyScriptPubKeyMan()) { + return util::Error{_("Error: This wallet is already a descriptor wallet")}; + } + MigrationResult res; bilingual_str error; std::vector<bilingual_str> warnings; diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 8b7e6dd526..f104a15f98 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -821,7 +821,8 @@ public: bool IsLegacy() const; /** Returns a bracketed wallet name for displaying in logs, will return [default wallet] if the wallet has no name */ - const std::string GetDisplayName() const override { + std::string GetDisplayName() const override + { std::string wallet_name = GetName().length() == 0 ? "default wallet" : GetName(); return strprintf("[%s]", wallet_name); }; @@ -954,10 +955,10 @@ private: using Clock = std::chrono::steady_clock; using NowFn = std::function<Clock::time_point()>; CWallet& m_wallet; - bool m_could_reserve; + bool m_could_reserve{false}; NowFn m_now; public: - explicit WalletRescanReserver(CWallet& w) : m_wallet(w), m_could_reserve(false) {} + explicit WalletRescanReserver(CWallet& w) : m_wallet(w) {} bool reserve() { diff --git a/src/wallet/wallettool.cpp b/src/wallet/wallettool.cpp index f93b666bd5..96537b9873 100644 --- a/src/wallet/wallettool.cpp +++ b/src/wallet/wallettool.cpp @@ -47,7 +47,7 @@ static void WalletCreate(CWallet* wallet_instance, uint64_t wallet_creation_flag wallet_instance->TopUpKeyPool(); } -static const std::shared_ptr<CWallet> MakeWallet(const std::string& name, const fs::path& path, const ArgsManager& args, DatabaseOptions options) +static std::shared_ptr<CWallet> MakeWallet(const std::string& name, const fs::path& path, const ArgsManager& args, DatabaseOptions options) { DatabaseStatus status; bilingual_str error; diff --git a/src/zmq/zmqabstractnotifier.h b/src/zmq/zmqabstractnotifier.h index 6899ee8fa6..cf0ee48f47 100644 --- a/src/zmq/zmqabstractnotifier.h +++ b/src/zmq/zmqabstractnotifier.h @@ -20,7 +20,7 @@ class CZMQAbstractNotifier public: static const int DEFAULT_ZMQ_SNDHWM {1000}; - CZMQAbstractNotifier() : psocket(nullptr), outbound_message_high_water_mark(DEFAULT_ZMQ_SNDHWM) { } + CZMQAbstractNotifier() : outbound_message_high_water_mark(DEFAULT_ZMQ_SNDHWM) {} virtual ~CZMQAbstractNotifier(); template <typename T> @@ -57,7 +57,7 @@ public: virtual bool NotifyTransaction(const CTransaction &transaction); protected: - void *psocket; + void* psocket{nullptr}; std::string type; std::string address; int outbound_message_high_water_mark; // aka SNDHWM diff --git a/src/zmq/zmqnotificationinterface.cpp b/src/zmq/zmqnotificationinterface.cpp index 6dc4737d0a..df129c0830 100644 --- a/src/zmq/zmqnotificationinterface.cpp +++ b/src/zmq/zmqnotificationinterface.cpp @@ -21,7 +21,7 @@ #include <utility> #include <vector> -CZMQNotificationInterface::CZMQNotificationInterface() : pcontext(nullptr) +CZMQNotificationInterface::CZMQNotificationInterface() { } diff --git a/src/zmq/zmqnotificationinterface.h b/src/zmq/zmqnotificationinterface.h index b24d4664da..a43f9bfef3 100644 --- a/src/zmq/zmqnotificationinterface.h +++ b/src/zmq/zmqnotificationinterface.h @@ -39,7 +39,7 @@ protected: private: CZMQNotificationInterface(); - void *pcontext; + void* pcontext{nullptr}; std::list<std::unique_ptr<CZMQAbstractNotifier>> notifiers; }; diff --git a/test/functional/wallet_migration.py b/test/functional/wallet_migration.py index 688ac98617..72c5fe7b84 100755 --- a/test/functional/wallet_migration.py +++ b/test/functional/wallet_migration.py @@ -163,6 +163,10 @@ class WalletMigrationTest(BitcoinTestFramework): assert_equal(basic2.getbalance(), basic2_balance) self.assert_list_txs_equal(basic2.listtransactions(), basic2_txs) + # Now test migration on a descriptor wallet + self.log.info("Test \"nothing to migrate\" when the user tries to migrate a wallet with no legacy data") + assert_raises_rpc_error(-4, "Error: This wallet is already a descriptor wallet", basic2.migratewallet) + def test_multisig(self): default = self.nodes[0].get_wallet_rpc(self.default_wallet_name) |