aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rwxr-xr-xcontrib/guix/guix-attest207
-rwxr-xr-xcontrib/guix/guix-verify113
-rwxr-xr-xcontrib/guix/libexec/build.sh24
-rw-r--r--depends/packages/qt.mk6
-rw-r--r--doc/files.md2
-rw-r--r--src/Makefile.am2
-rw-r--r--src/index/base.cpp15
-rw-r--r--src/index/base.h4
-rw-r--r--src/init.cpp27
-rw-r--r--src/mapport.cpp3
-rw-r--r--src/net.cpp24
-rw-r--r--src/net_permissions.h6
-rw-r--r--src/policy/policy.cpp4
-rw-r--r--src/protocol.cpp1
-rw-r--r--src/protocol.h3
-rw-r--r--src/qt/forms/sendcoinsdialog.ui2
-rw-r--r--src/qt/rpcconsole.cpp13
-rw-r--r--src/qt/rpcconsole.h2
-rw-r--r--src/qt/sendcoinsdialog.cpp4
-rw-r--r--src/rpc/blockchain.cpp2
-rw-r--r--src/rpc/mining.cpp4
-rw-r--r--src/rpc/net.cpp4
-rw-r--r--src/rpc/rawtransaction.cpp6
-rw-r--r--src/test/blockfilter_index_tests.cpp2
-rw-r--r--src/test/coinstatsindex_tests.cpp2
-rw-r--r--src/test/fuzz/net_permissions.cpp4
-rw-r--r--src/test/fuzz/rpc.cpp5
-rw-r--r--src/test/fuzz/script_ops.cpp61
-rw-r--r--src/test/fuzz/timedata.cpp4
-rw-r--r--src/test/fuzz/tx_pool.cpp2
-rw-r--r--src/test/fuzz/util.cpp5
-rw-r--r--src/test/fuzz/util.h5
-rw-r--r--src/test/netbase_tests.cpp26
-rw-r--r--src/test/txindex_tests.cpp2
-rw-r--r--src/test/util/setup_common.cpp4
-rw-r--r--src/torcontrol.cpp3
-rw-r--r--src/txmempool.cpp1
-rw-r--r--src/util/system.h23
-rw-r--r--src/util/thread.cpp27
-rw-r--r--src/util/thread.h18
-rw-r--r--src/wallet/init.cpp8
-rw-r--r--src/wallet/rpcwallet.cpp4
-rwxr-xr-xtest/functional/feature_blockfilterindex_prune.py8
-rw-r--r--test/sanitizer_suppressions/ubsan1
45 files changed, 552 insertions, 143 deletions
diff --git a/.gitignore b/.gitignore
index 5d817c8bbd..b76864cc38 100644
--- a/.gitignore
+++ b/.gitignore
@@ -61,7 +61,7 @@ src/qt/bitcoin-qt.includes
.dirstamp
.libs
.*.swp
-*.*~*
+*~
*.bak
*.rej
*.orig
diff --git a/contrib/guix/guix-attest b/contrib/guix/guix-attest
new file mode 100755
index 0000000000..081d1c0465
--- /dev/null
+++ b/contrib/guix/guix-attest
@@ -0,0 +1,207 @@
+#!/usr/bin/env bash
+export LC_ALL=C
+set -e -o pipefail
+
+# Source the common prelude, which:
+# 1. Checks if we're at the top directory of the Bitcoin Core repository
+# 2. Defines a few common functions and variables
+#
+# shellcheck source=libexec/prelude.bash
+source "$(dirname "${BASH_SOURCE[0]}")/libexec/prelude.bash"
+
+
+###################
+## Sanity Checks ##
+###################
+
+################
+# Required non-builtin commands should be invokable
+################
+
+check_tools cat env basename mkdir xargs find
+if [ -z "$NO_SIGN" ]; then
+ check_tools gpg
+fi
+
+################
+# Required env vars should be non-empty
+################
+
+cmd_usage() {
+cat <<EOF
+Synopsis:
+
+ env GUIX_SIGS_REPO=<path/to/guix.sigs> \\
+ SIGNER=GPG_KEY_NAME[=SIGNER_NAME] \\
+ [ NO_SIGN=1 ]
+ ./contrib/guix/guix-attest
+
+Example w/o overriding signing name:
+
+ env GUIX_SIGS_REPO=/home/achow101/guix.sigs \\
+ SIGNER=achow101 \\
+ ./contrib/guix/guix-attest
+
+Example overriding signing name:
+
+ env GUIX_SIGS_REPO=/home/dongcarl/guix.sigs \\
+ SIGNER=0x96AB007F1A7ED999=dongcarl \\
+ ./contrib/guix/guix-attest
+
+Example w/o signing, just creating SHA256SUMS:
+
+ env GUIX_SIGS_REPO=/home/achow101/guix.sigs \\
+ SIGNER=achow101 \\
+ NO_SIGN=1 \\
+ ./contrib/guix/guix-attest
+
+EOF
+}
+
+if [ -z "$GUIX_SIGS_REPO" ] || [ -z "$SIGNER" ]; then
+ cmd_usage
+ exit 1
+fi
+
+################
+# GUIX_SIGS_REPO should exist as a directory
+################
+
+if [ ! -d "$GUIX_SIGS_REPO" ]; then
+cat << EOF
+ERR: The specified GUIX_SIGS_REPO is not an existent directory:
+
+ '$GUIX_SIGS_REPO'
+
+Hint: Please clone the guix.sigs repository and point to it with the
+ GUIX_SIGS_REPO environment variable.
+
+EOF
+cmd_usage
+exit 1
+fi
+
+################
+# The key specified in SIGNER should be usable
+################
+
+IFS='=' read -r gpg_key_name signer_name <<< "$SIGNER"
+if [ -z "${signer_name}" ]; then
+ signer_name="$gpg_key_name"
+fi
+
+if [ -z "$NO_SIGN" ] && ! gpg --dry-run --list-secret-keys "${gpg_key_name}" >/dev/null 2>&1; then
+ echo "ERR: GPG can't seem to find any key named '${gpg_key_name}'"
+ exit 1
+fi
+
+################
+# We should be able to find at least one output
+################
+
+echo "Looking for build output directories in ${OUTDIR_BASE}"
+
+shopt -s nullglob
+OUTDIRS=( "${OUTDIR_BASE}"/* ) # This expands to an array of directories...
+shopt -u nullglob
+
+if (( ${#OUTDIRS[@]} )); then
+ echo "Found build output directories:"
+ for outdir in "${OUTDIRS[@]}"; do
+ echo " '$outdir'"
+ done
+ echo
+else
+ echo "ERR: Could not find any build output directories in ${OUTDIR_BASE}"
+ exit 1
+fi
+
+
+##############
+## Attest ##
+##############
+
+# Usage: out_name $outdir
+#
+# HOST: The output directory being attested
+#
+out_name() {
+ basename "$1"
+}
+
+# Usage: out_sig_dir $outdir
+#
+# outdir: The output directory being attested
+#
+out_sig_dir() {
+ echo "$GUIX_SIGS_REPO/$VERSION/$(out_name "$1")/$signer_name"
+}
+
+# Accumulate a list of signature directories that already exist...
+outdirs_already_attested_to=()
+
+echo "Attesting to build outputs for version: '${VERSION}'"
+echo ""
+
+# MAIN LOGIC: Loop through each output for VERSION and attest to output in
+# GUIX_SIGS_REPO as SIGNER, if attestation does not exist
+for outdir in "${OUTDIRS[@]}"; do
+ if [ -e "${outdir}/SKIPATTEST.TAG" ]; then
+ echo "${outname}: SKIPPING: Output directory marked with SKIPATTEST.TAG file"
+ continue
+ fi
+ outname="$(out_name "$outdir")"
+ outsigdir="$(out_sig_dir "$outdir")"
+ if [ -e "$outsigdir" ]; then
+ echo "${outname}: SKIPPING: Signature directory already exists in the specified guix.sigs repository"
+ outdirs_already_attested_to+=("$outdir")
+ else
+ # Clean up incomplete sigdir if something fails (likely gpg)
+ trap 'rm -rf "$outsigdir"' ERR
+
+ mkdir -p "$outsigdir"
+
+ (
+ cd "$outdir"
+
+ if [ -e inputs.SHA256SUMS ]; then
+ echo "${outname}: Including existent input SHA256SUMS"
+ cat inputs.SHA256SUMS >> "$outsigdir"/SHA256SUMS
+ fi
+
+ echo "${outname}: Hashing build outputs to produce SHA256SUMS"
+ files="$(find -L . -type f ! -iname '*.SHA256SUMS')"
+ if [ -n "$files" ]; then
+ cut -c3- <<< "$files" | env LC_ALL=C sort | xargs sha256sum >> "$outsigdir"/SHA256SUMS
+ else
+ echo "ERR: ${outname}: No outputs found in '${outdir}'"
+ exit 1
+ fi
+ )
+ if [ -z "$NO_SIGN" ]; then
+ echo "${outname}: Signing SHA256SUMS to produce SHA256SUMS.asc"
+ gpg --detach-sign --local-user "$gpg_key_name" --armor --output "$outsigdir"/SHA256SUMS.asc "$outsigdir"/SHA256SUMS
+ else
+ echo "${outname}: Not signing SHA256SUMS as \$NO_SIGN is not empty"
+ fi
+ echo ""
+
+ trap - ERR # Reset ERR trap
+ fi
+done
+
+if (( ${#outdirs_already_attested_to[@]} )); then
+# ...so that we can print them out nicely in a warning message
+cat << EOF
+
+WARN: Signature directories from '$signer_name' already exist in the specified
+ guix.sigs repository for the following output directories and were
+ skipped:
+
+EOF
+for outdir in "${outdirs_already_attested_to[@]}"; do
+ echo " '${outdir}'"
+ echo " Corresponds to: '$(out_sig_dir "$outdir")'"
+ echo ""
+done
+fi
diff --git a/contrib/guix/guix-verify b/contrib/guix/guix-verify
new file mode 100755
index 0000000000..629050956c
--- /dev/null
+++ b/contrib/guix/guix-verify
@@ -0,0 +1,113 @@
+#!/usr/bin/env bash
+export LC_ALL=C
+set -e -o pipefail
+
+# Source the common prelude, which:
+# 1. Checks if we're at the top directory of the Bitcoin Core repository
+# 2. Defines a few common functions and variables
+#
+# shellcheck source=libexec/prelude.bash
+source "$(dirname "${BASH_SOURCE[0]}")/libexec/prelude.bash"
+
+
+###################
+## Sanity Checks ##
+###################
+
+################
+# Required non-builtin commands should be invokable
+################
+
+check_tools cat diff gpg
+
+################
+# Required env vars should be non-empty
+################
+
+cmd_usage() {
+cat <<EOF
+Synopsis:
+
+ env GUIX_SIGS_REPO=<path/to/guix.sigs> ./contrib/guix/guix-verify
+
+EOF
+}
+
+if [ -z "$GUIX_SIGS_REPO" ]; then
+ cmd_usage
+ exit 1
+fi
+
+################
+# GUIX_SIGS_REPO should exist as a directory
+################
+
+if [ ! -d "$GUIX_SIGS_REPO" ]; then
+cat << EOF
+ERR: The specified GUIX_SIGS_REPO is not an existent directory:
+
+ '$GUIX_SIGS_REPO'
+
+Hint: Please clone the guix.sigs repository and point to it with the
+ GUIX_SIGS_REPO environment variable.
+
+EOF
+cmd_usage
+exit 1
+fi
+
+################
+# We should be able to find at least one output
+################
+
+OUTSIGDIR_BASE="${GUIX_SIGS_REPO}/${VERSION}"
+echo "Looking for output signature directories in '${OUTSIGDIR_BASE}'"
+
+shopt -s nullglob
+OUTSIGDIRS=( "$OUTSIGDIR_BASE"/* ) # This expands to an array of directories...
+shopt -u nullglob
+
+if (( ${#OUTSIGDIRS[@]} )); then
+ echo "Found output signature directories:"
+ for outsigdir in "${OUTSIGDIRS[@]}"; do
+ echo " '$outsigdir'"
+ done
+ echo
+else
+ echo "ERR: Could not find any output signature directories in ${OUTSIGDIR_BASE}"
+ exit 1
+fi
+
+
+##############
+## Verify ##
+##############
+
+# MAIN LOGIC: Loop through each output for VERSION and check that the SHA256SUMS
+# and SHA256SUMS.asc file match between signers, using the first
+# available signer as the arbitrary comparison base.
+for outsigdir in "${OUTSIGDIRS[@]}"; do
+ echo "BEGIN: Checking output signatures for $(basename "$outsigdir")"
+ echo ""
+ signer_dirs=( "$outsigdir"/* ) # This expands to an array of directories...
+ compare_signer_dir="${signer_dirs[0]}" # ...we just want the first one
+ for current_signer_dir in "${signer_dirs[@]}"; do
+ if ! gpg --quiet --batch --verify "$current_signer_dir"/SHA256SUMS.asc "$current_signer_dir"/SHA256SUMS; then
+ echo "ERR: Failed to verify GPG signature in '${current_signer_dir}/SHA256SUMS.asc'"
+ echo ""
+ echo "Hint: Either the signature is invalid or the public key is missing"
+ echo ""
+ elif ! diff --report-identical "$compare_signer_dir"/SHA256SUMS "$current_signer_dir"/SHA256SUMS; then
+ echo "ERR: The SHA256SUMS attestation in these two directories differ:"
+ echo " '${compare_signer_dir}'"
+ echo " '${current_signer_dir}'"
+ echo ""
+ else
+ echo "Verified: '${current_signer_dir}'"
+ echo ""
+ fi
+ done
+ echo "DONE: Checking output signatures for $(basename "$outsigdir")"
+ echo ""
+ echo ""
+done
diff --git a/contrib/guix/libexec/build.sh b/contrib/guix/libexec/build.sh
index e95617e2e2..00cb494963 100755
--- a/contrib/guix/libexec/build.sh
+++ b/contrib/guix/libexec/build.sh
@@ -33,6 +33,9 @@ Required environment variables as seen inside the container:
OUTDIR: ${OUTDIR:?not set}
EOF
+ACTUAL_OUTDIR="${OUTDIR}"
+OUTDIR="${DISTSRC}/output"
+
#####################
# Environment Setup #
#####################
@@ -224,9 +227,25 @@ GIT_ARCHIVE="${DIST_ARCHIVE_BASE}/${DISTNAME}.tar.gz"
# Create the source tarball if not already there
if [ ! -e "$GIT_ARCHIVE" ]; then
mkdir -p "$(dirname "$GIT_ARCHIVE")"
+ touch "${DIST_ARCHIVE_BASE}"/SKIPATTEST.TAG
git archive --prefix="${DISTNAME}/" --output="$GIT_ARCHIVE" HEAD
fi
+# tmpdir="$(mktemp -d)"
+# (
+# cd "$tmpdir"
+# mkdir -p inputs
+# ln -sf --target-directory=inputs "$GIT_ARCHIVE"
+
+# mkdir -p "$OUTDIR"
+# find -L inputs -type f -print0 | xargs -0 sha256sum > "${OUTDIR}/inputs.SHA256SUMS"
+# )
+
+mkdir -p "$OUTDIR"
+cat << EOF > "$OUTDIR"/inputs.SHA256SUMS
+$(sha256sum "$GIT_ARCHIVE" | cut -d' ' -f1) inputs/$(basename "$GIT_ARCHIVE")
+EOF
+
###########################
# Binary Tarball Building #
###########################
@@ -292,7 +311,8 @@ mkdir -p "$DISTSRC"
# version symbols for Linux distro back-compatibility.
make -C src --jobs=1 check-symbols ${V:+V=1}
- mkdir -p ${OUTDIR}
+ mkdir -p "$OUTDIR"
+
# Make the os-specific installers
case "$HOST" in
*mingw*)
@@ -427,3 +447,5 @@ mkdir -p "$DISTSRC"
;;
esac
) # $DISTSRC
+
+mv --no-target-directory "$OUTDIR" "$ACTUAL_OUTDIR"
diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk
index 8b5bfa6895..d23a64923b 100644
--- a/depends/packages/qt.mk
+++ b/depends/packages/qt.mk
@@ -148,6 +148,9 @@ $(package)_config_opts_s390x_linux = -platform linux-g++ -xplatform bitcoin-linu
$(package)_config_opts_mingw32 = -no-opengl
$(package)_config_opts_mingw32 += -no-dbus
$(package)_config_opts_mingw32 += -xplatform win32-g++
+$(package)_config_opts_mingw32 += "QMAKE_CFLAGS = '$($(package)_cflags) $($(package)_cppflags)'"
+$(package)_config_opts_mingw32 += "QMAKE_CXXFLAGS = '$($(package)_cflags) $($(package)_cppflags)'"
+$(package)_config_opts_mingw32 += "QMAKE_LFLAGS = '$($(package)_ldflags)'"
$(package)_config_opts_mingw32 += -device-option CROSS_COMPILE="$(host)-"
$(package)_config_opts_mingw32 += -pch
@@ -240,9 +243,6 @@ define $(package)_preprocess_cmds
echo "!host_build: QMAKE_CFLAGS += $($(package)_cflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \
echo "!host_build: QMAKE_CXXFLAGS += $($(package)_cxxflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \
echo "!host_build: QMAKE_LFLAGS += $($(package)_ldflags)" >> qtbase/mkspecs/common/gcc-base.conf && \
- sed -i.old "s|QMAKE_CFLAGS += |!host_build: QMAKE_CFLAGS = $($(package)_cflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \
- sed -i.old "s|QMAKE_CXXFLAGS += |!host_build: QMAKE_CXXFLAGS = $($(package)_cxxflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \
- sed -i.old "0,/^QMAKE_LFLAGS_/s|^QMAKE_LFLAGS_|!host_build: QMAKE_LFLAGS = $($(package)_ldflags)\n&|" qtbase/mkspecs/win32-g++/qmake.conf && \
sed -i.old "s|QMAKE_CC = \$$$$\$$$${CROSS_COMPILE}clang|QMAKE_CC = $($(package)_cc)|" qtbase/mkspecs/common/clang.conf && \
sed -i.old "s|QMAKE_CXX = \$$$$\$$$${CROSS_COMPILE}clang++|QMAKE_CXX = $($(package)_cxx)|" qtbase/mkspecs/common/clang.conf && \
sed -i.old "s/LIBRARY_PATH/(CROSS_)?\0/g" qtbase/mkspecs/features/toolchain.prf
diff --git a/doc/files.md b/doc/files.md
index 695ea6f448..353efe348d 100644
--- a/doc/files.md
+++ b/doc/files.md
@@ -60,7 +60,7 @@ Subdirectory | File(s) | Description
`./` | `bitcoin.conf` | User-defined [configuration settings](bitcoin-conf.md) for `bitcoind` or `bitcoin-qt`. File is not written to by the software and must be created manually. Path can be specified by `-conf` option
`./` | `bitcoind.pid` | Stores the process ID (PID) of `bitcoind` or `bitcoin-qt` while running; created at start and deleted on shutdown; can be specified by `-pid` option
`./` | `debug.log` | Contains debug information and general logging generated by `bitcoind` or `bitcoin-qt`; can be specified by `-debuglogfile` option
-`./` | `fee_estimates.dat` | Stores statistics used to estimate minimum transaction fees and priorities required for confirmation
+`./` | `fee_estimates.dat` | Stores statistics used to estimate minimum transaction fees required for confirmation
`./` | `guisettings.ini.bak` | Backup of former [GUI settings](#gui-settings) after `-resetguisettings` option is used
`./` | `ip_asn.map` | IP addresses to Autonomous System Numbers (ASNs) mapping used for bucketing of the peers; path can be specified with the `-asmap` option
`./` | `mempool.dat` | Dump of the mempool's transactions
diff --git a/src/Makefile.am b/src/Makefile.am
index 2b389e4b0a..770bb76226 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -258,6 +258,7 @@ BITCOIN_CORE_H = \
util/spanparsing.h \
util/string.h \
util/system.h \
+ util/thread.h \
util/threadnames.h \
util/time.h \
util/tokenpipe.h \
@@ -591,6 +592,7 @@ libbitcoin_util_a_SOURCES = \
util/rbf.cpp \
util/readwritefile.cpp \
util/settings.cpp \
+ util/thread.cpp \
util/threadnames.cpp \
util/spanparsing.cpp \
util/strencodings.cpp \
diff --git a/src/index/base.cpp b/src/index/base.cpp
index 357c4fbaf9..4079fc4569 100644
--- a/src/index/base.cpp
+++ b/src/index/base.cpp
@@ -8,7 +8,7 @@
#include <node/ui_interface.h>
#include <shutdown.h>
#include <tinyformat.h>
-#include <util/system.h>
+#include <util/thread.h>
#include <util/translation.h>
#include <validation.h> // For g_chainman
#include <warnings.h>
@@ -98,9 +98,7 @@ bool BaseIndex::Init()
}
}
if (prune_violation) {
- // throw error and graceful shutdown if we can't build the index
- FatalError("%s: %s best block of the index goes beyond pruned data. Please disable the index or reindex (which will download the whole blockchain again)", __func__, GetName());
- return false;
+ return InitError(strprintf(Untranslated("%s best block of the index goes beyond pruned data. Please disable the index or reindex (which will download the whole blockchain again)"), GetName()));
}
}
return true;
@@ -339,18 +337,17 @@ void BaseIndex::Interrupt()
m_interrupt();
}
-void BaseIndex::Start()
+bool BaseIndex::Start()
{
// Need to register this ValidationInterface before running Init(), so that
// callbacks are not missed if Init sets m_synced to true.
RegisterValidationInterface(this);
if (!Init()) {
- FatalError("%s: %s failed to initialize", __func__, GetName());
- return;
+ return false;
}
- m_thread_sync = std::thread(&TraceThread<std::function<void()>>, GetName(),
- std::bind(&BaseIndex::ThreadSync, this));
+ m_thread_sync = std::thread(&util::TraceThread, GetName(), [this] { ThreadSync(); });
+ return true;
}
void BaseIndex::Stop()
diff --git a/src/index/base.h b/src/index/base.h
index d887620524..59eefab29e 100644
--- a/src/index/base.h
+++ b/src/index/base.h
@@ -84,7 +84,7 @@ protected:
const CBlockIndex* CurrentIndex() { return m_best_block_index.load(); };
/// Initialize internal state from the database and block index.
- virtual bool Init();
+ [[nodiscard]] virtual bool Init();
/// Write update index entries for a newly connected block.
virtual bool WriteBlock(const CBlock& block, const CBlockIndex* pindex) { return true; }
@@ -117,7 +117,7 @@ public:
/// Start initializes the sync state and registers the instance as a
/// ValidationInterface so that it stays in sync with blockchain updates.
- void Start();
+ [[nodiscard]] bool Start();
/// Stops the instance from staying in sync with blockchain updates.
void Stop();
diff --git a/src/init.cpp b/src/init.cpp
index c8974c32ca..89e152e56f 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -59,6 +59,7 @@
#include <util/moneystr.h>
#include <util/string.h>
#include <util/system.h>
+#include <util/thread.h>
#include <util/threadnames.h>
#include <util/translation.h>
#include <validation.h>
@@ -519,25 +520,25 @@ void SetupServerArgs(NodeContext& node)
argsman.AddArg("-mocktime=<n>", "Replace actual time with " + UNIX_EPOCH_TIME + " (default: 0)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
argsman.AddArg("-maxsigcachesize=<n>", strprintf("Limit sum of signature cache and script execution cache sizes to <n> MiB (default: %u)", DEFAULT_MAX_SIG_CACHE_SIZE), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
argsman.AddArg("-maxtipage=<n>", strprintf("Maximum tip age in seconds to consider node in initial block download (default: %u)", DEFAULT_MAX_TIP_AGE), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
- argsman.AddArg("-printpriority", strprintf("Log transaction fee per kB when mining blocks (default: %u)", DEFAULT_PRINTPRIORITY), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
+ argsman.AddArg("-printpriority", strprintf("Log transaction fee rate in " + CURRENCY_UNIT + "/kvB when mining blocks (default: %u)", DEFAULT_PRINTPRIORITY), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
argsman.AddArg("-uacomment=<cmt>", "Append comment to the user agent string", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);
SetupChainParamsBaseOptions(argsman);
argsman.AddArg("-acceptnonstdtxn", strprintf("Relay and mine \"non-standard\" transactions (%sdefault: %u)", "testnet/regtest only; ", !testnetChainParams->RequireStandard()), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::NODE_RELAY);
- argsman.AddArg("-incrementalrelayfee=<amt>", strprintf("Fee rate (in %s/kB) used to define cost of relay, used for mempool limiting and BIP 125 replacement. (default: %s)", CURRENCY_UNIT, FormatMoney(DEFAULT_INCREMENTAL_RELAY_FEE)), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::NODE_RELAY);
- argsman.AddArg("-dustrelayfee=<amt>", strprintf("Fee rate (in %s/kB) used to define dust, the value of an output such that it will cost more than its value in fees at this fee rate to spend it. (default: %s)", CURRENCY_UNIT, FormatMoney(DUST_RELAY_TX_FEE)), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::NODE_RELAY);
+ argsman.AddArg("-incrementalrelayfee=<amt>", strprintf("Fee rate (in %s/kvB) used to define cost of relay, used for mempool limiting and BIP 125 replacement. (default: %s)", CURRENCY_UNIT, FormatMoney(DEFAULT_INCREMENTAL_RELAY_FEE)), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::NODE_RELAY);
+ argsman.AddArg("-dustrelayfee=<amt>", strprintf("Fee rate (in %s/kvB) used to define dust, the value of an output such that it will cost more than its value in fees at this fee rate to spend it. (default: %s)", CURRENCY_UNIT, FormatMoney(DUST_RELAY_TX_FEE)), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::NODE_RELAY);
argsman.AddArg("-bytespersigop", strprintf("Equivalent bytes per sigop in transactions for relay and mining (default: %u)", DEFAULT_BYTES_PER_SIGOP), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
argsman.AddArg("-datacarrier", strprintf("Relay and mine data carrier transactions (default: %u)", DEFAULT_ACCEPT_DATACARRIER), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
argsman.AddArg("-datacarriersize", strprintf("Maximum size of data in data carrier transactions we relay and mine (default: %u)", MAX_OP_RETURN_RELAY), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
- argsman.AddArg("-minrelaytxfee=<amt>", strprintf("Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)",
+ argsman.AddArg("-minrelaytxfee=<amt>", strprintf("Fees (in %s/kvB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)",
CURRENCY_UNIT, FormatMoney(DEFAULT_MIN_RELAY_TX_FEE)), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
argsman.AddArg("-whitelistforcerelay", strprintf("Add 'forcerelay' permission to whitelisted inbound peers with default permissions. This will relay transactions even if the transactions were already in the mempool. (default: %d)", DEFAULT_WHITELISTFORCERELAY), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
argsman.AddArg("-whitelistrelay", strprintf("Add 'relay' permission to whitelisted inbound peers with default permissions. This will accept relayed transactions even when not relaying transactions (default: %d)", DEFAULT_WHITELISTRELAY), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
argsman.AddArg("-blockmaxweight=<n>", strprintf("Set maximum BIP141 block weight (default: %d)", DEFAULT_BLOCK_MAX_WEIGHT), ArgsManager::ALLOW_ANY, OptionsCategory::BLOCK_CREATION);
- argsman.AddArg("-blockmintxfee=<amt>", strprintf("Set lowest fee rate (in %s/kB) for transactions to be included in block creation. (default: %s)", CURRENCY_UNIT, FormatMoney(DEFAULT_BLOCK_MIN_TX_FEE)), ArgsManager::ALLOW_ANY, OptionsCategory::BLOCK_CREATION);
+ argsman.AddArg("-blockmintxfee=<amt>", strprintf("Set lowest fee rate (in %s/kvB) for transactions to be included in block creation. (default: %s)", CURRENCY_UNIT, FormatMoney(DEFAULT_BLOCK_MIN_TX_FEE)), ArgsManager::ALLOW_ANY, OptionsCategory::BLOCK_CREATION);
argsman.AddArg("-blockversion=<n>", "Override block version to test forking scenarios", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::BLOCK_CREATION);
argsman.AddArg("-rest", strprintf("Accept public REST requests (default: %u)", DEFAULT_REST_ENABLE), ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
@@ -1114,7 +1115,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
node.scheduler = std::make_unique<CScheduler>();
// Start the lightweight task scheduler thread
- node.scheduler->m_service_thread = std::thread([&] { TraceThread("scheduler", [&] { node.scheduler->serviceQueue(); }); });
+ node.scheduler->m_service_thread = std::thread(util::TraceThread, "scheduler", [&] { node.scheduler->serviceQueue(); });
// Gather some entropy once per minute.
node.scheduler->scheduleEvery([]{
@@ -1549,17 +1550,23 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
// ********************************************************* Step 8: start indexers
if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) {
g_txindex = std::make_unique<TxIndex>(nTxIndexCache, false, fReindex);
- g_txindex->Start();
+ if (!g_txindex->Start()) {
+ return false;
+ }
}
for (const auto& filter_type : g_enabled_filter_types) {
InitBlockFilterIndex(filter_type, filter_index_cache, false, fReindex);
- GetBlockFilterIndex(filter_type)->Start();
+ if (!GetBlockFilterIndex(filter_type)->Start()) {
+ return false;
+ }
}
if (args.GetBoolArg("-coinstatsindex", DEFAULT_COINSTATSINDEX)) {
g_coin_stats_index = std::make_unique<CoinStatsIndex>(/* cache size */ 0, false, fReindex);
- g_coin_stats_index->Start();
+ if (!g_coin_stats_index->Start()) {
+ return false;
+ }
}
// ********************************************************* Step 9: load wallet
@@ -1629,7 +1636,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
vImportFiles.push_back(strFile);
}
- chainman.m_load_block = std::thread(&TraceThread<std::function<void()>>, "loadblk", [=, &chainman, &args] {
+ chainman.m_load_block = std::thread(&util::TraceThread, "loadblk", [=, &chainman, &args] {
ThreadImport(chainman, vImportFiles, args);
});
diff --git a/src/mapport.cpp b/src/mapport.cpp
index 2df4ce45d2..135efb561e 100644
--- a/src/mapport.cpp
+++ b/src/mapport.cpp
@@ -15,6 +15,7 @@
#include <netbase.h>
#include <threadinterrupt.h>
#include <util/system.h>
+#include <util/thread.h>
#ifdef USE_NATPMP
#include <compat.h>
@@ -255,7 +256,7 @@ void StartThreadMapPort()
{
if (!g_mapport_thread.joinable()) {
assert(!g_mapport_interrupt);
- g_mapport_thread = std::thread(std::bind(&TraceThread<void (*)()>, "mapport", &ThreadMapPort));
+ g_mapport_thread = std::thread(&util::TraceThread, "mapport", &ThreadMapPort);
}
}
diff --git a/src/net.cpp b/src/net.cpp
index ef4521d38a..bbc0b81056 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -23,6 +23,7 @@
#include <scheduler.h>
#include <util/sock.h>
#include <util/strencodings.h>
+#include <util/thread.h>
#include <util/translation.h>
#ifdef WIN32
@@ -2399,8 +2400,9 @@ NodeId CConnman::GetNewNodeId()
bool CConnman::Bind(const CService &addr, unsigned int flags, NetPermissionFlags permissions) {
- if (!(flags & BF_EXPLICIT) && !IsReachable(addr))
+ if (!(flags & BF_EXPLICIT) && !IsReachable(addr)) {
return false;
+ }
bilingual_str strError;
if (!BindListenPort(addr, strError, permissions)) {
if ((flags & BF_REPORT_ERROR) && clientInterface) {
@@ -2409,7 +2411,7 @@ bool CConnman::Bind(const CService &addr, unsigned int flags, NetPermissionFlags
return false;
}
- if (addr.IsRoutable() && fDiscover && !(flags & BF_DONT_ADVERTISE) && !(permissions & PF_NOBAN)) {
+ if (addr.IsRoutable() && fDiscover && !(flags & BF_DONT_ADVERTISE) && !NetPermissions::HasFlag(permissions, NetPermissionFlags::PF_NOBAN)) {
AddLocal(addr, LOCAL_BIND);
}
@@ -2518,15 +2520,15 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
}
// Send and receive from sockets, accept connections
- threadSocketHandler = std::thread(&TraceThread<std::function<void()> >, "net", std::function<void()>(std::bind(&CConnman::ThreadSocketHandler, this)));
+ threadSocketHandler = std::thread(&util::TraceThread, "net", [this] { ThreadSocketHandler(); });
if (!gArgs.GetBoolArg("-dnsseed", DEFAULT_DNSSEED))
LogPrintf("DNS seeding disabled\n");
else
- threadDNSAddressSeed = std::thread(&TraceThread<std::function<void()> >, "dnsseed", std::function<void()>(std::bind(&CConnman::ThreadDNSAddressSeed, this)));
+ threadDNSAddressSeed = std::thread(&util::TraceThread, "dnsseed", [this] { ThreadDNSAddressSeed(); });
// Initiate manual connections
- threadOpenAddedConnections = std::thread(&TraceThread<std::function<void()> >, "addcon", std::function<void()>(std::bind(&CConnman::ThreadOpenAddedConnections, this)));
+ threadOpenAddedConnections = std::thread(&util::TraceThread, "addcon", [this] { ThreadOpenAddedConnections(); });
if (connOptions.m_use_addrman_outgoing && !connOptions.m_specified_outgoing.empty()) {
if (clientInterface) {
@@ -2536,16 +2538,18 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
}
return false;
}
- if (connOptions.m_use_addrman_outgoing || !connOptions.m_specified_outgoing.empty())
- threadOpenConnections = std::thread(&TraceThread<std::function<void()> >, "opencon", std::function<void()>(std::bind(&CConnman::ThreadOpenConnections, this, connOptions.m_specified_outgoing)));
+ if (connOptions.m_use_addrman_outgoing || !connOptions.m_specified_outgoing.empty()) {
+ threadOpenConnections = std::thread(
+ &util::TraceThread, "opencon",
+ [this, connect = connOptions.m_specified_outgoing] { ThreadOpenConnections(connect); });
+ }
// Process messages
- threadMessageHandler = std::thread(&TraceThread<std::function<void()> >, "msghand", std::function<void()>(std::bind(&CConnman::ThreadMessageHandler, this)));
+ threadMessageHandler = std::thread(&util::TraceThread, "msghand", [this] { ThreadMessageHandler(); });
if (connOptions.m_i2p_accept_incoming && m_i2p_sam_session.get() != nullptr) {
threadI2PAcceptIncoming =
- std::thread(&TraceThread<std::function<void()>>, "i2paccept",
- std::function<void()>(std::bind(&CConnman::ThreadI2PAcceptIncoming, this)));
+ std::thread(&util::TraceThread, "i2paccept", [this] { ThreadI2PAcceptIncoming(); });
}
// Dump network addresses
diff --git a/src/net_permissions.h b/src/net_permissions.h
index bba0ea1695..142b317bf6 100644
--- a/src/net_permissions.h
+++ b/src/net_permissions.h
@@ -51,8 +51,14 @@ public:
{
flags = static_cast<NetPermissionFlags>(flags | f);
}
+ //! ClearFlag is only called with `f` == NetPermissionFlags::PF_ISIMPLICIT.
+ //! If that should change in the future, be aware that ClearFlag should not
+ //! be called with a subflag of a multiflag, e.g. NetPermissionFlags::PF_RELAY
+ //! or NetPermissionFlags::PF_DOWNLOAD, as that would leave `flags` in an
+ //! invalid state corresponding to none of the existing flags.
static inline void ClearFlag(NetPermissionFlags& flags, NetPermissionFlags f)
{
+ assert(f == NetPermissionFlags::PF_ISIMPLICIT);
flags = static_cast<NetPermissionFlags>(flags & ~f);
}
};
diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp
index 2b5fd4179d..9e433584e7 100644
--- a/src/policy/policy.cpp
+++ b/src/policy/policy.cpp
@@ -21,12 +21,12 @@ CAmount GetDustThreshold(const CTxOut& txout, const CFeeRate& dustRelayFeeIn)
// need a CTxIn of at least 148 bytes to spend:
// so dust is a spendable txout less than
// 182*dustRelayFee/1000 (in satoshis).
- // 546 satoshis at the default rate of 3000 sat/kB.
+ // 546 satoshis at the default rate of 3000 sat/kvB.
// A typical spendable segwit txout is 31 bytes big, and will
// need a CTxIn of at least 67 bytes to spend:
// so dust is a spendable txout less than
// 98*dustRelayFee/1000 (in satoshis).
- // 294 satoshis at the default rate of 3000 sat/kB.
+ // 294 satoshis at the default rate of 3000 sat/kvB.
if (txout.scriptPubKey.IsUnspendable())
return 0;
diff --git a/src/protocol.cpp b/src/protocol.cpp
index 0b893b9272..2f77ec18e6 100644
--- a/src/protocol.cpp
+++ b/src/protocol.cpp
@@ -91,7 +91,6 @@ CMessageHeader::CMessageHeader()
{
memset(pchMessageStart, 0, MESSAGE_START_SIZE);
memset(pchCommand, 0, sizeof(pchCommand));
- nMessageSize = -1;
memset(pchChecksum, 0, CHECKSUM_SIZE);
}
diff --git a/src/protocol.h b/src/protocol.h
index f183db0501..c73484bdf6 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -16,6 +16,7 @@
#include <uint256.h>
#include <version.h>
+#include <limits>
#include <stdint.h>
#include <string>
@@ -51,7 +52,7 @@ public:
char pchMessageStart[MESSAGE_START_SIZE];
char pchCommand[COMMAND_SIZE];
- uint32_t nMessageSize;
+ uint32_t nMessageSize{std::numeric_limits<uint32_t>::max()};
uint8_t pchChecksum[CHECKSUM_SIZE];
};
diff --git a/src/qt/forms/sendcoinsdialog.ui b/src/qt/forms/sendcoinsdialog.ui
index 1c0f91f736..37da6fedda 100644
--- a/src/qt/forms/sendcoinsdialog.ui
+++ b/src/qt/forms/sendcoinsdialog.ui
@@ -850,7 +850,7 @@
<property name="toolTip">
<string>Specify a custom fee per kB (1,000 bytes) of the transaction's virtual size.
-Note: Since the fee is calculated on a per-byte basis, a fee of "100 satoshis per kB" for a transaction size of 500 bytes (half of 1 kB) would ultimately yield a fee of only 50 satoshis.</string>
+Note: Since the fee is calculated on a per-byte basis, a fee rate of "100 satoshis per kvB" for a transaction size of 500 virtual bytes (half of 1 kvB) would ultimately yield a fee of only 50 satoshis.</string>
</property>
<property name="text">
<string>per kilobyte</string>
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index 58bca97c78..731d6a4eef 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -503,7 +503,7 @@ RPCConsole::RPCConsole(interfaces::Node& node, const PlatformStyle *_platformSty
ui->lineEdit->setMaxLength(16 * 1024 * 1024);
ui->messagesWidget->installEventFilter(this);
- connect(ui->clearButton, &QPushButton::clicked, this, &RPCConsole::clear);
+ connect(ui->clearButton, &QPushButton::clicked, [this] { clear(); });
connect(ui->fontBiggerButton, &QPushButton::clicked, this, &RPCConsole::fontBigger);
connect(ui->fontSmallerButton, &QPushButton::clicked, this, &RPCConsole::fontSmaller);
connect(ui->btnClearTrafficGraph, &QPushButton::clicked, ui->trafficGraph, &TrafficGraphWidget::clear);
@@ -771,20 +771,15 @@ void RPCConsole::setFontSize(int newSize)
// clear console (reset icon sizes, default stylesheet) and re-add the content
float oldPosFactor = 1.0 / ui->messagesWidget->verticalScrollBar()->maximum() * ui->messagesWidget->verticalScrollBar()->value();
- clear(false);
+ clear(/* keep_prompt */ true);
ui->messagesWidget->setHtml(str);
ui->messagesWidget->verticalScrollBar()->setValue(oldPosFactor * ui->messagesWidget->verticalScrollBar()->maximum());
}
-void RPCConsole::clear(bool clearHistory)
+void RPCConsole::clear(bool keep_prompt)
{
ui->messagesWidget->clear();
- if(clearHistory)
- {
- history.clear();
- historyPtr = 0;
- }
- ui->lineEdit->clear();
+ if (!keep_prompt) ui->lineEdit->clear();
ui->lineEdit->setFocus();
// Add smoothly scaled icon images.
diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h
index 5182d60a0d..14d8900716 100644
--- a/src/qt/rpcconsole.h
+++ b/src/qt/rpcconsole.h
@@ -99,7 +99,7 @@ private Q_SLOTS:
void updateDetailWidget();
public Q_SLOTS:
- void clear(bool clearHistory = true);
+ void clear(bool keep_prompt = false);
void fontBigger();
void fontSmaller();
void setFontSize(int newSize);
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index 1772f7cb56..e3ea6e9015 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -736,7 +736,7 @@ void SendCoinsDialog::updateFeeMinimizedLabel()
if (ui->radioSmartFee->isChecked())
ui->labelFeeMinimized->setText(ui->labelSmartFee->text());
else {
- ui->labelFeeMinimized->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), ui->customFee->value()) + "/kB");
+ ui->labelFeeMinimized->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), ui->customFee->value()) + "/kvB");
}
}
@@ -771,7 +771,7 @@ void SendCoinsDialog::updateSmartFeeLabel()
FeeReason reason;
CFeeRate feeRate = CFeeRate(model->wallet().getMinimumFee(1000, *m_coin_control, &returned_target, &reason));
- ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), feeRate.GetFeePerK()) + "/kB");
+ ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), feeRate.GetFeePerK()) + "/kvB");
if (reason == FeeReason::FALLBACK) {
ui->labelSmartFee2->show(); // (Smart fee not initialized yet. This usually takes a few blocks...)
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index 81cb802357..f2b99579b7 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -1663,7 +1663,7 @@ static RPCHelpMan getmempoolinfo()
{RPCResult::Type::NUM, "usage", "Total memory usage for the mempool"},
{RPCResult::Type::STR_AMOUNT, "total_fee", "Total fees for the mempool in " + CURRENCY_UNIT + ", ignoring modified fees through prioritizetransaction"},
{RPCResult::Type::NUM, "maxmempool", "Maximum memory usage for the mempool"},
- {RPCResult::Type::STR_AMOUNT, "mempoolminfee", "Minimum fee rate in " + CURRENCY_UNIT + "/kB for tx to be accepted. Is the maximum of minrelaytxfee and minimum mempool fee"},
+ {RPCResult::Type::STR_AMOUNT, "mempoolminfee", "Minimum fee rate in " + CURRENCY_UNIT + "/kvB for tx to be accepted. Is the maximum of minrelaytxfee and minimum mempool fee"},
{RPCResult::Type::STR_AMOUNT, "minrelaytxfee", "Current minimum relay fee for transactions"},
{RPCResult::Type::NUM, "unbroadcastcount", "Current number of transactions that haven't passed initial broadcast yet"}
}},
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
index f7cf1a7851..8190a2f006 100644
--- a/src/rpc/mining.cpp
+++ b/src/rpc/mining.cpp
@@ -1079,7 +1079,7 @@ static RPCHelpMan estimatesmartfee()
RPCResult{
RPCResult::Type::OBJ, "", "",
{
- {RPCResult::Type::NUM, "feerate", /* optional */ true, "estimate fee rate in " + CURRENCY_UNIT + "/kB (only present if no errors were encountered)"},
+ {RPCResult::Type::NUM, "feerate", /* optional */ true, "estimate fee rate in " + CURRENCY_UNIT + "/kvB (only present if no errors were encountered)"},
{RPCResult::Type::ARR, "errors", /* optional */ true, "Errors encountered during processing (if there are any)",
{
{RPCResult::Type::STR, "", "error"},
@@ -1148,7 +1148,7 @@ static RPCHelpMan estimaterawfee()
{
{RPCResult::Type::OBJ, "short", /* optional */ true, "estimate for short time horizon",
{
- {RPCResult::Type::NUM, "feerate", /* optional */ true, "estimate fee rate in " + CURRENCY_UNIT + "/kB"},
+ {RPCResult::Type::NUM, "feerate", /* optional */ true, "estimate fee rate in " + CURRENCY_UNIT + "/kvB"},
{RPCResult::Type::NUM, "decay", "exponential decay (per block) for historical moving average of confirmation data"},
{RPCResult::Type::NUM, "scale", "The resolution of confirmation targets at this time horizon"},
{RPCResult::Type::OBJ, "pass", /* optional */ true, "information about the lowest range of feerates to succeed in meeting the threshold",
diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp
index 382c6f11ff..1f6b6e8d7e 100644
--- a/src/rpc/net.cpp
+++ b/src/rpc/net.cpp
@@ -603,8 +603,8 @@ static RPCHelpMan getnetworkinfo()
{RPCResult::Type::BOOL, "proxy_randomize_credentials", "Whether randomized credentials are used"},
}},
}},
- {RPCResult::Type::NUM, "relayfee", "minimum relay fee for transactions in " + CURRENCY_UNIT + "/kB"},
- {RPCResult::Type::NUM, "incrementalfee", "minimum fee increment for mempool limiting or BIP 125 replacement in " + CURRENCY_UNIT + "/kB"},
+ {RPCResult::Type::NUM, "relayfee", "minimum relay fee rate for transactions in " + CURRENCY_UNIT + "/kvB"},
+ {RPCResult::Type::NUM, "incrementalfee", "minimum fee rate increment for mempool limiting or BIP 125 replacement in " + CURRENCY_UNIT + "/kvB"},
{RPCResult::Type::ARR, "localaddresses", "list of local addresses",
{
{RPCResult::Type::OBJ, "", "",
diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp
index 186a77385a..f1ab1b4687 100644
--- a/src/rpc/rawtransaction.cpp
+++ b/src/rpc/rawtransaction.cpp
@@ -834,7 +834,7 @@ static RPCHelpMan sendrawtransaction()
{"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex string of the raw transaction"},
{"maxfeerate", RPCArg::Type::AMOUNT, RPCArg::Default{FormatMoney(DEFAULT_MAX_RAW_TX_FEE_RATE.GetFeePerK())},
"Reject transactions whose fee rate is higher than the specified value, expressed in " + CURRENCY_UNIT +
- "/kB.\nSet to 0 to accept any fee rate.\n"},
+ "/kvB.\nSet to 0 to accept any fee rate.\n"},
},
RPCResult{
RPCResult::Type::STR_HEX, "", "The transaction hash in hex"
@@ -895,7 +895,7 @@ static RPCHelpMan testmempoolaccept()
{"rawtx", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, ""},
},
},
- {"maxfeerate", RPCArg::Type::AMOUNT, RPCArg::Default{FormatMoney(DEFAULT_MAX_RAW_TX_FEE_RATE.GetFeePerK())}, "Reject transactions whose fee rate is higher than the specified value, expressed in " + CURRENCY_UNIT + "/kB\n"},
+ {"maxfeerate", RPCArg::Type::AMOUNT, RPCArg::Default{FormatMoney(DEFAULT_MAX_RAW_TX_FEE_RATE.GetFeePerK())}, "Reject transactions whose fee rate is higher than the specified value, expressed in " + CURRENCY_UNIT + "/kvB\n"},
},
RPCResult{
RPCResult::Type::ARR, "", "The result of the mempool acceptance test for each raw transaction in the input array.\n"
@@ -1783,7 +1783,7 @@ static RPCHelpMan analyzepsbt()
}},
}},
{RPCResult::Type::NUM, "estimated_vsize", /* optional */ true, "Estimated vsize of the final signed transaction"},
- {RPCResult::Type::STR_AMOUNT, "estimated_feerate", /* optional */ true, "Estimated feerate of the final signed transaction in " + CURRENCY_UNIT + "/kB. Shown only if all UTXO slots in the PSBT have been filled"},
+ {RPCResult::Type::STR_AMOUNT, "estimated_feerate", /* optional */ true, "Estimated feerate of the final signed transaction in " + CURRENCY_UNIT + "/kvB. Shown only if all UTXO slots in the PSBT have been filled"},
{RPCResult::Type::STR_AMOUNT, "fee", /* optional */ true, "The transaction fee paid. Shown only if all UTXO slots in the PSBT have been filled"},
{RPCResult::Type::STR, "next", "Role of the next person that this psbt needs to go to"},
{RPCResult::Type::STR, "error", /* optional */ true, "Error message (if there is one)"},
diff --git a/src/test/blockfilter_index_tests.cpp b/src/test/blockfilter_index_tests.cpp
index 9903ba75cb..1cb1c002f4 100644
--- a/src/test/blockfilter_index_tests.cpp
+++ b/src/test/blockfilter_index_tests.cpp
@@ -131,7 +131,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
// BlockUntilSyncedToCurrentChain should return false before index is started.
BOOST_CHECK(!filter_index.BlockUntilSyncedToCurrentChain());
- filter_index.Start();
+ BOOST_REQUIRE(filter_index.Start());
// Allow filter index to catch up with the block index.
constexpr int64_t timeout_ms = 10 * 1000;
diff --git a/src/test/coinstatsindex_tests.cpp b/src/test/coinstatsindex_tests.cpp
index 3fc7b72077..bf7a80ae5c 100644
--- a/src/test/coinstatsindex_tests.cpp
+++ b/src/test/coinstatsindex_tests.cpp
@@ -32,7 +32,7 @@ BOOST_FIXTURE_TEST_CASE(coinstatsindex_initial_sync, TestChain100Setup)
// is started.
BOOST_CHECK(!coin_stats_index.BlockUntilSyncedToCurrentChain());
- coin_stats_index.Start();
+ BOOST_REQUIRE(coin_stats_index.Start());
// Allow the CoinStatsIndex to catch up with the block index that is syncing
// in a background thread.
diff --git a/src/test/fuzz/net_permissions.cpp b/src/test/fuzz/net_permissions.cpp
index 544a33047b..6fdf4b653c 100644
--- a/src/test/fuzz/net_permissions.cpp
+++ b/src/test/fuzz/net_permissions.cpp
@@ -25,7 +25,7 @@ FUZZ_TARGET(net_permissions)
(void)NetPermissions::ToStrings(net_whitebind_permissions.m_flags);
(void)NetPermissions::AddFlag(net_whitebind_permissions.m_flags, net_permission_flags);
assert(NetPermissions::HasFlag(net_whitebind_permissions.m_flags, net_permission_flags));
- (void)NetPermissions::ClearFlag(net_whitebind_permissions.m_flags, net_permission_flags);
+ (void)NetPermissions::ClearFlag(net_whitebind_permissions.m_flags, NetPermissionFlags::PF_ISIMPLICIT);
(void)NetPermissions::ToStrings(net_whitebind_permissions.m_flags);
}
@@ -35,7 +35,7 @@ FUZZ_TARGET(net_permissions)
(void)NetPermissions::ToStrings(net_whitelist_permissions.m_flags);
(void)NetPermissions::AddFlag(net_whitelist_permissions.m_flags, net_permission_flags);
assert(NetPermissions::HasFlag(net_whitelist_permissions.m_flags, net_permission_flags));
- (void)NetPermissions::ClearFlag(net_whitelist_permissions.m_flags, net_permission_flags);
+ (void)NetPermissions::ClearFlag(net_whitelist_permissions.m_flags, NetPermissionFlags::PF_ISIMPLICIT);
(void)NetPermissions::ToStrings(net_whitelist_permissions.m_flags);
}
}
diff --git a/src/test/fuzz/rpc.cpp b/src/test/fuzz/rpc.cpp
index cf32a79932..9195cc4873 100644
--- a/src/test/fuzz/rpc.cpp
+++ b/src/test/fuzz/rpc.cpp
@@ -168,6 +168,7 @@ const std::vector<std::string> RPC_COMMANDS_SAFE_FOR_FUZZING{
std::string ConsumeScalarRPCArgument(FuzzedDataProvider& fuzzed_data_provider)
{
const size_t max_string_length = 4096;
+ const size_t max_base58_bytes_length{64};
std::string r;
CallOneOf(
fuzzed_data_provider,
@@ -221,11 +222,11 @@ std::string ConsumeScalarRPCArgument(FuzzedDataProvider& fuzzed_data_provider)
},
[&] {
// base58 argument
- r = EncodeBase58(MakeUCharSpan(fuzzed_data_provider.ConsumeRandomLengthString(max_string_length)));
+ r = EncodeBase58(MakeUCharSpan(fuzzed_data_provider.ConsumeRandomLengthString(max_base58_bytes_length)));
},
[&] {
// base58 argument with checksum
- r = EncodeBase58Check(MakeUCharSpan(fuzzed_data_provider.ConsumeRandomLengthString(max_string_length)));
+ r = EncodeBase58Check(MakeUCharSpan(fuzzed_data_provider.ConsumeRandomLengthString(max_base58_bytes_length)));
},
[&] {
// hex encoded block
diff --git a/src/test/fuzz/script_ops.cpp b/src/test/fuzz/script_ops.cpp
index eb1c808a88..4bc709ed35 100644
--- a/src/test/fuzz/script_ops.cpp
+++ b/src/test/fuzz/script_ops.cpp
@@ -14,55 +14,54 @@
FUZZ_TARGET(script_ops)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
- CScript script = ConsumeScript(fuzzed_data_provider);
+ CScript script_mut = ConsumeScript(fuzzed_data_provider);
while (fuzzed_data_provider.remaining_bytes() > 0) {
CallOneOf(
fuzzed_data_provider,
[&] {
CScript s = ConsumeScript(fuzzed_data_provider);
- script = std::move(s);
+ script_mut = std::move(s);
},
[&] {
const CScript& s = ConsumeScript(fuzzed_data_provider);
- script = s;
+ script_mut = s;
},
[&] {
- script << fuzzed_data_provider.ConsumeIntegral<int64_t>();
+ script_mut << fuzzed_data_provider.ConsumeIntegral<int64_t>();
},
[&] {
- script << ConsumeOpcodeType(fuzzed_data_provider);
+ script_mut << ConsumeOpcodeType(fuzzed_data_provider);
},
[&] {
- script << ConsumeScriptNum(fuzzed_data_provider);
+ script_mut << ConsumeScriptNum(fuzzed_data_provider);
},
[&] {
- script << ConsumeRandomLengthByteVector(fuzzed_data_provider);
+ script_mut << ConsumeRandomLengthByteVector(fuzzed_data_provider);
},
[&] {
- script.clear();
- },
- [&] {
- (void)script.GetSigOpCount(false);
- (void)script.GetSigOpCount(true);
- (void)script.GetSigOpCount(script);
- (void)script.HasValidOps();
- (void)script.IsPayToScriptHash();
- (void)script.IsPayToWitnessScriptHash();
- (void)script.IsPushOnly();
- (void)script.IsUnspendable();
- {
- CScript::const_iterator pc = script.begin();
- opcodetype opcode;
- (void)script.GetOp(pc, opcode);
- std::vector<uint8_t> data;
- (void)script.GetOp(pc, opcode, data);
- (void)script.IsPushOnly(pc);
- }
- {
- int version;
- std::vector<uint8_t> program;
- (void)script.IsWitnessProgram(version, program);
- }
+ script_mut.clear();
});
}
+ const CScript& script = script_mut;
+ (void)script.GetSigOpCount(false);
+ (void)script.GetSigOpCount(true);
+ (void)script.GetSigOpCount(script);
+ (void)script.HasValidOps();
+ (void)script.IsPayToScriptHash();
+ (void)script.IsPayToWitnessScriptHash();
+ (void)script.IsPushOnly();
+ (void)script.IsUnspendable();
+ {
+ CScript::const_iterator pc = script.begin();
+ opcodetype opcode;
+ (void)script.GetOp(pc, opcode);
+ std::vector<uint8_t> data;
+ (void)script.GetOp(pc, opcode, data);
+ (void)script.IsPushOnly(pc);
+ }
+ {
+ int version;
+ std::vector<uint8_t> program;
+ (void)script.IsWitnessProgram(version, program);
+ }
}
diff --git a/src/test/fuzz/timedata.cpp b/src/test/fuzz/timedata.cpp
index d7fa66298a..f7dc5f433e 100644
--- a/src/test/fuzz/timedata.cpp
+++ b/src/test/fuzz/timedata.cpp
@@ -15,10 +15,12 @@ FUZZ_TARGET(timedata)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const unsigned int max_size = fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(0, 1000);
+ // A max_size of 0 implies no limit, so cap the max number of insertions to avoid timeouts
+ auto max_to_insert = fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 4000);
// Divide by 2 to avoid signed integer overflow in .median()
const int64_t initial_value = fuzzed_data_provider.ConsumeIntegral<int64_t>() / 2;
CMedianFilter<int64_t> median_filter{max_size, initial_value};
- while (fuzzed_data_provider.remaining_bytes() > 0) {
+ while (fuzzed_data_provider.remaining_bytes() > 0 && --max_to_insert >= 0) {
(void)median_filter.median();
assert(median_filter.size() > 0);
assert(static_cast<size_t>(median_filter.size()) == median_filter.sorted().size());
diff --git a/src/test/fuzz/tx_pool.cpp b/src/test/fuzz/tx_pool.cpp
index 59229987ba..068e207118 100644
--- a/src/test/fuzz/tx_pool.cpp
+++ b/src/test/fuzz/tx_pool.cpp
@@ -84,7 +84,7 @@ void Finish(FuzzedDataProvider& fuzzed_data_provider, MockedTxPool& tx_pool, CCh
{
BlockAssembler::Options options;
options.nBlockMaxWeight = fuzzed_data_provider.ConsumeIntegralInRange(0U, MAX_BLOCK_WEIGHT);
- options.blockMinFeeRate = CFeeRate{ConsumeMoney(fuzzed_data_provider)};
+ options.blockMinFeeRate = CFeeRate{ConsumeMoney(fuzzed_data_provider, /* max */ COIN)};
auto assembler = BlockAssembler{chainstate, *static_cast<CTxMemPool*>(&tx_pool), ::Params(), options};
auto block_template = assembler.CreateNewBlock(CScript{} << OP_TRUE);
Assert(block_template->block.vtx.size() >= 1);
diff --git a/src/test/fuzz/util.cpp b/src/test/fuzz/util.cpp
index 574b694d1a..bcf0b0ce72 100644
--- a/src/test/fuzz/util.cpp
+++ b/src/test/fuzz/util.cpp
@@ -217,6 +217,11 @@ void FillNode(FuzzedDataProvider& fuzzed_data_provider, CNode& node, bool init_v
}
}
+CAmount ConsumeMoney(FuzzedDataProvider& fuzzed_data_provider, const std::optional<CAmount>& max) noexcept
+{
+ return fuzzed_data_provider.ConsumeIntegralInRange<CAmount>(0, max.value_or(MAX_MONEY));
+}
+
int64_t ConsumeTime(FuzzedDataProvider& fuzzed_data_provider, const std::optional<int64_t>& min, const std::optional<int64_t>& max) noexcept
{
// Avoid t=0 (1970-01-01T00:00:00Z) since SetMockTime(0) disables mocktime.
diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h
index 1a83f7a57a..48b7877896 100644
--- a/src/test/fuzz/util.h
+++ b/src/test/fuzz/util.h
@@ -123,10 +123,7 @@ template <typename WeakEnumType, size_t size>
return static_cast<opcodetype>(fuzzed_data_provider.ConsumeIntegralInRange<uint32_t>(0, MAX_OPCODE));
}
-[[nodiscard]] inline CAmount ConsumeMoney(FuzzedDataProvider& fuzzed_data_provider) noexcept
-{
- return fuzzed_data_provider.ConsumeIntegralInRange<CAmount>(0, MAX_MONEY);
-}
+[[nodiscard]] CAmount ConsumeMoney(FuzzedDataProvider& fuzzed_data_provider, const std::optional<CAmount>& max = std::nullopt) noexcept;
[[nodiscard]] int64_t ConsumeTime(FuzzedDataProvider& fuzzed_data_provider, const std::optional<int64_t>& min = std::nullopt, const std::optional<int64_t>& max = std::nullopt) noexcept;
diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp
index 33b56624a8..b316a37c6e 100644
--- a/src/test/netbase_tests.cpp
+++ b/src/test/netbase_tests.cpp
@@ -395,6 +395,28 @@ BOOST_AUTO_TEST_CASE(netpermissions_test)
BOOST_CHECK(NetWhitebindPermissions::TryParse("@1.2.3.4:32", whitebindPermissions, error));
BOOST_CHECK_EQUAL(whitebindPermissions.m_flags, PF_NONE);
+ NetWhitebindPermissions noban, noban_download, download_noban, download;
+
+ // "noban" implies "download"
+ BOOST_REQUIRE(NetWhitebindPermissions::TryParse("noban@1.2.3.4:32", noban, error));
+ BOOST_CHECK_EQUAL(noban.m_flags, NetPermissionFlags::PF_NOBAN);
+ BOOST_CHECK(NetPermissions::HasFlag(noban.m_flags, NetPermissionFlags::PF_DOWNLOAD));
+ BOOST_CHECK(NetPermissions::HasFlag(noban.m_flags, NetPermissionFlags::PF_NOBAN));
+
+ // "noban,download" is equivalent to "noban"
+ BOOST_REQUIRE(NetWhitebindPermissions::TryParse("noban,download@1.2.3.4:32", noban_download, error));
+ BOOST_CHECK_EQUAL(noban_download.m_flags, noban.m_flags);
+
+ // "download,noban" is equivalent to "noban"
+ BOOST_REQUIRE(NetWhitebindPermissions::TryParse("download,noban@1.2.3.4:32", download_noban, error));
+ BOOST_CHECK_EQUAL(download_noban.m_flags, noban.m_flags);
+
+ // "download" excludes (does not imply) "noban"
+ BOOST_REQUIRE(NetWhitebindPermissions::TryParse("download@1.2.3.4:32", download, error));
+ BOOST_CHECK_EQUAL(download.m_flags, NetPermissionFlags::PF_DOWNLOAD);
+ BOOST_CHECK(NetPermissions::HasFlag(download.m_flags, NetPermissionFlags::PF_DOWNLOAD));
+ BOOST_CHECK(!NetPermissions::HasFlag(download.m_flags, NetPermissionFlags::PF_NOBAN));
+
// Happy path, can parse flags
BOOST_CHECK(NetWhitebindPermissions::TryParse("bloom,forcerelay@1.2.3.4:32", whitebindPermissions, error));
// forcerelay should also activate the relay permission
@@ -407,7 +429,7 @@ BOOST_AUTO_TEST_CASE(netpermissions_test)
// Allow dups
BOOST_CHECK(NetWhitebindPermissions::TryParse("bloom,relay,noban,noban@1.2.3.4:32", whitebindPermissions, error));
- BOOST_CHECK_EQUAL(whitebindPermissions.m_flags, PF_BLOOMFILTER | PF_RELAY | PF_NOBAN);
+ BOOST_CHECK_EQUAL(whitebindPermissions.m_flags, PF_BLOOMFILTER | PF_RELAY | PF_NOBAN | PF_DOWNLOAD); // "noban" implies "download"
// Allow empty
BOOST_CHECK(NetWhitebindPermissions::TryParse("bloom,relay,,noban@1.2.3.4:32", whitebindPermissions, error));
@@ -428,6 +450,8 @@ BOOST_AUTO_TEST_CASE(netpermissions_test)
// Happy path for whitelist parsing
BOOST_CHECK(NetWhitelistPermissions::TryParse("noban@1.2.3.4", whitelistPermissions, error));
BOOST_CHECK_EQUAL(whitelistPermissions.m_flags, PF_NOBAN);
+ BOOST_CHECK(NetPermissions::HasFlag(whitelistPermissions.m_flags, NetPermissionFlags::PF_NOBAN));
+
BOOST_CHECK(NetWhitelistPermissions::TryParse("bloom,forcerelay,noban,relay@1.2.3.4/32", whitelistPermissions, error));
BOOST_CHECK_EQUAL(whitelistPermissions.m_flags, PF_BLOOMFILTER | PF_FORCERELAY | PF_NOBAN | PF_RELAY);
BOOST_CHECK(error.empty());
diff --git a/src/test/txindex_tests.cpp b/src/test/txindex_tests.cpp
index 5fc172ee86..082655d811 100644
--- a/src/test/txindex_tests.cpp
+++ b/src/test/txindex_tests.cpp
@@ -27,7 +27,7 @@ BOOST_FIXTURE_TEST_CASE(txindex_initial_sync, TestChain100Setup)
// BlockUntilSyncedToCurrentChain should return false before txindex is started.
BOOST_CHECK(!txindex.BlockUntilSyncedToCurrentChain());
- txindex.Start();
+ BOOST_REQUIRE(txindex.Start());
// Allow tx index to catch up with the block index.
constexpr int64_t timeout_ms = 10 * 1000;
diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp
index ffc5115145..f92e4c4b99 100644
--- a/src/test/util/setup_common.cpp
+++ b/src/test/util/setup_common.cpp
@@ -28,6 +28,8 @@
#include <txdb.h>
#include <util/strencodings.h>
#include <util/string.h>
+#include <util/thread.h>
+#include <util/threadnames.h>
#include <util/time.h>
#include <util/translation.h>
#include <util/url.h>
@@ -135,7 +137,7 @@ ChainTestingSetup::ChainTestingSetup(const std::string& chainName, const std::ve
// We have to run a scheduler thread to prevent ActivateBestChain
// from blocking due to queue overrun.
m_node.scheduler = std::make_unique<CScheduler>();
- m_node.scheduler->m_service_thread = std::thread([&] { TraceThread("scheduler", [&] { m_node.scheduler->serviceQueue(); }); });
+ m_node.scheduler->m_service_thread = std::thread(util::TraceThread, "scheduler", [&] { m_node.scheduler->serviceQueue(); });
GetMainSignals().RegisterBackgroundSignalScheduler(*m_node.scheduler);
pblocktree.reset(new CBlockTreeDB(1 << 20, true));
diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp
index 6666e49a2b..19d0a5da81 100644
--- a/src/torcontrol.cpp
+++ b/src/torcontrol.cpp
@@ -15,6 +15,7 @@
#include <util/readwritefile.h>
#include <util/strencodings.h>
#include <util/system.h>
+#include <util/thread.h>
#include <util/time.h>
#include <deque>
@@ -596,7 +597,7 @@ void StartTorControl(CService onion_service_target)
return;
}
- torControlThread = std::thread(&TraceThread<std::function<void()>>, "torcontrol", [onion_service_target] {
+ torControlThread = std::thread(&util::TraceThread, "torcontrol", [onion_service_target] {
TorControlThread(onion_service_target);
});
}
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index 67549fc13d..5957637e81 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -18,6 +18,7 @@
#include <validation.h>
#include <validationinterface.h>
+#include <cmath>
#include <optional>
CTxMemPoolEntry::CTxMemPoolEntry(const CTransactionRef& _tx, const CAmount& _nFee,
diff --git a/src/util/system.h b/src/util/system.h
index 61f862c93a..f68975ffa3 100644
--- a/src/util/system.h
+++ b/src/util/system.h
@@ -22,7 +22,6 @@
#include <sync.h>
#include <tinyformat.h>
#include <util/settings.h>
-#include <util/threadnames.h>
#include <util/time.h>
#include <any>
@@ -478,28 +477,6 @@ std::string HelpMessageOpt(const std::string& option, const std::string& message
*/
int GetNumCores();
-/**
- * .. and a wrapper that just calls func once
- */
-template <typename Callable> void TraceThread(const char* name, Callable func)
-{
- util::ThreadRename(name);
- try
- {
- LogPrintf("%s thread start\n", name);
- func();
- LogPrintf("%s thread exit\n", name);
- }
- catch (const std::exception& e) {
- PrintExceptionContinue(&e, name);
- throw;
- }
- catch (...) {
- PrintExceptionContinue(nullptr, name);
- throw;
- }
-}
-
std::string CopyrightHolders(const std::string& strPrefix);
/**
diff --git a/src/util/thread.cpp b/src/util/thread.cpp
new file mode 100644
index 0000000000..14be668685
--- /dev/null
+++ b/src/util/thread.cpp
@@ -0,0 +1,27 @@
+// Copyright (c) 2021 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 <util/thread.h>
+
+#include <logging.h>
+#include <util/system.h>
+#include <util/threadnames.h>
+
+#include <exception>
+
+void util::TraceThread(const char* thread_name, std::function<void()> thread_func)
+{
+ util::ThreadRename(thread_name);
+ try {
+ LogPrintf("%s thread start\n", thread_name);
+ thread_func();
+ LogPrintf("%s thread exit\n", thread_name);
+ } catch (const std::exception& e) {
+ PrintExceptionContinue(&e, thread_name);
+ throw;
+ } catch (...) {
+ PrintExceptionContinue(nullptr, thread_name);
+ throw;
+ }
+}
diff --git a/src/util/thread.h b/src/util/thread.h
new file mode 100644
index 0000000000..ca2eccc0c3
--- /dev/null
+++ b/src/util/thread.h
@@ -0,0 +1,18 @@
+// Copyright (c) 2021 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_UTIL_THREAD_H
+#define BITCOIN_UTIL_THREAD_H
+
+#include <functional>
+
+namespace util {
+/**
+ * A wrapper for do-something-once thread functions.
+ */
+void TraceThread(const char* thread_name, std::function<void()> thread_func);
+
+} // namespace util
+
+#endif // BITCOIN_UTIL_THREAD_H
diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp
index 0dc220b6fd..632aae87c9 100644
--- a/src/wallet/init.cpp
+++ b/src/wallet/init.cpp
@@ -46,19 +46,19 @@ void WalletInit::AddWalletOptions(ArgsManager& argsman) const
argsman.AddArg("-avoidpartialspends", strprintf("Group outputs by address, selecting all or none, instead of selecting on a per-output basis. Privacy is improved as an address is only used once (unless someone sends to it after spending from it), but may result in slightly higher fees as suboptimal coin selection may result due to the added limitation (default: %u (always enabled for wallets with \"avoid_reuse\" enabled))", DEFAULT_AVOIDPARTIALSPENDS), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
argsman.AddArg("-changetype", "What type of change to use (\"legacy\", \"p2sh-segwit\", or \"bech32\"). Default is same as -addresstype, except when -addresstype=p2sh-segwit a native segwit output is used when sending to a native segwit address)", ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
argsman.AddArg("-disablewallet", "Do not load the wallet and disable wallet RPC calls", ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
- argsman.AddArg("-discardfee=<amt>", strprintf("The fee rate (in %s/kB) that indicates your tolerance for discarding change by adding it to the fee (default: %s). "
+ argsman.AddArg("-discardfee=<amt>", strprintf("The fee rate (in %s/kvB) that indicates your tolerance for discarding change by adding it to the fee (default: %s). "
"Note: An output is discarded if it is dust at this rate, but we will always discard up to the dust relay fee and a discard fee above that is limited by the fee estimate for the longest target",
CURRENCY_UNIT, FormatMoney(DEFAULT_DISCARD_FEE)), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
- argsman.AddArg("-fallbackfee=<amt>", strprintf("A fee rate (in %s/kB) that will be used when fee estimation has insufficient data. 0 to entirely disable the fallbackfee feature. (default: %s)",
+ argsman.AddArg("-fallbackfee=<amt>", strprintf("A fee rate (in %s/kvB) that will be used when fee estimation has insufficient data. 0 to entirely disable the fallbackfee feature. (default: %s)",
CURRENCY_UNIT, FormatMoney(DEFAULT_FALLBACK_FEE)), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
argsman.AddArg("-keypool=<n>", strprintf("Set key pool size to <n> (default: %u). Warning: Smaller sizes may increase the risk of losing funds when restoring from an old backup, if none of the addresses in the original keypool have been used.", DEFAULT_KEYPOOL_SIZE), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
argsman.AddArg("-maxapsfee=<n>", strprintf("Spend up to this amount in additional (absolute) fees (in %s) if it allows the use of partial spend avoidance (default: %s)", CURRENCY_UNIT, FormatMoney(DEFAULT_MAX_AVOIDPARTIALSPEND_FEE)), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
argsman.AddArg("-maxtxfee=<amt>", strprintf("Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)",
CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MAXFEE)), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);
- argsman.AddArg("-mintxfee=<amt>", strprintf("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)",
+ argsman.AddArg("-mintxfee=<amt>", strprintf("Fee rates (in %s/kvB) smaller than this are considered zero fee for transaction creation (default: %s)",
CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MINFEE)), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
- argsman.AddArg("-paytxfee=<amt>", strprintf("Fee (in %s/kB) to add to transactions you send (default: %s)",
+ argsman.AddArg("-paytxfee=<amt>", strprintf("Fee rate (in %s/kvB) to add to transactions you send (default: %s)",
CURRENCY_UNIT, FormatMoney(CFeeRate{DEFAULT_PAY_TX_FEE}.GetFeePerK())), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
argsman.AddArg("-rescan", "Rescan the block chain for missing wallet transactions on startup", ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
#ifdef ENABLE_EXTERNAL_SIGNER
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index 3f1c1aeab5..326e183a7f 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -2293,10 +2293,10 @@ static RPCHelpMan listlockunspent()
static RPCHelpMan settxfee()
{
return RPCHelpMan{"settxfee",
- "\nSet the transaction fee per kB for this wallet. Overrides the global -paytxfee command line parameter.\n"
+ "\nSet the transaction fee rate in " + CURRENCY_UNIT + "/kvB for this wallet. Overrides the global -paytxfee command line parameter.\n"
"Can be deactivated by passing 0 as the fee. In that case automatic fee selection will be used by default.\n",
{
- {"amount", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "The transaction fee in " + CURRENCY_UNIT + "/kvB"},
+ {"amount", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "The transaction fee rate in " + CURRENCY_UNIT + "/kvB"},
},
RPCResult{
RPCResult::Type::BOOL, "", "Returns true if successful"
diff --git a/test/functional/feature_blockfilterindex_prune.py b/test/functional/feature_blockfilterindex_prune.py
index bada791fba..28d8f2fbbc 100755
--- a/test/functional/feature_blockfilterindex_prune.py
+++ b/test/functional/feature_blockfilterindex_prune.py
@@ -54,11 +54,13 @@ class FeatureBlockfilterindexPruneTest(BitcoinTestFramework):
self.stop_node(0)
self.log.info("make sure we get an init error when starting the node again with block filters")
- with self.nodes[0].assert_debug_log(["basic block filter index best block of the index goes beyond pruned data. Please disable the index or reindex (which will download the whole blockchain again)"]):
- self.nodes[0].assert_start_raises_init_error(extra_args=["-fastprune", "-prune=1", "-blockfilterindex=1"])
+ self.nodes[0].assert_start_raises_init_error(
+ extra_args=["-fastprune", "-prune=1", "-blockfilterindex=1"],
+ expected_msg="Error: basic block filter index best block of the index goes beyond pruned data. Please disable the index or reindex (which will download the whole blockchain again)",
+ )
self.log.info("make sure the node starts again with the -reindex arg")
- self.start_node(0, extra_args = ["-fastprune", "-prune=1", "-blockfilterindex", "-reindex"])
+ self.start_node(0, extra_args=["-fastprune", "-prune=1", "-blockfilterindex", "-reindex"])
if __name__ == '__main__':
diff --git a/test/sanitizer_suppressions/ubsan b/test/sanitizer_suppressions/ubsan
index b66ca00376..4f6f92bd3c 100644
--- a/test/sanitizer_suppressions/ubsan
+++ b/test/sanitizer_suppressions/ubsan
@@ -62,7 +62,6 @@ implicit-integer-sign-change:key.cpp
implicit-integer-sign-change:noui.cpp
implicit-integer-sign-change:policy/fees.cpp
implicit-integer-sign-change:prevector.h
-implicit-integer-sign-change:protocol.cpp
implicit-integer-sign-change:script/bitcoinconsensus.cpp
implicit-integer-sign-change:script/interpreter.cpp
implicit-integer-sign-change:serialize.h