aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xci/test/05_before_script.sh2
-rwxr-xr-xcontrib/devtools/previous_release.py217
-rwxr-xr-xcontrib/devtools/previous_release.sh152
-rwxr-xr-xcontrib/devtools/test_deterministic_coverage.sh1
-rw-r--r--depends/README.md2
-rw-r--r--depends/packages/native_cdrkit.mk4
-rw-r--r--src/consensus/validation.h30
-rw-r--r--src/init.cpp2
-rw-r--r--src/net.h2
-rw-r--r--src/rpc/rawtransaction.cpp20
-rw-r--r--src/test/denialofservice_tests.cpp20
-rw-r--r--src/test/fuzz/addrdb.cpp2
-rw-r--r--src/test/fuzz/script.cpp2
-rw-r--r--src/test/fuzz/scriptnum_ops.cpp2
-rw-r--r--src/test/fuzz/signature_checker.cpp6
-rw-r--r--src/test/fuzz/util.h4
-rw-r--r--src/validation.cpp7
-rw-r--r--src/wallet/bdb.cpp32
-rw-r--r--src/wallet/bdb.h2
-rw-r--r--src/wallet/salvage.cpp6
-rw-r--r--src/wallet/test/wallet_tests.cpp5
-rwxr-xr-xtest/functional/feature_backwards_compatibility.py2
-rwxr-xr-xtest/functional/mempool_compatibility.py2
-rwxr-xr-xtest/functional/p2p_ibd_txrelay.py8
-rwxr-xr-xtest/functional/test_framework/test_framework.py4
-rwxr-xr-xtest/functional/wallet_upgradewallet.py2
26 files changed, 304 insertions, 234 deletions
diff --git a/ci/test/05_before_script.sh b/ci/test/05_before_script.sh
index 057395eba6..131ea21677 100755
--- a/ci/test/05_before_script.sh
+++ b/ci/test/05_before_script.sh
@@ -48,6 +48,6 @@ if [ -z "$NO_DEPENDS" ]; then
fi
if [ -n "$PREVIOUS_RELEASES_TO_DOWNLOAD" ]; then
BEGIN_FOLD previous-versions
- DOCKER_EXEC contrib/devtools/previous_release.sh -b -t "$PREVIOUS_RELEASES_DIR" "${PREVIOUS_RELEASES_TO_DOWNLOAD}"
+ DOCKER_EXEC contrib/devtools/previous_release.py -b -t "$PREVIOUS_RELEASES_DIR" "${PREVIOUS_RELEASES_TO_DOWNLOAD}"
END_FOLD
fi
diff --git a/contrib/devtools/previous_release.py b/contrib/devtools/previous_release.py
new file mode 100755
index 0000000000..5599051cf3
--- /dev/null
+++ b/contrib/devtools/previous_release.py
@@ -0,0 +1,217 @@
+#!/usr/bin/env python3
+#
+# Copyright (c) 2018-2020 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#
+# Download or build previous releases.
+# Needs curl and tar to download a release, or the build dependencies when
+# building a release.
+
+import argparse
+import contextlib
+from fnmatch import fnmatch
+import os
+from pathlib import Path
+import re
+import shutil
+import subprocess
+import sys
+import hashlib
+
+
+@contextlib.contextmanager
+def pushd(new_dir) -> None:
+ previous_dir = os.getcwd()
+ os.chdir(new_dir)
+ try:
+ yield
+ finally:
+ os.chdir(previous_dir)
+
+
+def download_binary(tag, args) -> int:
+ if Path(tag).is_dir():
+ if not args.remove_dir:
+ print('Using cached {}'.format(tag))
+ return 0
+ shutil.rmtree(tag)
+ Path(tag).mkdir()
+ bin_path = 'bin/bitcoin-core-{}'.format(tag[1:])
+ match = re.compile('v(.*)(rc[0-9]+)$').search(tag)
+ if match:
+ bin_path = 'bin/bitcoin-core-{}/test.{}'.format(
+ match.group(1), match.group(2))
+ tarball = 'bitcoin-{tag}-{platform}.tar.gz'.format(
+ tag=tag[1:], platform=args.platform)
+ sha256Sums = "SHA256SUMS-{tag}.asc".format(tag=tag[1:])
+ tarballUrl = 'https://bitcoincore.org/{bin_path}/{tarball}'.format(
+ bin_path=bin_path, tarball=tarball)
+ sha256SumsUrl = 'https://bitcoincore.org/{bin_path}/SHA256SUMS.asc'.format(
+ bin_path=bin_path)
+
+ print('Fetching: {tarballUrl}'.format(tarballUrl=tarballUrl))
+ print('Fetching: {sha256SumsUrl}'.format(sha256SumsUrl=sha256SumsUrl))
+
+ header, status = subprocess.Popen(
+ ['curl', '--head', tarballUrl], stdout=subprocess.PIPE).communicate()
+ if re.search("404 Not Found", header.decode("utf-8")):
+ print("Binary tag was not found")
+ return 1
+
+ curlCmds = [
+ ['curl', '--remote-name', tarballUrl],
+ ['curl', '--output', sha256Sums, sha256SumsUrl],
+ ]
+
+ for cmd in curlCmds:
+ ret = subprocess.run(cmd).returncode
+ if ret:
+ return ret
+
+ hasher = hashlib.sha256()
+ with open(tarball, "rb") as afile:
+ hasher.update(afile.read())
+ tarballHash = hasher.hexdigest()
+ tarballHash = '{} {}\n'.format(tarballHash, tarball)
+ with open(sha256Sums, 'r', encoding="utf-8") as afile:
+ shasums = afile.readlines()
+
+ if tarballHash not in shasums:
+ print("Checksum did not match")
+ Path(tarball).unlink()
+ return 1
+ print("Checksum matched")
+
+ # Bitcoin Core Release Signing Keys v0.11.0+
+ signingKey = "01EA5486DE18A882D4C2684590C8019E36C2E964"
+
+ isKeyPresent = subprocess.run(
+ ["gpg", "--list-keys", signingKey]).returncode
+ if isKeyPresent:
+ return isKeyPresent
+
+ isVerified = subprocess.run(
+ ["gpg", "--verify", sha256Sums]).returncode
+ if isVerified:
+ return isVerified
+
+ # Extract tarball
+ ret = subprocess.run(['tar', '-zxf', tarball, '-C', tag,
+ '--strip-components=1',
+ 'bitcoin-{tag}'.format(tag=tag[1:])]).returncode
+ if ret:
+ return ret
+
+ Path(tarball).unlink()
+ Path(sha256Sums).unlink()
+ return 0
+
+
+def build_release(tag, args) -> int:
+ githubUrl = "https://github.com/bitcoin/bitcoin"
+ if args.remove_dir:
+ if Path(tag).is_dir():
+ shutil.rmtree(tag)
+ if not Path(tag).is_dir():
+ # fetch new tags
+ subprocess.run(
+ ["git", "fetch", githubUrl, "--tags"])
+ output = subprocess.check_output(['git', 'tag', '-l', tag])
+ if not output:
+ print('Tag {} not found'.format(tag))
+ return 1
+ ret = subprocess.run([
+ 'git', 'clone', githubUrl, tag
+ ]).returncode
+ if ret:
+ return ret
+ with pushd(tag):
+ ret = subprocess.run(['git', 'checkout', tag]).returncode
+ if ret:
+ return ret
+ host = args.host
+ if args.depends:
+ with pushd('depends'):
+ ret = subprocess.run(['make', 'NO_QT=1']).returncode
+ if ret:
+ return ret
+ host = os.environ.get(
+ 'HOST', subprocess.check_output(['./config.guess']))
+ config_flags = '--prefix={pwd}/depends/{host} '.format(
+ pwd=os.getcwd(),
+ host=host) + args.config_flags
+ cmds = [
+ './autogen.sh',
+ './configure {}'.format(config_flags),
+ 'make',
+ ]
+ for cmd in cmds:
+ ret = subprocess.run(cmd.split()).returncode
+ if ret:
+ return ret
+ # Move binaries, so they're in the same place as in the
+ # release download
+ Path('bin').mkdir(exist_ok=True)
+ files = ['bitcoind', 'bitcoin-cli', 'bitcoin-tx']
+ for f in files:
+ Path('src/'+f).rename('bin/'+f)
+ return 0
+
+
+def check_host(args) -> int:
+ args.host = os.environ.get('HOST', subprocess.check_output(
+ './depends/config.guess').decode())
+ if args.download_binary:
+ platforms = {
+ 'x86_64-*-linux*': 'x86_64-linux-gnu',
+ 'x86_64-apple-darwin*': 'osx64',
+ }
+ args.platform = ''
+ for pattern, target in platforms.items():
+ if fnmatch(args.host, pattern):
+ args.platform = target
+ if not args.platform:
+ print('Not sure which binary to download for {}'.format(args.host))
+ return 1
+ return 0
+
+
+def main(args) -> int:
+ Path(args.target_dir).mkdir(exist_ok=True, parents=True)
+ print("Releases directory: {}".format(args.target_dir))
+ ret = check_host(args)
+ if ret:
+ return ret
+ if args.download_binary:
+ with pushd(args.target_dir):
+ for tag in args.tags:
+ ret = download_binary(tag, args)
+ if ret:
+ return ret
+ return 0
+ args.config_flags = os.environ.get('CONFIG_FLAGS', '')
+ args.config_flags += ' --without-gui --disable-tests --disable-bench'
+ with pushd(args.target_dir):
+ for tag in args.tags:
+ ret = build_release(tag, args)
+ if ret:
+ return ret
+ return 0
+
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser(
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter)
+ parser.add_argument('-r', '--remove-dir', action='store_true',
+ help='remove existing directory.')
+ parser.add_argument('-d', '--depends', action='store_true',
+ help='use depends.')
+ parser.add_argument('-b', '--download-binary', action='store_true',
+ help='download release binary.')
+ parser.add_argument('-t', '--target-dir', action='store',
+ help='target directory.', default='releases')
+ parser.add_argument('tags', nargs='+',
+ help="release tags. e.g.: v0.18.1 v0.20.0rc2")
+ args = parser.parse_args()
+ sys.exit(main(args))
diff --git a/contrib/devtools/previous_release.sh b/contrib/devtools/previous_release.sh
deleted file mode 100755
index d375291f47..0000000000
--- a/contrib/devtools/previous_release.sh
+++ /dev/null
@@ -1,152 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) 2018-2020 The Bitcoin Core developers
-# Distributed under the MIT software license, see the accompanying
-# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#
-# Build previous releases.
-
-export LC_ALL=C
-
-CONFIG_FLAGS=""
-FUNCTIONAL_TESTS=0
-DELETE_EXISTING=0
-USE_DEPENDS=0
-DOWNLOAD_BINARY=0
-CONFIG_FLAGS=""
-TARGET="releases"
-
-while getopts ":hfrdbt:" opt; do
- case $opt in
- h)
- echo "Usage: .previous_release.sh [options] tag1 tag2"
- echo " options:"
- echo " -h Print this message"
- echo " -f Configure for functional tests"
- echo " -r Remove existing directory"
- echo " -d Use depends"
- echo " -b Download release binary"
- echo " -t Target directory (default: releases)"
- exit 0
- ;;
- f)
- FUNCTIONAL_TESTS=1
- CONFIG_FLAGS="$CONFIG_FLAGS --without-gui --disable-tests --disable-bench"
- ;;
- r)
- DELETE_EXISTING=1
- ;;
- d)
- USE_DEPENDS=1
- ;;
- b)
- DOWNLOAD_BINARY=1
- ;;
- t)
- TARGET=$OPTARG
- ;;
- \?)
- echo "Invalid option: -$OPTARG" >&2
- exit 1
- ;;
- esac
-done
-
-shift $((OPTIND-1))
-
-if [ -z "$1" ]; then
- echo "Specify release tag(s), e.g.: .previous_release v0.15.1"
- exit 1
-fi
-
-if [ ! -d "$TARGET" ]; then
- mkdir -p $TARGET
-fi
-
-if [ "$DOWNLOAD_BINARY" -eq "1" ]; then
- HOST="${HOST:-$(./depends/config.guess)}"
- case "$HOST" in
- x86_64-*-linux*)
- PLATFORM=x86_64-linux-gnu
- ;;
- x86_64-apple-darwin*)
- PLATFORM=osx64
- ;;
- *)
- echo "Not sure which binary to download for $HOST."
- exit 1
- ;;
- esac
-fi
-
-echo "Releases directory: $TARGET"
-pushd "$TARGET" || exit 1
-{
- for tag in "$@"
- do
- if [ "$DELETE_EXISTING" -eq "1" ]; then
- if [ -d "$tag" ]; then
- rm -r "$tag"
- fi
- fi
-
- if [ "$DOWNLOAD_BINARY" -eq "0" ]; then
-
- if [ ! -d "$tag" ]; then
- if [ -z $(git tag -l "$tag") ]; then
- echo "Tag $tag not found"
- exit 1
- fi
-
- git clone https://github.com/bitcoin/bitcoin "$tag"
- pushd "$tag" || exit 1
- {
- git checkout "$tag"
- if [ "$USE_DEPENDS" -eq "1" ]; then
- pushd depends || exit 1
- {
- if [ "$FUNCTIONAL_TESTS" -eq "1" ]; then
- make NO_QT=1
- else
- make
- fi
- HOST="${HOST:-$(./config.guess)}"
- }
- popd || exit 1
- CONFIG_FLAGS="--prefix=$PWD/depends/$HOST $CONFIG_FLAGS"
- fi
- ./autogen.sh
- ./configure $CONFIG_FLAGS
- make
- # Move binaries, so they're in the same place as in the release download:
- mkdir bin
- mv src/bitcoind src/bitcoin-cli src/bitcoin-tx bin
- if [ "$FUNCTIONAL_TESTS" -eq "0" ]; then
- mv src/qt/bitcoin-qt bin
- fi
- }
- popd || exit 1
- fi
- else
- if [ -d "$tag" ]; then
- echo "Using cached $tag"
- else
- mkdir "$tag"
- if [[ "$tag" =~ v(.*)(rc[0-9]+)$ ]]; then
- BIN_PATH="bin/bitcoin-core-${BASH_REMATCH[1]}/test.${BASH_REMATCH[2]}"
- else
- BIN_PATH="bin/bitcoin-core-${tag:1}"
- fi
- URL="https://bitcoincore.org/$BIN_PATH/bitcoin-${tag:1}-$PLATFORM.tar.gz"
- echo "Fetching: $URL"
- if ! curl -O -f $URL; then
- echo "Download failed."
- exit 1
- fi
- tar -zxf "bitcoin-${tag:1}-$PLATFORM.tar.gz" -C "$tag" --strip-components=1 "bitcoin-${tag:1}"
- rm "bitcoin-${tag:1}-$PLATFORM.tar.gz"
- fi
- fi
- done
-}
-popd || exit 1
diff --git a/contrib/devtools/test_deterministic_coverage.sh b/contrib/devtools/test_deterministic_coverage.sh
index 95b1553215..8501c72f04 100755
--- a/contrib/devtools/test_deterministic_coverage.sh
+++ b/contrib/devtools/test_deterministic_coverage.sh
@@ -16,7 +16,6 @@ GCOV_EXECUTABLE="gcov"
NON_DETERMINISTIC_TESTS=(
"blockfilter_index_tests/blockfilter_index_initial_sync" # src/checkqueue.h: In CCheckQueue::Loop(): while (queue.empty()) { ... }
"coinselector_tests/knapsack_solver_test" # coinselector_tests.cpp: if (equal_sets(setCoinsRet, setCoinsRet2))
- "denialofservice_tests/DoS_mapOrphans" # denialofservice_tests.cpp: it = mapOrphanTransactions.lower_bound(InsecureRand256());
"fs_tests/fsbridge_fstream" # deterministic test failure?
"miner_tests/CreateNewBlock_validity" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10)
"scheduler_tests/manythreads" # scheduler.cpp: CScheduler::serviceQueue()
diff --git a/depends/README.md b/depends/README.md
index 01276e48ee..11733024b1 100644
--- a/depends/README.md
+++ b/depends/README.md
@@ -44,7 +44,7 @@ The paths are automatically configured and no other options are needed unless ta
#### For macOS cross compilation
- sudo apt-get install curl librsvg2-bin libtiff-tools bsdmainutils cmake imagemagick libcap-dev libz-dev libbz2-dev python3-setuptools
+ sudo apt-get install curl librsvg2-bin libtiff-tools bsdmainutils cmake imagemagick libcap-dev libz-dev libbz2-dev python3-setuptools libtinfo5
#### For Win64 cross compilation
diff --git a/depends/packages/native_cdrkit.mk b/depends/packages/native_cdrkit.mk
index 8243458ec8..14c37a0fc7 100644
--- a/depends/packages/native_cdrkit.mk
+++ b/depends/packages/native_cdrkit.mk
@@ -9,8 +9,10 @@ define $(package)_preprocess_cmds
patch -p1 < $($(package)_patch_dir)/cdrkit-deterministic.patch
endef
+# Starting with 10.1, GCC defaults to -fno-common, resulting in linking errors.
+# Pass -fcommon to retain the legacy behaviour.
define $(package)_config_cmds
- cmake -DCMAKE_INSTALL_PREFIX=$(build_prefix)
+ cmake -DCMAKE_INSTALL_PREFIX=$(build_prefix) -DCMAKE_C_FLAGS="-fcommon"
endef
define $(package)_build_cmds
diff --git a/src/consensus/validation.h b/src/consensus/validation.h
index 337ee244d3..8de7a8f2d8 100644
--- a/src/consensus/validation.h
+++ b/src/consensus/validation.h
@@ -79,37 +79,39 @@ enum class BlockValidationResult {
* by TxValidationState and BlockValidationState for validation information on transactions
* and blocks respectively. */
template <typename Result>
-class ValidationState {
+class ValidationState
+{
private:
- enum mode_state {
- MODE_VALID, //!< everything ok
- MODE_INVALID, //!< network rule violation (DoS value may be set)
- MODE_ERROR, //!< run-time error
- } m_mode{MODE_VALID};
+ enum class ModeState {
+ M_VALID, //!< everything ok
+ M_INVALID, //!< network rule violation (DoS value may be set)
+ M_ERROR, //!< run-time error
+ } m_mode{ModeState::M_VALID};
Result m_result{};
std::string m_reject_reason;
std::string m_debug_message;
+
public:
bool Invalid(Result result,
- const std::string &reject_reason="",
- const std::string &debug_message="")
+ const std::string& reject_reason = "",
+ const std::string& debug_message = "")
{
m_result = result;
m_reject_reason = reject_reason;
m_debug_message = debug_message;
- if (m_mode != MODE_ERROR) m_mode = MODE_INVALID;
+ if (m_mode != ModeState::M_ERROR) m_mode = ModeState::M_INVALID;
return false;
}
bool Error(const std::string& reject_reason)
{
- if (m_mode == MODE_VALID)
+ if (m_mode == ModeState::M_VALID)
m_reject_reason = reject_reason;
- m_mode = MODE_ERROR;
+ m_mode = ModeState::M_ERROR;
return false;
}
- bool IsValid() const { return m_mode == MODE_VALID; }
- bool IsInvalid() const { return m_mode == MODE_INVALID; }
- bool IsError() const { return m_mode == MODE_ERROR; }
+ bool IsValid() const { return m_mode == ModeState::M_VALID; }
+ bool IsInvalid() const { return m_mode == ModeState::M_INVALID; }
+ bool IsError() const { return m_mode == ModeState::M_ERROR; }
Result GetResult() const { return m_result; }
std::string GetRejectReason() const { return m_reject_reason; }
std::string GetDebugMessage() const { return m_debug_message; }
diff --git a/src/init.cpp b/src/init.cpp
index 9864bad291..2b62d5d306 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -1888,7 +1888,7 @@ bool AppInitMain(const util::Ref& context, NodeContext& node)
connOptions.nLocalServices = nLocalServices;
connOptions.nMaxConnections = nMaxConnections;
connOptions.m_max_outbound_full_relay = std::min(MAX_OUTBOUND_FULL_RELAY_CONNECTIONS, connOptions.nMaxConnections);
- connOptions.m_max_outbound_block_relay = std::min(MAX_BLOCKS_ONLY_CONNECTIONS, connOptions.nMaxConnections-connOptions.m_max_outbound_full_relay);
+ connOptions.m_max_outbound_block_relay = std::min(MAX_BLOCK_RELAY_ONLY_CONNECTIONS, connOptions.nMaxConnections-connOptions.m_max_outbound_full_relay);
connOptions.nMaxAddnode = MAX_ADDNODE_CONNECTIONS;
connOptions.nMaxFeeler = MAX_FEELER_CONNECTIONS;
connOptions.nBestHeight = chain_active_height;
diff --git a/src/net.h b/src/net.h
index 254c86ec8a..72c73dc3a1 100644
--- a/src/net.h
+++ b/src/net.h
@@ -61,7 +61,7 @@ static const int MAX_OUTBOUND_FULL_RELAY_CONNECTIONS = 8;
/** Maximum number of addnode outgoing nodes */
static const int MAX_ADDNODE_CONNECTIONS = 8;
/** Maximum number of block-relay-only outgoing connections */
-static const int MAX_BLOCKS_ONLY_CONNECTIONS = 2;
+static const int MAX_BLOCK_RELAY_ONLY_CONNECTIONS = 2;
/** Maximum number of feeler connections */
static const int MAX_FEELER_CONNECTIONS = 1;
/** -listen default */
diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp
index 0bc3e0fe9f..d5e902cadd 100644
--- a/src/rpc/rawtransaction.cpp
+++ b/src/rpc/rawtransaction.cpp
@@ -28,6 +28,7 @@
#include <script/signingprovider.h>
#include <script/standard.h>
#include <uint256.h>
+#include <util/bip32.h>
#include <util/moneystr.h>
#include <util/strencodings.h>
#include <util/string.h>
@@ -938,25 +939,6 @@ static UniValue testmempoolaccept(const JSONRPCRequest& request)
return result;
}
-static std::string WriteHDKeypath(std::vector<uint32_t>& keypath)
-{
- std::string keypath_str = "m";
- for (uint32_t num : keypath) {
- keypath_str += "/";
- bool hardened = false;
- if (num & 0x80000000) {
- hardened = true;
- num &= ~0x80000000;
- }
-
- keypath_str += ToString(num);
- if (hardened) {
- keypath_str += "'";
- }
- }
- return keypath_str;
-}
-
UniValue decodepsbt(const JSONRPCRequest& request)
{
RPCHelpMan{"decodepsbt",
diff --git a/src/test/denialofservice_tests.cpp b/src/test/denialofservice_tests.cpp
index fdc63cd70e..b1a635d9da 100644
--- a/src/test/denialofservice_tests.cpp
+++ b/src/test/denialofservice_tests.cpp
@@ -4,10 +4,12 @@
// Unit tests for denial-of-service detection/prevention code
+#include <arith_uint256.h>
#include <banman.h>
#include <chainparams.h>
#include <net.h>
#include <net_processing.h>
+#include <pubkey.h>
#include <script/sign.h>
#include <script/signingprovider.h>
#include <script/standard.h>
@@ -314,10 +316,26 @@ static CTransactionRef RandomOrphan()
return it->second.tx;
}
+static void MakeNewKeyWithFastRandomContext(CKey& key)
+{
+ std::vector<unsigned char> keydata;
+ keydata = g_insecure_rand_ctx.randbytes(32);
+ key.Set(keydata.data(), keydata.data() + keydata.size(), /*fCompressedIn*/ true);
+ assert(key.IsValid());
+}
+
BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
{
+ // This test had non-deterministic coverage due to
+ // randomly selected seeds.
+ // This seed is chosen so that all branches of the function
+ // ecdsa_signature_parse_der_lax are executed during this test.
+ // Specifically branches that run only when an ECDSA
+ // signature's R and S values have leading zeros.
+ g_insecure_rand_ctx = FastRandomContext(ArithToUint256(arith_uint256(33)));
+
CKey key;
- key.MakeNewKey(true);
+ MakeNewKeyWithFastRandomContext(key);
FillableSigningProvider keystore;
BOOST_CHECK(keystore.AddKey(key));
diff --git a/src/test/fuzz/addrdb.cpp b/src/test/fuzz/addrdb.cpp
index ad6461650f..16b1cb755a 100644
--- a/src/test/fuzz/addrdb.cpp
+++ b/src/test/fuzz/addrdb.cpp
@@ -17,6 +17,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
+ // The point of this code is to exercise all CBanEntry constructors.
const CBanEntry ban_entry = [&] {
switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 2)) {
case 0:
@@ -32,4 +33,5 @@ void test_one_input(const std::vector<uint8_t>& buffer)
}
return CBanEntry{};
}();
+ (void)ban_entry; // currently unused
}
diff --git a/src/test/fuzz/script.cpp b/src/test/fuzz/script.cpp
index cad548178d..85aac6ac7a 100644
--- a/src/test/fuzz/script.cpp
+++ b/src/test/fuzz/script.cpp
@@ -48,7 +48,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
if (CompressScript(script, compressed)) {
const unsigned int size = compressed[0];
compressed.erase(compressed.begin());
- assert(size >= 0 && size <= 5);
+ assert(size <= 5);
CScript decompressed_script;
const bool ok = DecompressScript(decompressed_script, size, compressed);
assert(ok);
diff --git a/src/test/fuzz/scriptnum_ops.cpp b/src/test/fuzz/scriptnum_ops.cpp
index f4e079fb89..68c1ae58ca 100644
--- a/src/test/fuzz/scriptnum_ops.cpp
+++ b/src/test/fuzz/scriptnum_ops.cpp
@@ -33,7 +33,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
case 0: {
const int64_t i = fuzzed_data_provider.ConsumeIntegral<int64_t>();
assert((script_num == i) != (script_num != i));
- assert((script_num <= i) != script_num > i);
+ assert((script_num <= i) != (script_num > i));
assert((script_num >= i) != (script_num < i));
// Avoid signed integer overflow:
// script/script.h:264:93: runtime error: signed integer overflow: -2261405121394637306 + -9223372036854775802 cannot be represented in type 'long'
diff --git a/src/test/fuzz/signature_checker.cpp b/src/test/fuzz/signature_checker.cpp
index 4a8c7a63af..3aaeb66649 100644
--- a/src/test/fuzz/signature_checker.cpp
+++ b/src/test/fuzz/signature_checker.cpp
@@ -28,17 +28,17 @@ public:
{
}
- virtual bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const
+ bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override
{
return m_fuzzed_data_provider.ConsumeBool();
}
- virtual bool CheckLockTime(const CScriptNum& nLockTime) const
+ bool CheckLockTime(const CScriptNum& nLockTime) const override
{
return m_fuzzed_data_provider.ConsumeBool();
}
- virtual bool CheckSequence(const CScriptNum& nSequence) const
+ bool CheckSequence(const CScriptNum& nSequence) const override
{
return m_fuzzed_data_provider.ConsumeBool();
}
diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h
index 148610c04d..9f9552edb9 100644
--- a/src/test/fuzz/util.h
+++ b/src/test/fuzz/util.h
@@ -332,7 +332,7 @@ public:
return 0;
}
std::memcpy(buf, random_bytes.data(), random_bytes.size());
- if (AdditionOverflow((uint64_t)fuzzed_file->m_offset, random_bytes.size())) {
+ if (AdditionOverflow(fuzzed_file->m_offset, (int64_t)random_bytes.size())) {
return fuzzed_file->m_fuzzed_data_provider.ConsumeBool() ? 0 : -1;
}
fuzzed_file->m_offset += random_bytes.size();
@@ -343,7 +343,7 @@ public:
{
FuzzedFileProvider* fuzzed_file = (FuzzedFileProvider*)cookie;
const ssize_t n = fuzzed_file->m_fuzzed_data_provider.ConsumeIntegralInRange<ssize_t>(0, size);
- if (AdditionOverflow(fuzzed_file->m_offset, n)) {
+ if (AdditionOverflow(fuzzed_file->m_offset, (int64_t)n)) {
return fuzzed_file->m_fuzzed_data_provider.ConsumeBool() ? 0 : -1;
}
fuzzed_file->m_offset += n;
diff --git a/src/validation.cpp b/src/validation.cpp
index ff7345b55f..5aa3d315d5 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -3641,8 +3641,10 @@ bool BlockManager::AcceptBlockHeader(const CBlockHeader& block, BlockValidationS
return true;
}
- if (!CheckBlockHeader(block, state, chainparams.GetConsensus()))
- return error("%s: Consensus::CheckBlockHeader: %s, %s", __func__, hash.ToString(), state.ToString());
+ if (!CheckBlockHeader(block, state, chainparams.GetConsensus())) {
+ LogPrint(BCLog::VALIDATION, "%s: Consensus::CheckBlockHeader: %s, %s\n", __func__, hash.ToString(), state.ToString());
+ return false;
+ }
// Get prev block index
CBlockIndex* pindexPrev = nullptr;
@@ -4708,7 +4710,6 @@ void LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, FlatFi
if (dbp)
dbp->nPos = nBlockPos;
blkdat.SetLimit(nBlockPos + nSize);
- blkdat.SetPos(nBlockPos);
std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
CBlock& block = *pblock;
blkdat >> block;
diff --git a/src/wallet/bdb.cpp b/src/wallet/bdb.cpp
index 44d1bafaf6..b8e03e3ec1 100644
--- a/src/wallet/bdb.cpp
+++ b/src/wallet/bdb.cpp
@@ -139,7 +139,7 @@ BerkeleyEnvironment::~BerkeleyEnvironment()
Close();
}
-bool BerkeleyEnvironment::Open(bool retry)
+bool BerkeleyEnvironment::Open(bilingual_str& err)
{
if (fDbEnvInit) {
return true;
@@ -149,6 +149,7 @@ bool BerkeleyEnvironment::Open(bool retry)
TryCreateDirectories(pathIn);
if (!LockDirectory(pathIn, ".walletlock")) {
LogPrintf("Cannot obtain a lock on wallet directory %s. Another instance of bitcoin may be using it.\n", strPath);
+ err = strprintf(_("Error initializing wallet database environment %s!"), Directory());
return false;
}
@@ -188,23 +189,11 @@ bool BerkeleyEnvironment::Open(bool retry)
LogPrintf("BerkeleyEnvironment::Open: Error %d closing failed database environment: %s\n", ret2, DbEnv::strerror(ret2));
}
Reset();
- if (retry) {
- // try moving the database env out of the way
- fs::path pathDatabaseBak = pathIn / strprintf("database.%d.bak", GetTime());
- try {
- fs::rename(pathLogDir, pathDatabaseBak);
- LogPrintf("Moved old %s to %s. Retrying.\n", pathLogDir.string(), pathDatabaseBak.string());
- } catch (const fs::filesystem_error&) {
- // failure is ok (well, not really, but it's not worse than what we started with)
- }
- // try opening it again one more time
- if (!Open(false /* retry */)) {
- // if it still fails, it probably means we can't even create the database env
- return false;
- }
- } else {
- return false;
+ err = strprintf(_("Error initializing wallet database environment %s!"), Directory());
+ if (ret == DB_RUNRECOVERY) {
+ err += Untranslated(" ") + _("This error could occur if this wallet was not shutdown cleanly and was last loaded using a build with a newer version of Berkeley DB. If so, please use the software that last loaded this wallet");
}
+ return false;
}
fDbEnvInit = true;
@@ -300,8 +289,7 @@ bool BerkeleyDatabase::Verify(bilingual_str& errorStr)
LogPrintf("Using BerkeleyDB version %s\n", BerkeleyDatabaseVersion());
LogPrintf("Using wallet %s\n", file_path.string());
- if (!env->Open(true /* retry */)) {
- errorStr = strprintf(_("Error initializing wallet database environment %s!"), walletDir);
+ if (!env->Open(errorStr)) {
return false;
}
@@ -342,7 +330,8 @@ BerkeleyBatch::BerkeleyBatch(BerkeleyDatabase& database, const char* pszMode, bo
{
LOCK(cs_db);
- if (!env->Open(false /* retry */))
+ bilingual_str open_err;
+ if (!env->Open(open_err))
throw std::runtime_error("BerkeleyBatch: Failed to open database environment.");
pdb = database.m_db.get();
@@ -482,7 +471,8 @@ void BerkeleyEnvironment::ReloadDbEnv()
// Reset the environment
Flush(true); // This will flush and close the environment
Reset();
- Open(true);
+ bilingual_str open_err;
+ Open(open_err);
}
bool BerkeleyDatabase::Rewrite(const char* pszSkip)
diff --git a/src/wallet/bdb.h b/src/wallet/bdb.h
index e54776fc0d..1b9b5de9f9 100644
--- a/src/wallet/bdb.h
+++ b/src/wallet/bdb.h
@@ -69,7 +69,7 @@ public:
bool Verify(const std::string& strFile);
- bool Open(bool retry);
+ bool Open(bilingual_str& error);
void Close();
void Flush(bool fShutdown);
void CheckpointLSN(const std::string& strFile);
diff --git a/src/wallet/salvage.cpp b/src/wallet/salvage.cpp
index e6e62332c0..af57210f01 100644
--- a/src/wallet/salvage.cpp
+++ b/src/wallet/salvage.cpp
@@ -5,6 +5,7 @@
#include <fs.h>
#include <streams.h>
+#include <util/translation.h>
#include <wallet/salvage.h>
#include <wallet/wallet.h>
#include <wallet/walletdb.h>
@@ -20,8 +21,9 @@ bool RecoverDatabaseFile(const fs::path& file_path)
std::string filename;
std::shared_ptr<BerkeleyEnvironment> env = GetWalletEnv(file_path, filename);
- if (!env->Open(true /* retry */)) {
- tfm::format(std::cerr, "Error initializing wallet database environment %s!", env->Directory());
+ bilingual_str open_err;
+ if (!env->Open(open_err)) {
+ tfm::format(std::cerr, "%s\n", open_err.original);
return false;
}
diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp
index 9cc847b2d0..d2770a46f7 100644
--- a/src/wallet/test/wallet_tests.cpp
+++ b/src/wallet/test/wallet_tests.cpp
@@ -28,6 +28,11 @@ extern UniValue importmulti(const JSONRPCRequest& request);
extern UniValue dumpwallet(const JSONRPCRequest& request);
extern UniValue importwallet(const JSONRPCRequest& request);
+// Ensure that fee levels defined in the wallet are at least as high
+// as the default levels for node policy.
+static_assert(DEFAULT_TRANSACTION_MINFEE >= DEFAULT_MIN_RELAY_TX_FEE, "wallet minimum fee is smaller than default relay fee");
+static_assert(WALLET_INCREMENTAL_RELAY_FEE >= DEFAULT_INCREMENTAL_RELAY_FEE, "wallet incremental fee is smaller than default incremental relay fee");
+
BOOST_FIXTURE_TEST_SUITE(wallet_tests, WalletTestingSetup)
static std::shared_ptr<CWallet> TestLoadWallet(interfaces::Chain& chain)
diff --git a/test/functional/feature_backwards_compatibility.py b/test/functional/feature_backwards_compatibility.py
index 5cddd6527e..07dd0f8f82 100755
--- a/test/functional/feature_backwards_compatibility.py
+++ b/test/functional/feature_backwards_compatibility.py
@@ -6,7 +6,7 @@
Test various backwards compatibility scenarios. Download the previous node binaries:
-contrib/devtools/previous_release.sh -b v0.19.1 v0.18.1 v0.17.1 v0.16.3 v0.15.2
+contrib/devtools/previous_release.py -b v0.19.1 v0.18.1 v0.17.1 v0.16.3 v0.15.2
v0.15.2 is not required by this test, but it is used in wallet_upgradewallet.py.
Due to a hardfork in regtest, it can't be used to sync nodes.
diff --git a/test/functional/mempool_compatibility.py b/test/functional/mempool_compatibility.py
index 999399dec0..31fb751904 100755
--- a/test/functional/mempool_compatibility.py
+++ b/test/functional/mempool_compatibility.py
@@ -8,7 +8,7 @@ NOTE: The test is designed to prevent cases when compatibility is broken acciden
In case we need to break mempool compatibility we can continue to use the test by just bumping the version number.
Download node binaries:
-contrib/devtools/previous_release.sh -b v0.19.1 v0.18.1 v0.17.1 v0.16.3 v0.15.2
+contrib/devtools/previous_release.py -b v0.19.1 v0.18.1 v0.17.1 v0.16.3 v0.15.2
Only v0.15.2 is required by this test. The rest is used in other backwards compatibility tests.
"""
diff --git a/test/functional/p2p_ibd_txrelay.py b/test/functional/p2p_ibd_txrelay.py
index be201e6bc3..c3e758b021 100755
--- a/test/functional/p2p_ibd_txrelay.py
+++ b/test/functional/p2p_ibd_txrelay.py
@@ -8,7 +8,6 @@ from decimal import Decimal
from test_framework.messages import COIN
from test_framework.test_framework import BitcoinTestFramework
-from test_framework.util import assert_equal
MAX_FEE_FILTER = Decimal(9170997) / COIN
NORMAL_FEE_FILTER = Decimal(100) / COIN
@@ -22,12 +21,12 @@ class P2PIBDTxRelayTest(BitcoinTestFramework):
["-minrelaytxfee={}".format(NORMAL_FEE_FILTER)],
["-minrelaytxfee={}".format(NORMAL_FEE_FILTER)],
]
+
def run_test(self):
self.log.info("Check that nodes set minfilter to MAX_MONEY while still in IBD")
for node in self.nodes:
assert node.getblockchaininfo()['initialblockdownload']
- for conn_info in node.getpeerinfo():
- assert_equal(conn_info['minfeefilter'], MAX_FEE_FILTER)
+ self.wait_until(lambda: all(peer['minfeefilter'] == MAX_FEE_FILTER for peer in node.getpeerinfo()))
# Come out of IBD by generating a block
self.nodes[0].generate(1)
@@ -36,8 +35,7 @@ class P2PIBDTxRelayTest(BitcoinTestFramework):
self.log.info("Check that nodes reset minfilter after coming out of IBD")
for node in self.nodes:
assert not node.getblockchaininfo()['initialblockdownload']
- for conn_info in node.getpeerinfo():
- assert_equal(conn_info['minfeefilter'], NORMAL_FEE_FILTER)
+ self.wait_until(lambda: all(peer['minfeefilter'] == NORMAL_FEE_FILTER for peer in node.getpeerinfo()))
if __name__ == '__main__':
diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py
index 9d9e065158..8d402d4888 100755
--- a/test/functional/test_framework/test_framework.py
+++ b/test/functional/test_framework/test_framework.py
@@ -31,6 +31,7 @@ from .util import (
disconnect_nodes,
get_datadir_path,
initialize_datadir,
+ wait_until,
)
@@ -602,6 +603,9 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
self.sync_blocks(nodes)
self.sync_mempools(nodes)
+ def wait_until(self, test_function, timeout=60, lock=None):
+ return wait_until(test_function, timeout=timeout, lock=lock, timeout_factor=self.options.timeout_factor)
+
# Private helper methods. These should not be accessed by the subclass test scripts.
def _start_logging(self):
diff --git a/test/functional/wallet_upgradewallet.py b/test/functional/wallet_upgradewallet.py
index cc2139a027..1a76f65215 100755
--- a/test/functional/wallet_upgradewallet.py
+++ b/test/functional/wallet_upgradewallet.py
@@ -6,7 +6,7 @@
Test upgradewallet RPC. Download node binaries:
-contrib/devtools/previous_release.sh -b v0.19.1 v0.18.1 v0.17.1 v0.16.3 v0.15.2
+contrib/devtools/previous_release.py -b v0.19.1 v0.18.1 v0.17.1 v0.16.3 v0.15.2
Only v0.15.2 and v0.16.3 are required by this test. The others are used in feature_backwards_compatibility.py
"""