diff --git a/depend/bitcoin/.github/workflows/ci.yml b/depend/bitcoin/.github/workflows/ci.yml index 5e5b0c48..f54e0661 100644 --- a/depend/bitcoin/.github/workflows/ci.yml +++ b/depend/bitcoin/.github/workflows/ci.yml @@ -258,7 +258,7 @@ jobs: sed -i '1s/^/set(ENV{CMAKE_POLICY_VERSION_MINIMUM} 3.5)\n/' "${VCPKG_INSTALLATION_ROOT}/scripts/ports.cmake" - name: vcpkg tools cache - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: C:/vcpkg/downloads/tools key: ${{ github.job }}-vcpkg-tools @@ -320,12 +320,15 @@ jobs: BITCOIN_BIN: '${{ github.workspace }}\build\bin\Release\bitcoin.exe' BITCOIND: '${{ github.workspace }}\build\bin\Release\bitcoind.exe' BITCOINCLI: '${{ github.workspace }}\build\bin\Release\bitcoin-cli.exe' + BITCOIN_BENCH: '${{ github.workspace }}\build\bin\Release\bench_bitcoin.exe' BITCOINTX: '${{ github.workspace }}\build\bin\Release\bitcoin-tx.exe' BITCOINUTIL: '${{ github.workspace }}\build\bin\Release\bitcoin-util.exe' BITCOINWALLET: '${{ github.workspace }}\build\bin\Release\bitcoin-wallet.exe' BITCOINCHAINSTATE: '${{ github.workspace }}\build\bin\Release\bitcoin-chainstate.exe' TEST_RUNNER_EXTRA: ${{ github.event_name != 'pull_request' && '--extended' || '' }} - run: py -3 test/functional/test_runner.py --jobs $NUMBER_OF_PROCESSORS --ci --quiet --tmpdirprefix="${RUNNER_TEMP}" --combinedlogslen=99999999 --timeout-factor=${TEST_RUNNER_TIMEOUT_FACTOR} ${TEST_RUNNER_EXTRA} + run: | + py -3 -m pip install pyzmq + py -3 test/functional/test_runner.py --jobs $NUMBER_OF_PROCESSORS --quiet --tmpdirprefix="${RUNNER_TEMP}" --combinedlogslen=99999999 --timeout-factor=${TEST_RUNNER_TIMEOUT_FACTOR} ${TEST_RUNNER_EXTRA} - name: Clone corpora if: matrix.job-type == 'fuzz' @@ -406,7 +409,7 @@ jobs: uses: ./.github/actions/save-caches - name: Upload built executables - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: ${{ matrix.artifact-name }}-${{ github.run_id }} path: | @@ -444,7 +447,7 @@ jobs: ref: ${{ needs.record-frozen-commit.outputs.commit }} - name: Download built executables - uses: actions/download-artifact@v5 + uses: actions/download-artifact@v7 with: name: ${{ matrix.artifact-name }}-${{ github.run_id }} @@ -483,9 +486,6 @@ jobs: ./src/univalue/object.exe ./src/univalue/unitester.exe - - name: Run benchmarks - run: ./bin/bench_bitcoin.exe -sanity-check - - name: Adjust paths in test/config.ini shell: pwsh run: | @@ -501,11 +501,18 @@ jobs: - name: Run functional tests env: - # TODO: Fix the excluded test and re-enable it. - # feature_unsupported_utxo_db.py fails on windows because of emojis in the test data directory - EXCLUDE: '--exclude wallet_multiwallet.py,feature_unsupported_utxo_db.py' TEST_RUNNER_EXTRA: ${{ github.event_name != 'pull_request' && '--extended' || '' }} - run: py -3 test/functional/test_runner.py --jobs $NUMBER_OF_PROCESSORS --ci --quiet --tmpdirprefix="$RUNNER_TEMP" --combinedlogslen=99999999 --timeout-factor=$TEST_RUNNER_TIMEOUT_FACTOR $EXCLUDE $TEST_RUNNER_EXTRA + run: | + py -3 -m pip install pyzmq + py -3 test/functional/test_runner.py --jobs $NUMBER_OF_PROCESSORS --quiet --tmpdirprefix="$RUNNER_TEMP" --combinedlogslen=99999999 --timeout-factor=$TEST_RUNNER_TIMEOUT_FACTOR $TEST_RUNNER_EXTRA \ + `# feature_unsupported_utxo_db.py fails on Windows because of emojis in the test data directory.` \ + --exclude feature_unsupported_utxo_db.py \ + `# See https://github.com/bitcoin/bitcoin/issues/31409.` \ + --exclude wallet_multiwallet.py + # Run feature_unsupported_utxo_db sequentially in ASCII-only tmp dir, + # because it is excluded above due to lack of UTF-8 support in the + # ancient release. + py -3 test/functional/feature_unsupported_utxo_db.py --previous-releases --tmpdir="${RUNNER_TEMP}/test_feature_unsupported_utxo_db" ci-matrix: name: ${{ matrix.name }} diff --git a/depend/bitcoin/CMakeLists.txt b/depend/bitcoin/CMakeLists.txt index 9e6c255d..1b1df77b 100644 --- a/depend/bitcoin/CMakeLists.txt +++ b/depend/bitcoin/CMakeLists.txt @@ -32,7 +32,7 @@ set(CLIENT_VERSION_MINOR 99) set(CLIENT_VERSION_BUILD 0) set(CLIENT_VERSION_RC 0) set(CLIENT_VERSION_IS_RELEASE "false") -set(COPYRIGHT_YEAR "2025") +set(COPYRIGHT_YEAR "2026") # During the enabling of the CXX and CXXOBJ languages, we modify # CMake's compiler/linker invocation strings by appending the content diff --git a/depend/bitcoin/COPYING b/depend/bitcoin/COPYING index 23dc5e90..89960cbf 100644 --- a/depend/bitcoin/COPYING +++ b/depend/bitcoin/COPYING @@ -1,7 +1,7 @@ The MIT License (MIT) -Copyright (c) 2009-2025 The Bitcoin Core developers -Copyright (c) 2009-2025 Bitcoin Developers +Copyright (c) 2009-2026 The Bitcoin Core developers +Copyright (c) 2009-2026 Bitcoin Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/depend/bitcoin/ci/test/00_setup_env_arm.sh b/depend/bitcoin/ci/test/00_setup_env_arm.sh index c410a80d..f4ad97d2 100755 --- a/depend/bitcoin/ci/test/00_setup_env_arm.sh +++ b/depend/bitcoin/ci/test/00_setup_env_arm.sh @@ -10,10 +10,8 @@ export HOST=arm-linux-gnueabihf export DPKG_ADD_ARCH="armhf" export PACKAGES="python3-zmq g++-arm-linux-gnueabihf libc6:armhf libstdc++6:armhf libfontconfig1:armhf libxcb1:armhf" export CONTAINER_NAME=ci_arm_linux -export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:24.04" # Check that https://packages.ubuntu.com/noble/g++-arm-linux-gnueabihf (version 13.x, similar to guix) can cross-compile +export CI_IMAGE_NAME_TAG="mirror.gcr.io/debian:trixie" # Check that https://packages.debian.org/trixie/g++-arm-linux-gnueabihf (version 14.x, similar to guix) can cross-compile export CI_IMAGE_PLATFORM="linux/arm64" -export RUN_UNIT_TESTS=true -export RUN_FUNCTIONAL_TESTS=false export GOAL="install" export CI_LIMIT_STACK_SIZE=1 # -Wno-psabi is to disable ABI warnings: "note: parameter passing for argument of type ... changed in GCC 7.1" diff --git a/depend/bitcoin/ci/test/00_setup_env_i686_no_ipc.sh b/depend/bitcoin/ci/test/00_setup_env_i686_no_ipc.sh index c32e68cb..dca0486f 100755 --- a/depend/bitcoin/ci/test/00_setup_env_i686_no_ipc.sh +++ b/depend/bitcoin/ci/test/00_setup_env_i686_no_ipc.sh @@ -8,7 +8,7 @@ export LC_ALL=C.UTF-8 export HOST=i686-pc-linux-gnu export CONTAINER_NAME=ci_i686_no_multiprocess -export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:24.04" +export CI_IMAGE_NAME_TAG="mirror.gcr.io/debian:trixie" export CI_IMAGE_PLATFORM="linux/amd64" export PACKAGES="llvm clang g++-multilib" export DEP_OPTS="DEBUG=1 NO_IPC=1" diff --git a/depend/bitcoin/ci/test/00_setup_env_native_fuzz_with_valgrind.sh b/depend/bitcoin/ci/test/00_setup_env_native_fuzz_with_valgrind.sh index f1d99f81..d8b0f5f1 100755 --- a/depend/bitcoin/ci/test/00_setup_env_native_fuzz_with_valgrind.sh +++ b/depend/bitcoin/ci/test/00_setup_env_native_fuzz_with_valgrind.sh @@ -6,7 +6,7 @@ export LC_ALL=C.UTF-8 -export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:24.04" +export CI_IMAGE_NAME_TAG="mirror.gcr.io/debian:trixie" export CONTAINER_NAME=ci_native_fuzz_valgrind export PACKAGES="libevent-dev libboost-dev libsqlite3-dev valgrind libcapnp-dev capnproto" export NO_DEPENDS=1 diff --git a/depend/bitcoin/ci/test/00_setup_env_native_valgrind.sh b/depend/bitcoin/ci/test/00_setup_env_native_valgrind.sh index 884bc395..30c84bf4 100755 --- a/depend/bitcoin/ci/test/00_setup_env_native_valgrind.sh +++ b/depend/bitcoin/ci/test/00_setup_env_native_valgrind.sh @@ -6,14 +6,14 @@ export LC_ALL=C.UTF-8 -export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:24.04" +export CI_IMAGE_NAME_TAG="mirror.gcr.io/debian:trixie" export CONTAINER_NAME=ci_native_valgrind export PACKAGES="valgrind python3-zmq libevent-dev libboost-dev libzmq3-dev libsqlite3-dev libcapnp-dev capnproto python3-pip" export PIP_PACKAGES="--break-system-packages pycapnp" export USE_VALGRIND=1 export NO_DEPENDS=1 # bind tests excluded for now, see https://github.com/bitcoin/bitcoin/issues/17765#issuecomment-602068547 -export TEST_RUNNER_EXTRA="--exclude rpc_bind,feature_bind_extra" +export TEST_RUNNER_EXTRA="--exclude rpc_bind --exclude feature_bind_extra" export GOAL="install" # TODO enable GUI export BITCOIN_CONFIG="\ diff --git a/depend/bitcoin/ci/test/00_setup_env_s390x.sh b/depend/bitcoin/ci/test/00_setup_env_s390x.sh index b7d23fbf..d1e34070 100755 --- a/depend/bitcoin/ci/test/00_setup_env_s390x.sh +++ b/depend/bitcoin/ci/test/00_setup_env_s390x.sh @@ -9,9 +9,10 @@ export LC_ALL=C.UTF-8 export HOST=s390x-linux-gnu export PACKAGES="python3-zmq" export CONTAINER_NAME=ci_s390x -export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:24.04" +export CI_IMAGE_NAME_TAG="mirror.gcr.io/debian:trixie" export CI_IMAGE_PLATFORM="linux/s390x" -export TEST_RUNNER_EXTRA="--exclude rpc_bind,feature_bind_extra" # Excluded for now, see https://github.com/bitcoin/bitcoin/issues/17765#issuecomment-602068547 +# bind tests excluded for now, see https://github.com/bitcoin/bitcoin/issues/17765#issuecomment-602068547 +export TEST_RUNNER_EXTRA="--exclude rpc_bind --exclude feature_bind_extra" export RUN_FUNCTIONAL_TESTS=true export GOAL="install" export BITCOIN_CONFIG="\ diff --git a/depend/bitcoin/ci/test/00_setup_env_win64_msvcrt.sh b/depend/bitcoin/ci/test/00_setup_env_win64_msvcrt.sh index 86e0ea9c..6c948aeb 100755 --- a/depend/bitcoin/ci/test/00_setup_env_win64_msvcrt.sh +++ b/depend/bitcoin/ci/test/00_setup_env_win64_msvcrt.sh @@ -7,7 +7,7 @@ export LC_ALL=C.UTF-8 export CONTAINER_NAME=ci_win64_msvcrt -export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:24.04" # Check that https://packages.ubuntu.com/noble/g++-mingw-w64-x86-64-posix (version 13.x, similar to guix) can cross-compile +export CI_IMAGE_NAME_TAG="mirror.gcr.io/debian:trixie" # Check that https://packages.debian.org/trixie/g++-mingw-w64-x86-64-posix (version 14.x, similar to guix) can cross-compile export HOST=x86_64-w64-mingw32 export PACKAGES="g++-mingw-w64-x86-64-posix nsis" export RUN_UNIT_TESTS=false diff --git a/depend/bitcoin/ci/test/01_iwyu.patch b/depend/bitcoin/ci/test/01_iwyu.patch index e14316bf..e7d75f4e 100644 --- a/depend/bitcoin/ci/test/01_iwyu.patch +++ b/depend/bitcoin/ci/test/01_iwyu.patch @@ -539,10 +539,11 @@ See: https://github.com/include-what-you-use/include-what-you-use/blob/clang_21/ }; const IncludeMapEntry stdlib_c_include_map[] = { -@@ -601,31 +601,31 @@ const IncludeMapEntry stdlib_c_include_map[] = { +@@ -600,32 +600,32 @@ const IncludeMapEntry stdlib_c_include_map[] = { + // https://github.com/cplusplus/draft/blob/c+%2B20/source/lib-intro.tex // // $ curl -s -N https://raw.githubusercontent.com/cplusplus/draft/c%2B%2B20/source/lib-intro.tex | sed -n '/begin{multicolfloattable}.*{headers.cpp.c}/,/end{multicolfloattable}/p' | grep tcode | perl -nle 'm/tcode{}/ && print qq@ { "<$1.h>", kPublic, "", kPublic },@' | sort - { "", kPublic, "", kPublic }, +- { "", kPublic, "", kPublic }, - { "", kPublic, "", kPublic }, - { "", kPublic, "", kPublic }, - { "", kPublic, "", kPublic }, @@ -568,6 +569,7 @@ See: https://github.com/include-what-you-use/include-what-you-use/blob/clang_21/ - { "", kPublic, "", kPublic }, - { "", kPublic, "", kPublic }, - { "", kPublic, "", kPublic }, ++ { "", kPrivate, "", kPublic }, + { "", kPrivate, "", kPublic }, + { "", kPrivate, "", kPublic }, + { "", kPrivate, "", kPublic }, diff --git a/depend/bitcoin/ci/test/03_test_script.sh b/depend/bitcoin/ci/test/03_test_script.sh index 1cf9eb23..050d9e6a 100755 --- a/depend/bitcoin/ci/test/03_test_script.sh +++ b/depend/bitcoin/ci/test/03_test_script.sh @@ -184,7 +184,7 @@ if [ "$RUN_FUNCTIONAL_TESTS" = "true" ]; then eval "TEST_RUNNER_EXTRA=($TEST_RUNNER_EXTRA)" LD_LIBRARY_PATH="${DEPENDS_DIR}/${HOST}/lib" \ "${BASE_BUILD_DIR}/test/functional/test_runner.py" \ - --ci "${MAKEJOBS}" \ + "${MAKEJOBS}" \ --tmpdirprefix "${BASE_SCRATCH_DIR}/test_runner/" \ --ansi \ --combinedlogslen=99999999 \ @@ -215,7 +215,7 @@ fi if [[ "${RUN_IWYU}" == true ]]; then # TODO: Consider enforcing IWYU across the entire codebase. - FILES_WITH_ENFORCED_IWYU="/src/((crypto|index)/.*\\.cpp|node/blockstorage.cpp|node/utxo_snapshot.cpp|core_read.cpp|signet.cpp|kernel/chain.cpp)" + FILES_WITH_ENFORCED_IWYU="/src/((crypto|index|kernel)/.*\\.cpp|node/blockstorage.cpp|node/utxo_snapshot.cpp|core_io.cpp|signet.cpp)" jq --arg patterns "$FILES_WITH_ENFORCED_IWYU" 'map(select(.file | test($patterns)))' "${BASE_BUILD_DIR}/compile_commands.json" > "${BASE_BUILD_DIR}/compile_commands_iwyu_errors.json" jq --arg patterns "$FILES_WITH_ENFORCED_IWYU" 'map(select(.file | test($patterns) | not))' "${BASE_BUILD_DIR}/compile_commands.json" > "${BASE_BUILD_DIR}/compile_commands_iwyu_warnings.json" diff --git a/depend/bitcoin/contrib/debian/copyright b/depend/bitcoin/contrib/debian/copyright index 4e4deef9..4f703770 100644 --- a/depend/bitcoin/contrib/debian/copyright +++ b/depend/bitcoin/contrib/debian/copyright @@ -5,7 +5,7 @@ Upstream-Contact: Satoshi Nakamoto Source: https://github.com/bitcoin/bitcoin Files: * -Copyright: 2009-2025, Bitcoin Core Developers +Copyright: 2009-2026, Bitcoin Core Developers License: Expat Comment: The Bitcoin Core Developers encompasses all contributors to the project, listed in the release notes or the git log. diff --git a/depend/bitcoin/contrib/devtools/README.md b/depend/bitcoin/contrib/devtools/README.md index 3309057b..50e80781 100644 --- a/depend/bitcoin/contrib/devtools/README.md +++ b/depend/bitcoin/contrib/devtools/README.md @@ -61,65 +61,6 @@ the script should be called from the git root folder as follows. git diff -U0 HEAD~1.. | ./contrib/devtools/clang-format-diff.py -p1 -i -v ``` -copyright\_header.py -==================== - -Provides utilities for managing copyright headers of `The Bitcoin Core -developers` in repository source files. It has three subcommands: - -``` -$ ./copyright_header.py report [verbose] -$ ./copyright_header.py update -$ ./copyright_header.py insert -``` -Running these subcommands without arguments displays a usage string. - -copyright\_header.py report \ [verbose] ---------------------------------------------------------- - -Produces a report of all copyright header notices found inside the source files -of a repository. Useful to quickly visualize the state of the headers. -Specifying `verbose` will list the full filenames of files of each category. - -copyright\_header.py update \ [verbose] ---------------------------------------------------------- -Updates all the copyright headers of `The Bitcoin Core developers` which were -changed in a year more recent than is listed. For example: -``` -// Copyright (c) - The Bitcoin Core developers -``` -will be updated to: -``` -// Copyright (c) - The Bitcoin Core developers -``` -where `` is obtained from the `git log` history. - -This subcommand also handles copyright headers that have only a single year. In -those cases: -``` -// Copyright (c) The Bitcoin Core developers -``` -will be updated to: -``` -// Copyright (c) - The Bitcoin Core developers -``` -where the update is appropriate. - -copyright\_header.py insert \ ------------------------------------- -Inserts a copyright header for `The Bitcoin Core developers` at the top of the -file in either Python or C++ style as determined by the file extension. If the -file is a Python file and it has `#!` starting the first line, the header is -inserted in the line below it. - -The copyright dates will be set to be `-` where -`` is according to the `git log` history. If -`` is equal to ``, it will be set as a single -year rather than two hyphenated years. - -If the file already has a copyright for `The Bitcoin Core developers`, the -script will exit. - gen-manpages.py =============== diff --git a/depend/bitcoin/contrib/devtools/circular-dependencies.py b/depend/bitcoin/contrib/devtools/circular-dependencies.py index af19b3a0..7c058171 100755 --- a/depend/bitcoin/contrib/devtools/circular-dependencies.py +++ b/depend/bitcoin/contrib/devtools/circular-dependencies.py @@ -6,11 +6,6 @@ import sys import re -MAPPING = { - 'core_read.cpp': 'core_io.cpp', - 'core_write.cpp': 'core_io.cpp', -} - # Directories with header-based modules, where the assumption that .cpp files # define functions and variables declared in corresponding .h files is # incorrect. @@ -19,8 +14,6 @@ ] def module_name(path): - if path in MAPPING: - path = MAPPING[path] if any(path.startswith(dirpath) for dirpath in HEADER_MODULE_PATHS): return path if path.endswith(".h"): diff --git a/depend/bitcoin/contrib/devtools/copyright_header.py b/depend/bitcoin/contrib/devtools/copyright_header.py deleted file mode 100755 index aa77de8a..00000000 --- a/depend/bitcoin/contrib/devtools/copyright_header.py +++ /dev/null @@ -1,601 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2016-present The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -import re -import fnmatch -import sys -import subprocess -import datetime -import os - -################################################################################ -# file filtering -################################################################################ - -EXCLUDE = [ - # auto generated: - 'src/qt/bitcoinstrings.cpp', - 'src/chainparamsseeds.h', - # other external copyrights: - 'src/test/fuzz/FuzzedDataProvider.h', - 'src/tinyformat.h', - 'src/bench/nanobench.h', - # python init: - '*__init__.py', -] -EXCLUDE_COMPILED = re.compile('|'.join([fnmatch.translate(m) for m in EXCLUDE])) - -EXCLUDE_DIRS = [ - # git subtrees - "src/crypto/ctaes/", - "src/leveldb/", - "src/minisketch", - "src/secp256k1/", - "src/crc32c/", -] - -INCLUDE = ['*.h', '*.cpp', '*.cc', '*.c', '*.mm', '*.py', '*.sh', '*.bash-completion'] -INCLUDE_COMPILED = re.compile('|'.join([fnmatch.translate(m) for m in INCLUDE])) - -def applies_to_file(filename): - for excluded_dir in EXCLUDE_DIRS: - if filename.startswith(excluded_dir): - return False - return ((EXCLUDE_COMPILED.match(filename) is None) and - (INCLUDE_COMPILED.match(filename) is not None)) - -################################################################################ -# obtain list of files in repo according to INCLUDE and EXCLUDE -################################################################################ - -GIT_LS_CMD = 'git ls-files --full-name'.split(' ') -GIT_TOPLEVEL_CMD = 'git rev-parse --show-toplevel'.split(' ') - -def call_git_ls(base_directory): - out = subprocess.check_output([*GIT_LS_CMD, base_directory], text=True) - return [f for f in out.split('\n') if f != ''] - -def call_git_toplevel(): - "Returns the absolute path to the project root" - return subprocess.check_output(GIT_TOPLEVEL_CMD, text=True).strip() - -def get_filenames_to_examine(base_directory): - "Returns an array of absolute paths to any project files in the base_directory that pass the include/exclude filters" - root = call_git_toplevel() - filenames = call_git_ls(base_directory) - return sorted([os.path.join(root, filename) for filename in filenames if - applies_to_file(filename)]) - -################################################################################ -# define and compile regexes for the patterns we are looking for -################################################################################ - - -COPYRIGHT_WITH_C = r'Copyright \(c\)' -COPYRIGHT_WITHOUT_C = 'Copyright' -ANY_COPYRIGHT_STYLE = '(%s|%s)' % (COPYRIGHT_WITH_C, COPYRIGHT_WITHOUT_C) - -YEAR = "20[0-9][0-9]" -YEAR_RANGE = '(%s)(-%s)?' % (YEAR, YEAR) -YEAR_LIST = '(%s)(, %s)+' % (YEAR, YEAR) -ANY_YEAR_STYLE = '(%s|%s)' % (YEAR_RANGE, YEAR_LIST) -ANY_COPYRIGHT_STYLE_OR_YEAR_STYLE = ("%s %s" % (ANY_COPYRIGHT_STYLE, - ANY_YEAR_STYLE)) - -ANY_COPYRIGHT_COMPILED = re.compile(ANY_COPYRIGHT_STYLE_OR_YEAR_STYLE) - -def compile_copyright_regex(copyright_style, year_style, name): - return re.compile(r'%s %s,? %s( +\*)?\n' % (copyright_style, year_style, name)) - -EXPECTED_HOLDER_NAMES = [ - r"Satoshi Nakamoto", - r"The Bitcoin Core developers", - r"BitPay Inc\.", - r"Pieter Wuille", - r"Wladimir J\. van der Laan", - r"Jeff Garzik", - r"Jan-Klaas Kollhof", - r"ArtForz -- public domain half-a-node", - r"Intel Corporation ?", - r"The Zcash developers", - r"Jeremy Rubin", -] - -DOMINANT_STYLE_COMPILED = {} -YEAR_LIST_STYLE_COMPILED = {} -WITHOUT_C_STYLE_COMPILED = {} - -for holder_name in EXPECTED_HOLDER_NAMES: - DOMINANT_STYLE_COMPILED[holder_name] = ( - compile_copyright_regex(COPYRIGHT_WITH_C, YEAR_RANGE, holder_name)) - YEAR_LIST_STYLE_COMPILED[holder_name] = ( - compile_copyright_regex(COPYRIGHT_WITH_C, YEAR_LIST, holder_name)) - WITHOUT_C_STYLE_COMPILED[holder_name] = ( - compile_copyright_regex(COPYRIGHT_WITHOUT_C, ANY_YEAR_STYLE, - holder_name)) - -################################################################################ -# search file contents for copyright message of particular category -################################################################################ - -def get_count_of_copyrights_of_any_style_any_holder(contents): - return len(ANY_COPYRIGHT_COMPILED.findall(contents)) - -def file_has_dominant_style_copyright_for_holder(contents, holder_name): - match = DOMINANT_STYLE_COMPILED[holder_name].search(contents) - return match is not None - -def file_has_year_list_style_copyright_for_holder(contents, holder_name): - match = YEAR_LIST_STYLE_COMPILED[holder_name].search(contents) - return match is not None - -def file_has_without_c_style_copyright_for_holder(contents, holder_name): - match = WITHOUT_C_STYLE_COMPILED[holder_name].search(contents) - return match is not None - -################################################################################ -# get file info -################################################################################ - -def read_file(filename): - return open(filename, 'r').read() - -def gather_file_info(filename): - info = {} - info['filename'] = filename - c = read_file(filename) - info['contents'] = c - - info['all_copyrights'] = get_count_of_copyrights_of_any_style_any_holder(c) - - info['classified_copyrights'] = 0 - info['dominant_style'] = {} - info['year_list_style'] = {} - info['without_c_style'] = {} - for holder_name in EXPECTED_HOLDER_NAMES: - has_dominant_style = ( - file_has_dominant_style_copyright_for_holder(c, holder_name)) - has_year_list_style = ( - file_has_year_list_style_copyright_for_holder(c, holder_name)) - has_without_c_style = ( - file_has_without_c_style_copyright_for_holder(c, holder_name)) - info['dominant_style'][holder_name] = has_dominant_style - info['year_list_style'][holder_name] = has_year_list_style - info['without_c_style'][holder_name] = has_without_c_style - if has_dominant_style or has_year_list_style or has_without_c_style: - info['classified_copyrights'] = info['classified_copyrights'] + 1 - return info - -################################################################################ -# report execution -################################################################################ - -SEPARATOR = '-'.join(['' for _ in range(80)]) - -def print_filenames(filenames, verbose): - if not verbose: - return - for filename in filenames: - print("\t%s" % filename) - -def print_report(file_infos, verbose): - print(SEPARATOR) - examined = [i['filename'] for i in file_infos] - print("%d files examined according to INCLUDE and EXCLUDE fnmatch rules" % - len(examined)) - print_filenames(examined, verbose) - - print(SEPARATOR) - print('') - zero_copyrights = [i['filename'] for i in file_infos if - i['all_copyrights'] == 0] - print("%4d with zero copyrights" % len(zero_copyrights)) - print_filenames(zero_copyrights, verbose) - one_copyright = [i['filename'] for i in file_infos if - i['all_copyrights'] == 1] - print("%4d with one copyright" % len(one_copyright)) - print_filenames(one_copyright, verbose) - two_copyrights = [i['filename'] for i in file_infos if - i['all_copyrights'] == 2] - print("%4d with two copyrights" % len(two_copyrights)) - print_filenames(two_copyrights, verbose) - three_copyrights = [i['filename'] for i in file_infos if - i['all_copyrights'] == 3] - print("%4d with three copyrights" % len(three_copyrights)) - print_filenames(three_copyrights, verbose) - four_or_more_copyrights = [i['filename'] for i in file_infos if - i['all_copyrights'] >= 4] - print("%4d with four or more copyrights" % len(four_or_more_copyrights)) - print_filenames(four_or_more_copyrights, verbose) - print('') - print(SEPARATOR) - print('Copyrights with dominant style:\ne.g. "Copyright (c)" and ' - '"" or "-":\n') - for holder_name in EXPECTED_HOLDER_NAMES: - dominant_style = [i['filename'] for i in file_infos if - i['dominant_style'][holder_name]] - if len(dominant_style) > 0: - print("%4d with '%s'" % (len(dominant_style), - holder_name.replace('\n', '\\n'))) - print_filenames(dominant_style, verbose) - print('') - print(SEPARATOR) - print('Copyrights with year list style:\ne.g. "Copyright (c)" and ' - '", , ...":\n') - for holder_name in EXPECTED_HOLDER_NAMES: - year_list_style = [i['filename'] for i in file_infos if - i['year_list_style'][holder_name]] - if len(year_list_style) > 0: - print("%4d with '%s'" % (len(year_list_style), - holder_name.replace('\n', '\\n'))) - print_filenames(year_list_style, verbose) - print('') - print(SEPARATOR) - print('Copyrights with no "(c)" style:\ne.g. "Copyright" and "" or ' - '"-":\n') - for holder_name in EXPECTED_HOLDER_NAMES: - without_c_style = [i['filename'] for i in file_infos if - i['without_c_style'][holder_name]] - if len(without_c_style) > 0: - print("%4d with '%s'" % (len(without_c_style), - holder_name.replace('\n', '\\n'))) - print_filenames(without_c_style, verbose) - - print('') - print(SEPARATOR) - - unclassified_copyrights = [i['filename'] for i in file_infos if - i['classified_copyrights'] < i['all_copyrights']] - print("%d with unexpected copyright holder names" % - len(unclassified_copyrights)) - print_filenames(unclassified_copyrights, verbose) - print(SEPARATOR) - -def exec_report(base_directory, verbose): - filenames = get_filenames_to_examine(base_directory) - file_infos = [gather_file_info(f) for f in filenames] - print_report(file_infos, verbose) - -################################################################################ -# report cmd -################################################################################ - -REPORT_USAGE = """ -Produces a report of all copyright header notices found inside the source files -of a repository. - -Usage: - $ ./copyright_header.py report [verbose] - -Arguments: - - The base directory of a bitcoin source code repository. - [verbose] - Includes a list of every file of each subcategory in the report. -""" - -def report_cmd(argv): - if len(argv) == 2: - sys.exit(REPORT_USAGE) - - base_directory = argv[2] - if not os.path.exists(base_directory): - sys.exit("*** bad : %s" % base_directory) - - if len(argv) == 3: - verbose = False - elif argv[3] == 'verbose': - verbose = True - else: - sys.exit("*** unknown argument: %s" % argv[2]) - - exec_report(base_directory, verbose) - -################################################################################ -# query git for year of last change -################################################################################ - -GIT_LOG_CMD = "git log --pretty=format:%%ai %s" - -def call_git_log(filename): - out = subprocess.check_output((GIT_LOG_CMD % filename).split(' '), text=True) - return out.split('\n') - -def get_git_change_years(filename): - git_log_lines = call_git_log(filename) - if len(git_log_lines) == 0: - return [datetime.date.today().year] - # timestamp is in ISO 8601 format. e.g. "2016-09-05 14:25:32 -0600" - return [line.split(' ')[0].split('-')[0] for line in git_log_lines] - -def get_most_recent_git_change_year(filename): - return max(get_git_change_years(filename)) - -################################################################################ -# read and write to file -################################################################################ - -def read_file_lines(filename): - with open(filename, 'r') as f: - file_lines = f.readlines() - return file_lines - -def write_file_lines(filename, file_lines): - with open(filename, 'w') as f: - f.write(''.join(file_lines)) - -################################################################################ -# update header years execution -################################################################################ - -COPYRIGHT = r'Copyright \(c\)' -YEAR = "20[0-9][0-9]" -YEAR_RANGE = '(%s)(-%s)?' % (YEAR, YEAR) -HOLDER = 'The Bitcoin Core developers' -UPDATEABLE_LINE_COMPILED = re.compile(' '.join([COPYRIGHT, YEAR_RANGE, HOLDER])) - -def get_updatable_copyright_line(file_lines): - index = 0 - for line in file_lines: - if UPDATEABLE_LINE_COMPILED.search(line) is not None: - return index, line - index = index + 1 - return None, None - -def parse_year_range(year_range): - year_split = year_range.split('-') - start_year = year_split[0] - if len(year_split) == 1: - return start_year, start_year - return start_year, year_split[1] - -def year_range_to_str(start_year, end_year): - if start_year == end_year: - return start_year - return "%s-%s" % (start_year, end_year) - -def create_updated_copyright_line(line, last_git_change_year): - copyright_splitter = 'Copyright (c) ' - copyright_split = line.split(copyright_splitter) - # Preserve characters on line that are ahead of the start of the copyright - # notice - they are part of the comment block and vary from file-to-file. - before_copyright = copyright_split[0] - after_copyright = copyright_split[1] - - space_split = after_copyright.split(' ') - year_range = space_split[0] - start_year, end_year = parse_year_range(year_range) - if end_year >= last_git_change_year: - return line - return (before_copyright + copyright_splitter + - year_range_to_str(start_year, last_git_change_year) + ' ' + - ' '.join(space_split[1:])) - -def update_updatable_copyright(filename): - file_lines = read_file_lines(filename) - index, line = get_updatable_copyright_line(file_lines) - if not line: - print_file_action_message(filename, "No updatable copyright.") - return - last_git_change_year = get_most_recent_git_change_year(filename) - new_line = create_updated_copyright_line(line, last_git_change_year) - if line == new_line: - print_file_action_message(filename, "Copyright up-to-date.") - return - file_lines[index] = new_line - write_file_lines(filename, file_lines) - print_file_action_message(filename, - "Copyright updated! -> %s" % last_git_change_year) - -def exec_update_header_year(base_directory): - for filename in get_filenames_to_examine(base_directory): - update_updatable_copyright(filename) - -################################################################################ -# update cmd -################################################################################ - -UPDATE_USAGE = """ -Updates all the copyright headers of "The Bitcoin Core developers" which were -changed in a year more recent than is listed. For example: - -// Copyright (c) - The Bitcoin Core developers - -will be updated to: - -// Copyright (c) - The Bitcoin Core developers - -where is obtained from the 'git log' history. - -This subcommand also handles copyright headers that have only a single year. In those cases: - -// Copyright (c) The Bitcoin Core developers - -will be updated to: - -// Copyright (c) - The Bitcoin Core developers - -where the update is appropriate. - -Usage: - $ ./copyright_header.py update - -Arguments: - - The base directory of a bitcoin source code repository. -""" - -def print_file_action_message(filename, action): - print("%-52s %s" % (filename, action)) - -def update_cmd(argv): - if len(argv) != 3: - sys.exit(UPDATE_USAGE) - - base_directory = argv[2] - if not os.path.exists(base_directory): - sys.exit("*** bad base_directory: %s" % base_directory) - exec_update_header_year(base_directory) - -################################################################################ -# inserted copyright header format -################################################################################ - -def get_header_lines(header, start_year, end_year): - lines = header.split('\n')[1:-1] - lines[0] = lines[0] % year_range_to_str(start_year, end_year) - return [line + '\n' for line in lines] - -CPP_HEADER = ''' -// Copyright (c) %s The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. -''' - -def get_cpp_header_lines_to_insert(start_year, end_year): - return reversed(get_header_lines(CPP_HEADER, start_year, end_year)) - -SCRIPT_HEADER = ''' -# Copyright (c) %s The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. -''' - -def get_script_header_lines_to_insert(start_year, end_year): - return reversed(get_header_lines(SCRIPT_HEADER, start_year, end_year)) - -################################################################################ -# query git for year of last change -################################################################################ - -def get_git_change_year_range(filename): - years = get_git_change_years(filename) - return min(years), max(years) - -################################################################################ -# check for existing core copyright -################################################################################ - -def file_already_has_core_copyright(file_lines): - index, _ = get_updatable_copyright_line(file_lines) - return index is not None - -################################################################################ -# insert header execution -################################################################################ - -def file_has_hashbang(file_lines): - if len(file_lines) < 1: - return False - if len(file_lines[0]) <= 2: - return False - return file_lines[0][:2] == '#!' - -def insert_script_header(filename, file_lines, start_year, end_year): - if file_has_hashbang(file_lines): - insert_idx = 1 - else: - insert_idx = 0 - header_lines = get_script_header_lines_to_insert(start_year, end_year) - for line in header_lines: - file_lines.insert(insert_idx, line) - write_file_lines(filename, file_lines) - -def insert_cpp_header(filename, file_lines, start_year, end_year): - file_lines.insert(0, '\n') - header_lines = get_cpp_header_lines_to_insert(start_year, end_year) - for line in header_lines: - file_lines.insert(0, line) - write_file_lines(filename, file_lines) - -def exec_insert_header(filename, style): - file_lines = read_file_lines(filename) - if file_already_has_core_copyright(file_lines): - sys.exit('*** %s already has a copyright by The Bitcoin Core developers' - % (filename)) - start_year, end_year = get_git_change_year_range(filename) - if style in ['python', 'shell']: - insert_script_header(filename, file_lines, start_year, end_year) - else: - insert_cpp_header(filename, file_lines, start_year, end_year) - -################################################################################ -# insert cmd -################################################################################ - -INSERT_USAGE = """ -Inserts a copyright header for "The Bitcoin Core developers" at the top of the -file in either Python or C++ style as determined by the file extension. If the -file is a Python file and it has a '#!' starting the first line, the header is -inserted in the line below it. - -The copyright dates will be set to be: - -"-" - -where is according to the 'git log' history. If - is equal to , the date will be set to be: - -"" - -If the file already has a copyright for "The Bitcoin Core developers", the -script will exit. - -Usage: - $ ./copyright_header.py insert - -Arguments: - - A source file in the bitcoin repository. -""" - -def insert_cmd(argv): - if len(argv) != 3: - sys.exit(INSERT_USAGE) - - filename = argv[2] - if not os.path.isfile(filename): - sys.exit("*** bad filename: %s" % filename) - _, extension = os.path.splitext(filename) - if extension not in ['.h', '.cpp', '.cc', '.c', '.py', '.sh']: - sys.exit("*** cannot insert for file extension %s" % extension) - - if extension == '.py': - style = 'python' - elif extension == '.sh': - style = 'shell' - else: - style = 'cpp' - exec_insert_header(filename, style) - -################################################################################ -# UI -################################################################################ - -USAGE = """ -copyright_header.py - utilities for managing copyright headers of 'The Bitcoin -Core developers' in repository source files. - -Usage: - $ ./copyright_header - -Subcommands: - report - update - insert - -To see subcommand usage, run them without arguments. -""" - -SUBCOMMANDS = ['report', 'update', 'insert'] - -if __name__ == "__main__": - if len(sys.argv) == 1: - sys.exit(USAGE) - subcommand = sys.argv[1] - if subcommand not in SUBCOMMANDS: - sys.exit(USAGE) - if subcommand == 'report': - report_cmd(sys.argv) - elif subcommand == 'update': - update_cmd(sys.argv) - elif subcommand == 'insert': - insert_cmd(sys.argv) diff --git a/depend/bitcoin/contrib/devtools/utils.py b/depend/bitcoin/contrib/devtools/utils.py deleted file mode 100755 index 7f37c607..00000000 --- a/depend/bitcoin/contrib/devtools/utils.py +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2021-present The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. -''' -Common utility functions -''' -import shutil -import sys -import os - - -def determine_wellknown_cmd(envvar, progname) -> list[str]: - maybe_env = os.getenv(envvar) - maybe_which = shutil.which(progname) - if maybe_env: - return maybe_env.split(' ') # Well-known vars are often meant to be word-split - elif maybe_which: - return [ maybe_which ] - else: - sys.exit(f"{progname} not found") diff --git a/depend/bitcoin/contrib/guix/guix-codesign b/depend/bitcoin/contrib/guix/guix-codesign index ac7aae3a..ec8fbc0c 100755 --- a/depend/bitcoin/contrib/guix/guix-codesign +++ b/depend/bitcoin/contrib/guix/guix-codesign @@ -328,16 +328,6 @@ EOF # container so that we have something to build. '/bitcoin' was # chosen arbitrarily. # - # ${SOURCES_PATH:+--share="$SOURCES_PATH"} - # - # make the downloaded depends sources path available - # inside the isolated container - # - # The isolated container has no network access as it's in a - # different network namespace from the main machine, so we have to - # make the downloaded depends sources available to it. The sources - # should have been downloaded prior to this invocation. - # # ${SUBSTITUTE_URLS:+--substitute-urls="$SUBSTITUTE_URLS"} # # fetch substitute from SUBSTITUTE_URLS if they are @@ -359,7 +349,6 @@ EOF --share="$DETACHED_SIGS_REPO"=/detached-sigs \ --expose="$(git rev-parse --git-common-dir)" \ --expose="$(git -C "$DETACHED_SIGS_REPO" rev-parse --git-common-dir)" \ - ${SOURCES_PATH:+--share="$SOURCES_PATH"} \ --cores="$JOBS" \ --keep-failed \ --fallback \ @@ -372,7 +361,6 @@ EOF JOBS="$JOBS" \ SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:?unable to determine value}" \ ${V:+V=1} \ - ${SOURCES_PATH:+SOURCES_PATH="$SOURCES_PATH"} \ DISTSRC="$(DISTSRC_BASE=/distsrc-base && distsrc_for_host "$HOST")" \ OUTDIR="$(OUTDIR_BASE=/outdir-base && outdir_for_host "$HOST" codesigned)" \ DIST_ARCHIVE_BASE=/outdir-base/dist-archive \ diff --git a/depend/bitcoin/contrib/guix/manifest.scm b/depend/bitcoin/contrib/guix/manifest.scm index 011ba0de..ea1ffe5d 100644 --- a/depend/bitcoin/contrib/guix/manifest.scm +++ b/depend/bitcoin/contrib/guix/manifest.scm @@ -2,6 +2,7 @@ ((gnu packages bash) #:select (bash-minimal)) (gnu packages bison) ((gnu packages certs) #:select (nss-certs)) + ((gnu packages check) #:select (libfaketime)) ((gnu packages cmake) #:select (cmake-minimal)) (gnu packages commencement) (gnu packages compression) @@ -93,7 +94,17 @@ chain for " target " development.")) (home-page (package-home-page xgcc)) (license (package-license xgcc))))) -(define base-gcc gcc-13) ;; 13.3.0 +(define base-gcc + (package + (inherit gcc-14) ;; 14.2.0 + (version "14.3.0") + (source (origin + (method url-fetch) + (uri (string-append "mirror://gnu/gcc/gcc-" + version "/gcc-" version ".tar.xz")) + (sha256 + (base32 + "0fna78ly417g69fdm4i5f3ms96g8xzzjza8gwp41lqr5fqlpgp70")))))) (define base-linux-kernel-headers linux-libre-headers-6.1) @@ -113,7 +124,7 @@ desirable for building Bitcoin Core release binaries." (define (gcc-libgcc-patches gcc) (package-with-extra-patches gcc - (search-our-patches "gcc-remap-guix-store.patch"))) + (search-our-patches "gcc-remap-guix-store.patch" "gcc-ssa-generation.patch"))) (define (binutils-mingw-patches binutils) (package-with-extra-patches binutils @@ -208,7 +219,17 @@ and abstract ELF, PE and MachO formats.") (base32 "1j47vwq4caxfv0xw68kw5yh00qcpbd56d7rq6c483ma3y7s96yyz")))) (build-system cmake-build-system) - (inputs (list openssl)) + (arguments + (list + #:phases + #~(modify-phases %standard-phases + (replace 'check + (lambda* (#:key tests? #:allow-other-keys) + (if tests? + (invoke "faketime" "-f" "@2025-01-01 00:00:00" ;; Tests fail after 2025. + "ctest" "--output-on-failure" "--no-tests=error") + (format #t "test suite not run~%"))))))) + (inputs (list libfaketime openssl)) (home-page "https://github.com/mtrojnar/osslsigncode") (synopsis "Authenticode signing and timestamping tool") (description "osslsigncode is a small tool that implements part of the @@ -421,7 +442,9 @@ inspecting signatures in Mach-O binaries.") ;; https://gcc.gnu.org/install/configure.html (list "--enable-threads=posix", "--enable-default-ssp=yes", + "--enable-host-bind-now=yes", "--disable-gcov", + "--disable-libgomp", building-on))))))) (define-public linux-base-gcc @@ -435,9 +458,13 @@ inspecting signatures in Mach-O binaries.") (list "--enable-initfini-array=yes", "--enable-default-ssp=yes", "--enable-default-pie=yes", + "--enable-host-bind-now=yes", "--enable-standard-branch-protection=yes", "--enable-cet=yes", + "--enable-gprofng=no", "--disable-gcov", + "--disable-libgomp", + "--disable-libquadmath", "--disable-libsanitizer", building-on))) ((#:phases phases) @@ -544,7 +571,7 @@ inspecting signatures in Mach-O binaries.") gzip xz ;; Build tools - gcc-toolchain-13 + gcc-toolchain-14 cmake-minimal gnu-make ninja @@ -564,7 +591,7 @@ inspecting signatures in Mach-O binaries.") ((string-contains target "-linux-") (list bison pkg-config - (list gcc-toolchain-13 "static") + (list gcc-toolchain-14 "static") (make-bitcoin-cross-toolchain target))) ((string-contains target "darwin") (list clang-toolchain-19 diff --git a/depend/bitcoin/contrib/guix/patches/gcc-ssa-generation.patch b/depend/bitcoin/contrib/guix/patches/gcc-ssa-generation.patch new file mode 100644 index 00000000..2e5a6002 --- /dev/null +++ b/depend/bitcoin/contrib/guix/patches/gcc-ssa-generation.patch @@ -0,0 +1,49 @@ +commit b46614ebfc57ccca8a050668ad0e8ba5968c5943 +Author: Jakub Jelinek +Date: Tue Jan 6 08:36:20 2026 +0100 + + tree-object-size: Deterministic SSA generation [PR123351] + + The order of evaluation of function arguments is unspecified in C++. + The function object_sizes_set_temp called object_sizes_set with two + calls to make_ssa_name() as arguments. Since make_ssa_name() has the + side effect of incrementing the global SSA version counter, different + architectures of the same compiler evaluated these calls in different + orders. + + This resulted in non-deterministic SSA version numbering between + x86_64 and aarch64 hosts during cross-compilation, leading to + divergent object files. + + Sequencing the calls into separate statements ensures deterministic + evaluation order. + + https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123351 + https://gcc.gnu.org/pipermail/gcc-patches/2026-January/704817.html + + 2026-01-06 Jakub Jelinek + Marco Falke + + PR tree-optimization/123351 + * tree-object-size.cc (object_sizes_set_temp): Separate calls to + make_ssa_name to ensure deterministic execution order. + +diff --git a/gcc/tree-object-size.cc b/gcc/tree-object-size.cc +index 018fbc30cbb..24e7d710371 100644 +--- a/gcc/tree-object-size.cc ++++ b/gcc/tree-object-size.cc +@@ -319,9 +319,11 @@ object_sizes_set_temp (struct object_size_info *osi, unsigned varno) + tree val = object_sizes_get (osi, varno); + + if (size_initval_p (val, osi->object_size_type)) +- object_sizes_set (osi, varno, +- make_ssa_name (sizetype), +- make_ssa_name (sizetype)); ++ { ++ val = make_ssa_name (sizetype); ++ tree wholeval = make_ssa_name (sizetype); ++ object_sizes_set (osi, varno, val, wholeval); ++ } + } + + /* Initialize OFFSET_LIMIT variable. */ diff --git a/depend/bitcoin/contrib/guix/symbol-check.py b/depend/bitcoin/contrib/guix/symbol-check.py index c32c1b5b..93002ddc 100755 --- a/depend/bitcoin/contrib/guix/symbol-check.py +++ b/depend/bitcoin/contrib/guix/symbol-check.py @@ -172,7 +172,7 @@ def check_version(max_versions, version, arch) -> bool: (lib, _, ver) = version.rpartition('_') ver = tuple([int(x) for x in ver.split('.')]) - if not lib in max_versions: + if lib not in max_versions: return False if isinstance(max_versions[lib], tuple): return ver <= max_versions[lib] diff --git a/depend/bitcoin/contrib/linearize/linearize-data.py b/depend/bitcoin/contrib/linearize/linearize-data.py index 9b29fe71..afaaca18 100755 --- a/depend/bitcoin/contrib/linearize/linearize-data.py +++ b/depend/bitcoin/contrib/linearize/linearize-data.py @@ -229,7 +229,7 @@ def run(self): inExtent = BlockExtent(self.inFn, self.inF.tell(), inhdr, blk_hdr, inLen) self.hash_str = calc_hash_str(blk_hdr) - if not self.hash_str in blkmap: + if self.hash_str not in blkmap: # Because blocks can be written to files out-of-order as of 0.10, the script # may encounter blocks it doesn't know about. Treat as debug output. if settings['debug_output'] == 'true': @@ -320,7 +320,7 @@ def run(self): blkmap = mkblockmap(blkindex) # Block hash map won't be byte-reversed. Neither should the genesis hash. - if not settings['genesis'] in blkmap: + if settings['genesis'] not in blkmap: print("Genesis block not found in hashlist") else: BlockDataCopier(settings, blkindex, blkmap).run() diff --git a/depend/bitcoin/contrib/verify-binaries/verify.py b/depend/bitcoin/contrib/verify-binaries/verify.py index af891122..c989e8bd 100755 --- a/depend/bitcoin/contrib/verify-binaries/verify.py +++ b/depend/bitcoin/contrib/verify-binaries/verify.py @@ -39,8 +39,6 @@ import shutil import tempfile import textwrap -import urllib.request -import urllib.error import enum from hashlib import sha256 from pathlib import PurePath, Path @@ -116,18 +114,6 @@ def download_with_wget(remote_file, local_file): return result.returncode == 0, result.stdout.decode().rstrip() -def download_lines_with_urllib(url) -> tuple[bool, list[str]]: - """Get (success, text lines of a file) over HTTP.""" - try: - return (True, [ - line.strip().decode() for line in urllib.request.urlopen(url).readlines()]) - except urllib.error.HTTPError as e: - log.warning(f"HTTP request to {url} failed (HTTPError): {e}") - except Exception as e: - log.warning(f"HTTP request to {url} failed ({e})") - return (False, []) - - def verify_with_gpg( filename, signature_filename, @@ -148,11 +134,6 @@ def verify_with_gpg( return result.returncode, gpg_data -def remove_files(filenames): - for filename in filenames: - os.remove(filename) - - class SigData: """GPG signature data as parsed from GPG stdout.""" def __init__(self): diff --git a/depend/bitcoin/contrib/verify-commits/trusted-keys b/depend/bitcoin/contrib/verify-commits/trusted-keys index f2548677..0121f290 100644 --- a/depend/bitcoin/contrib/verify-commits/trusted-keys +++ b/depend/bitcoin/contrib/verify-commits/trusted-keys @@ -3,3 +3,4 @@ D1DBF2C4B96F2DEBF4C16654410108112E7EA81F 152812300785C96444D3334D17565732E08E5E41 6B002C6EA3F91B1B0DF0C9BC8F617F1200A6D25C 4D1B3D5ECBA1A7E05371EEBE46800E30FC748A66 +A8FC55F3B04BA3146F3492E79303B33A305224CB diff --git a/depend/bitcoin/contrib/verify-commits/verify-commits.py b/depend/bitcoin/contrib/verify-commits/verify-commits.py index 1af6b031..b053fbd1 100755 --- a/depend/bitcoin/contrib/verify-commits/verify-commits.py +++ b/depend/bitcoin/contrib/verify-commits/verify-commits.py @@ -7,6 +7,7 @@ import hashlib import logging import os +from pathlib import Path import subprocess import sys import time @@ -80,20 +81,14 @@ def main(): args = parser.parse_args() # get directory of this program and read data files - dirname = os.path.dirname(os.path.abspath(__file__)) - print("Using verify-commits data from " + dirname) - with open(dirname + "/trusted-git-root", "r") as f: - verified_root = f.read().splitlines()[0] - with open(dirname + "/trusted-sha512-root-commit", "r") as f: - verified_sha512_root = f.read().splitlines()[0] - with open(dirname + "/allow-revsig-commits", "r") as f: - revsig_allowed = f.read().splitlines() - with open(dirname + "/allow-unclean-merge-commits", "r") as f: - unclean_merge_allowed = f.read().splitlines() - with open(dirname + "/allow-incorrect-sha512-commits", "r") as f: - incorrect_sha512_allowed = f.read().splitlines() - with open(dirname + "/trusted-keys", "r") as f: - trusted_keys = f.read().splitlines() + dirname = Path(__file__).absolute().parent + print(f"Using verify-commits data from {dirname}") + verified_root = (dirname / "trusted-git-root").read_text().splitlines()[0] + verified_sha512_root = (dirname / "trusted-sha512-root-commit").read_text().splitlines()[0] + revsig_allowed = (dirname / "allow-revsig-commits").read_text().splitlines() + unclean_merge_allowed = (dirname / "allow-unclean-merge-commits").read_text().splitlines() + incorrect_sha512_allowed = (dirname / "allow-incorrect-sha512-commits").read_text().splitlines() + trusted_keys = (dirname / "trusted-keys").read_text().splitlines() # Set commit and variables current_commit = args.commit diff --git a/depend/bitcoin/depends/packages/boost.mk b/depend/bitcoin/depends/packages/boost.mk index 312f19e2..2d027c68 100644 --- a/depend/bitcoin/depends/packages/boost.mk +++ b/depend/bitcoin/depends/packages/boost.mk @@ -1,9 +1,8 @@ package=boost -$(package)_version = 1.88.0 +$(package)_version = 1.90.0 $(package)_download_path = https://github.com/boostorg/boost/releases/download/boost-$($(package)_version) $(package)_file_name = boost-$($(package)_version)-cmake.tar.gz -$(package)_sha256_hash = dcea50f40ba1ecfc448fdf886c0165cf3e525fef2c9e3e080b9804e8117b9694 -$(package)_patches = skip_compiled_targets.patch +$(package)_sha256_hash = 913ca43d49e93d1b158c9862009add1518a4c665e7853b349a6492d158b036d4 $(package)_build_subdir = build define $(package)_set_vars @@ -16,10 +15,6 @@ define $(package)_set_vars $(package)_config_opts += -DCMAKE_DISABLE_FIND_PACKAGE_ICU=ON endef -define $(package)_preprocess_cmds - patch -p1 < $($(package)_patch_dir)/skip_compiled_targets.patch -endef - define $(package)_config_cmds $($(package)_cmake) -S .. -B . endef diff --git a/depend/bitcoin/depends/packages/native_capnp.mk b/depend/bitcoin/depends/packages/native_capnp.mk index a3a089d4..0cd0dcdf 100644 --- a/depend/bitcoin/depends/packages/native_capnp.mk +++ b/depend/bitcoin/depends/packages/native_capnp.mk @@ -1,9 +1,9 @@ package=native_capnp -$(package)_version=1.2.0 +$(package)_version=1.3.0 $(package)_download_path=https://capnproto.org/ $(package)_download_file=capnproto-c++-$($(package)_version).tar.gz $(package)_file_name=capnproto-cxx-$($(package)_version).tar.gz -$(package)_sha256_hash=ed00e44ecbbda5186bc78a41ba64a8dc4a861b5f8d4e822959b0144ae6fd42ef +$(package)_sha256_hash=098f824a495a1a837d56ae17e07b3f721ac86f8dbaf58896a389923458522108 define $(package)_set_vars $(package)_config_opts := -DBUILD_TESTING=OFF diff --git a/depend/bitcoin/depends/patches/boost/skip_compiled_targets.patch b/depend/bitcoin/depends/patches/boost/skip_compiled_targets.patch deleted file mode 100644 index 32b69ce6..00000000 --- a/depend/bitcoin/depends/patches/boost/skip_compiled_targets.patch +++ /dev/null @@ -1,136 +0,0 @@ -cmake: Add `BOOST_TEST_HEADERS_ONLY` configuration variable - -This change allows the build to be configured to install only the -Boost.Test headers required for using the headers-only variant of the -Unit Test Framework. - -Upstream commit: 097e97820e654ead9c477b47443a545cef5d3b12 - - ---- a/libs/test/CMakeLists.txt -+++ b/libs/test/CMakeLists.txt -@@ -30,60 +30,70 @@ set(_boost_test_dependencies - Boost::utility - ) - --# Compiled targets -+option(BOOST_TEST_HEADERS_ONLY "Boost.Test: Only install headers" OFF) - --function(boost_test_add_library name) -+set(_boost_test_libraries "") - -- add_library(boost_${name} ${ARGN}) -- add_library(Boost::${name} ALIAS boost_${name}) -+if (NOT BOOST_TEST_HEADERS_ONLY) - -- target_include_directories(boost_${name} PUBLIC include) -- target_link_libraries(boost_${name} PUBLIC ${_boost_test_dependencies}) -+ # Compiled targets - -- target_compile_definitions(boost_${name} -- PUBLIC BOOST_TEST_NO_LIB -- # Source files already define BOOST_TEST_SOURCE -- # PRIVATE BOOST_TEST_SOURCE -- ) -+ function(boost_test_add_library name) - -- if(BUILD_SHARED_LIBS) -- target_compile_definitions(boost_${name} PUBLIC BOOST_TEST_DYN_LINK) -- else() -- target_compile_definitions(boost_${name} PUBLIC BOOST_TEST_STATIC_LINK) -- endif() -+ add_library(boost_${name} ${ARGN}) -+ add_library(Boost::${name} ALIAS boost_${name}) - --endfunction() -+ target_include_directories(boost_${name} PUBLIC include) -+ target_link_libraries(boost_${name} PUBLIC ${_boost_test_dependencies}) - --boost_test_add_library(prg_exec_monitor -- src/cpp_main.cpp -- src/debug.cpp -- src/execution_monitor.cpp --) -+ target_compile_definitions(boost_${name} -+ PUBLIC BOOST_TEST_NO_LIB -+ # Source files already define BOOST_TEST_SOURCE -+ # PRIVATE BOOST_TEST_SOURCE -+ ) - --set(SOURCES -- src/compiler_log_formatter.cpp -- src/debug.cpp -- src/decorator.cpp -- src/execution_monitor.cpp -- src/framework.cpp -- src/junit_log_formatter.cpp -- src/plain_report_formatter.cpp -- src/progress_monitor.cpp -- src/results_collector.cpp -- src/results_reporter.cpp -- src/test_framework_init_observer.cpp -- src/test_tools.cpp -- src/test_tree.cpp -- src/unit_test_log.cpp -- src/unit_test_main.cpp -- src/unit_test_monitor.cpp -- src/unit_test_parameters.cpp -- src/xml_log_formatter.cpp -- src/xml_report_formatter.cpp --) -+ if(BUILD_SHARED_LIBS) -+ target_compile_definitions(boost_${name} PUBLIC BOOST_TEST_DYN_LINK) -+ else() -+ target_compile_definitions(boost_${name} PUBLIC BOOST_TEST_STATIC_LINK) -+ endif() -+ -+ endfunction() - --boost_test_add_library(test_exec_monitor STATIC ${SOURCES} src/test_main.cpp) --boost_test_add_library(unit_test_framework ${SOURCES}) -+ boost_test_add_library(prg_exec_monitor -+ src/cpp_main.cpp -+ src/debug.cpp -+ src/execution_monitor.cpp -+ ) -+ -+ set(SOURCES -+ src/compiler_log_formatter.cpp -+ src/debug.cpp -+ src/decorator.cpp -+ src/execution_monitor.cpp -+ src/framework.cpp -+ src/junit_log_formatter.cpp -+ src/plain_report_formatter.cpp -+ src/progress_monitor.cpp -+ src/results_collector.cpp -+ src/results_reporter.cpp -+ src/test_framework_init_observer.cpp -+ src/test_tools.cpp -+ src/test_tree.cpp -+ src/unit_test_log.cpp -+ src/unit_test_main.cpp -+ src/unit_test_monitor.cpp -+ src/unit_test_parameters.cpp -+ src/xml_log_formatter.cpp -+ src/xml_report_formatter.cpp -+ ) -+ -+ boost_test_add_library(test_exec_monitor STATIC ${SOURCES} src/test_main.cpp) -+ boost_test_add_library(unit_test_framework ${SOURCES}) -+ -+ set(_boost_test_libraries boost_prg_exec_monitor boost_test_exec_monitor boost_unit_test_framework) -+ -+endif() - - # Header-only targets - -@@ -107,7 +117,7 @@ if(BOOST_SUPERPROJECT_VERSION AND NOT CMAKE_VERSION VERSION_LESS 3.13) - - boost_install( - TARGETS -- boost_prg_exec_monitor boost_test_exec_monitor boost_unit_test_framework -+ ${_boost_test_libraries} - boost_included_prg_exec_monitor boost_included_test_exec_monitor boost_included_unit_test_framework - VERSION ${BOOST_SUPERPROJECT_VERSION} - HEADER_DIRECTORY include diff --git a/depend/bitcoin/doc/bips.md b/depend/bitcoin/doc/bips.md index 97645d0e..c814717a 100644 --- a/depend/bitcoin/doc/bips.md +++ b/depend/bitcoin/doc/bips.md @@ -73,3 +73,4 @@ BIPs that are implemented by Bitcoin Core: * [`BIP 386`](https://github.com/bitcoin/bips/blob/master/bip-0386.mediawiki): tr() Output Script Descriptors are implemented as of **v22.0** ([PR 22051](https://github.com/bitcoin/bitcoin/pull/22051)). * [`BIP 387`](https://github.com/bitcoin/bips/blob/master/bip-0387.mediawiki): Tapscript Multisig Output Script Descriptors are implemented as of **v24.0** ([PR 24043](https://github.com/bitcoin/bitcoin/pull/24043)). * [`BIP 431`](https://github.com/bitcoin/bips/blob/master/bip-0431.mediawiki): transactions with nVersion=3 are standard and treated as Topologically Restricted Until Confirmation as of **v28.0** ([PR 29496](https://github.com/bitcoin/bitcoin/pull/29496)). +* [`BIP 433`](https://github.com/bitcoin/bips/blob/master/bip-0433.mediawiki): Spending of Pay to Anchor (P2A) outputs is standard as of **v28.0** ([PR 30352](https://github.com/bitcoin/bitcoin/pull/30352)). diff --git a/depend/bitcoin/doc/build-openbsd.md b/depend/bitcoin/doc/build-openbsd.md index fdeafe88..4ea58795 100644 --- a/depend/bitcoin/doc/build-openbsd.md +++ b/depend/bitcoin/doc/build-openbsd.md @@ -1,6 +1,6 @@ # OpenBSD Build Guide -**Updated for OpenBSD [7.6](https://www.openbsd.org/76.html)** +**Updated for OpenBSD [7.8](https://www.openbsd.org/78.html)** This guide describes how to build bitcoind, command-line utilities, and GUI on OpenBSD. @@ -21,8 +21,11 @@ pkg_add sqlite3 To build Bitcoin Core without the wallet, use `-DENABLE_WALLET=OFF`. -Cap'n Proto is needed for IPC functionality (see [multiprocess.md](multiprocess.md)) -and can be built from source: https://capnproto.org/install.html +Cap'n Proto is needed for IPC functionality (see [multiprocess.md](multiprocess.md)): + +```bash +pkg_add capnproto +``` Compile with `-DENABLE_IPC=OFF` if you do not need IPC functionality. diff --git a/depend/bitcoin/doc/developer-notes.md b/depend/bitcoin/doc/developer-notes.md index d17f8024..b8a16ec0 100644 --- a/depend/bitcoin/doc/developer-notes.md +++ b/depend/bitcoin/doc/developer-notes.md @@ -558,6 +558,21 @@ llvm-cov show \ The generated coverage report can be accessed at `build/coverage_report/index.html`. +### Using IWYU + +The [`include-what-you-use`](https://github.com/include-what-you-use/include-what-you-use) tool (IWYU) +helps to enforce the source code organization [policy](#source-code-organization) in this repository. + +To ensure consistency, it is recommended to run the IWYU CI job locally rather than running the tool directly. + +In some cases, IWYU might suggest headers that seem unnecessary at first glance, but are actually required. +For example, a macro may use a symbol that requires its own include. Another example is passing a string literal +to a function that accepts a `std::string` parameter. An implicit conversion occurs at the callsite using the +`std::string` constructor, which makes the corresponding header required. We accept these suggestions as is. + +Use `IWYU pragma: export` very sparingly, as this enforces transitive inclusion of headers +and undermines the specific purpose of IWYU. + ### Performance profiling with perf Profiling is a good way to get a precise idea of where time is being spent in @@ -1057,7 +1072,7 @@ Write scripts in Python or Rust rather than bash, when possible. - *Rationale*: Excluding headers because they are already indirectly included results in compilation failures when those indirect dependencies change. Furthermore, it obscures what the real code - dependencies are. + dependencies are. The [Using IWYU](#using-iwyu) section describes a tool to help enforce this. - Don't import anything into the global namespace (`using namespace ...`). Use fully specified types such as `std::string`. diff --git a/depend/bitcoin/doc/policy/packages.md b/depend/bitcoin/doc/policy/packages.md index d48afed4..71b1f2e4 100644 --- a/depend/bitcoin/doc/policy/packages.md +++ b/depend/bitcoin/doc/policy/packages.md @@ -99,14 +99,6 @@ submitted as a package. transaction (i.e. in which a replacement transaction with a higher fee cannot be signed) being rejected from the mempool when transaction volume is high and the mempool minimum feerate rises. -*Rationale*: Avoid situations in which the mempool contains non-bumped transactions below min relay -feerate (which we consider to have pay 0 fees and thus receiving free relay). While package -submission would ensure these transactions are bumped at the time of entry, it is not guaranteed -that the transaction will always be bumped. For example, a later transaction could replace the -fee-bumping child without still bumping the parent. These no-longer-bumped transactions should be -removed during a replacement, but we do not have a DoS-resistant way of removing them or enforcing a -limit on their quantity. Instead, prevent their entry into the mempool. - Implementation Note: Transactions within a package are always validated individually first, and package validation is used for the transactions that failed. Since package feerate is only calculated using transactions that are not in the mempool, this implementation detail affects the diff --git a/depend/bitcoin/doc/release-notes-29415.md b/depend/bitcoin/doc/release-notes-29415.md new file mode 100644 index 00000000..d5040a31 --- /dev/null +++ b/depend/bitcoin/doc/release-notes-29415.md @@ -0,0 +1,14 @@ +P2P and network changes +----------------------- + +- Normally local transactions are broadcast to all connected peers with + which we do transaction relay. Now, for the `sendrawtransaction` RPC + this behavior can be changed to only do the broadcast via the Tor or + I2P networks. A new boolean option `-privatebroadcast` has been added + to enable this behavior. This improves the privacy of the transaction + originator in two aspects: + 1. Their IP address (and thus geolocation) is never known to the + recipients. + 2. If the originator sends two otherwise unrelated transactions, they + will not be linkable. This is because a separate connection is used + for broadcasting each transaction. (#29415) diff --git a/depend/bitcoin/doc/release-notes-33629.md b/depend/bitcoin/doc/release-notes-33629.md index 16bdf0fd..46adf220 100644 --- a/depend/bitcoin/doc/release-notes-33629.md +++ b/depend/bitcoin/doc/release-notes-33629.md @@ -41,3 +41,11 @@ are noted: mempool. - Chunk size and chunk fees are now also included in the output of `getmempoolentry`. + +- The "CPFP Carveout" has been removed from the mempool logic. The CPFP carveout + allowed one additional child transaction to be added to a package that's already + at its descendant limit, but only if that child has exactly one ancestor + (the package's root) and is small (no larger than 10kvB). Nothing is allowed to + bypass the cluster count limit. It is expected that smart contracting use-cases + requiring similar functionality employ TRUC transactions and sibling eviction + instead going forward. diff --git a/depend/bitcoin/doc/release-notes-33819.md b/depend/bitcoin/doc/release-notes-33819.md new file mode 100644 index 00000000..79ed1f70 --- /dev/null +++ b/depend/bitcoin/doc/release-notes-33819.md @@ -0,0 +1,8 @@ +Mining IPC +---------- + +- The `getCoinbaseTx()` method is renamed to `getCoinbaseRawTx()` and deprecated. + IPC clients do not use the function name, so they're not affected. (#33819) +- Adds `getCoinbaseTx()` which clients should use instead of `getCoinbaseRawTx()`. It + contains all fields required to construct a coinbase transaction, and omits the + dummy output which Bitcoin Core uses internally. (#33819) diff --git a/depend/bitcoin/doc/release-notes-34197.md b/depend/bitcoin/doc/release-notes-34197.md new file mode 100644 index 00000000..377ca9cc --- /dev/null +++ b/depend/bitcoin/doc/release-notes-34197.md @@ -0,0 +1,7 @@ +Updated RPCs +------------ + +- The `getpeerinfo` RPC no longer returns the `startingheight` field unless + the configuration option `-deprecatedrpc=startingheight` is used. The + `startingheight` field will be fully removed in the next major release. + (#34197) diff --git a/depend/bitcoin/doc/release-notes/release-notes-30.1.md b/depend/bitcoin/doc/release-notes/release-notes-30.1.md new file mode 100644 index 00000000..3299af4e --- /dev/null +++ b/depend/bitcoin/doc/release-notes/release-notes-30.1.md @@ -0,0 +1,108 @@ +v30.1 Release Notes +=================== + +Bitcoin Core version v30.1 is now available from: + + + +This release includes new features, various bug fixes and performance +improvements, as well as updated translations. + +Please report bugs using the issue tracker at GitHub: + + + +To receive security and update notifications, please subscribe to: + + + +How to Upgrade +============== + +If you are running an older version, shut it down. Wait until it has completely +shut down (which might take a few minutes in some cases), then run the +installer (on Windows) or just copy over `/Applications/Bitcoin-Qt` (on macOS) +or `bitcoind`/`bitcoin-qt` (on Linux). + +Upgrading directly from a version of Bitcoin Core that has reached its EOL is +possible, but it might take some time if the data directory needs to be migrated. Old +wallet versions of Bitcoin Core are generally supported. + +Compatibility +============== + +Bitcoin Core is supported and tested on operating systems using the +Linux Kernel 3.17+, macOS 13+, and Windows 10+. Bitcoin +Core should also work on most other Unix-like systems but is not as +frequently tested on them. It is not recommended to use Bitcoin Core on +unsupported systems. + +Notable changes +=============== + +### Wallet + +- #33528 wallet: don't consider unconfirmed TRUC coins with ancestors + +### Build + +- #33580 depends: Use `$(package)_file_name` when downloading from the fallback +- #33906 depends: Add patch for Windows11Style plugin +- #32009 contrib: turn off compression of macOS SDK to fix determinism + +### IPC + +- #33229 multiprocess: Don't require bitcoin -m argument when IPC options are used +- #33517 multiprocess: Fix high overhead from message logging +- #33519 Update libmultiprocess subtree in 30.x branch +- #33566 miner: fix empty mempool case for waitNext() +- #33676 interfaces: enable cancelling running waitNext calls + +### P2P + +- #33723 chainparams: remove dnsseed.bitcoin.dashjr-list-of-p2p-nodes.us + +### GUI + +- gui#899 qt: Modernize custom filtering +- gui#901 Add createwallet, createwalletdescriptor, and migratewallet to history filter + +### Test + +- #33612 test: change log rate limit version gate + +### Doc + +- #33630 doc: correct topology requirements in submitpackage helptext +- #33826 scripted-diff: Remove obsolete comment +- #33827 doc: Correct pkgin command usage on NetBSD + +### Misc + +- #33508 ci: fix buildx gha cache authentication on forks +- #33558 ci: Use native platform for win-cross task +- #33581 ci: Properly include $FILE_ENV in DEPENDS_HASH +- #33744 ci: Fix lint runner selection (and docker cache) +- #33996 contrib: fix manpage generation + +Credits +======= + +Thanks to everyone who directly contributed to this release: + +- Ava Chow +- Cory Fields +- Eugene Siegel +- fanquake +- glozow +- Hennadii Stepanov +- ismaelsadeeq +- MarcoFalke +- Ryan Ofsky +- SatsAndSports +- Sjors Provoost +- WakeTrainDev +- willcl-ark + +As well as to everyone that helped with translations on +[Transifex](https://explore.transifex.com/bitcoin/bitcoin/). diff --git a/depend/bitcoin/doc/release-notes/release-notes-30.2.md b/depend/bitcoin/doc/release-notes/release-notes-30.2.md new file mode 100644 index 00000000..888b3f91 --- /dev/null +++ b/depend/bitcoin/doc/release-notes/release-notes-30.2.md @@ -0,0 +1,91 @@ +v30.2 Release Notes +=================== + +Bitcoin Core version v30.2 is now available from: + + + +This release includes new features, various bug fixes and performance +improvements, as well as updated translations. + +Please report bugs using the issue tracker at GitHub: + + + +To receive security and update notifications, please subscribe to: + + + +How to Upgrade +============== + +If you are running an older version, shut it down. Wait until it has completely +shut down (which might take a few minutes in some cases), then run the +installer (on Windows) or just copy over `/Applications/Bitcoin-Qt` (on macOS) +or `bitcoind`/`bitcoin-qt` (on Linux). + +Upgrading directly from a version of Bitcoin Core that has reached its EOL is +possible, but it might take some time if the data directory needs to be migrated. Old +wallet versions of Bitcoin Core are generally supported. + +Compatibility +============== + +Bitcoin Core is supported and tested on operating systems using the +Linux Kernel 3.17+, macOS 13+, and Windows 10+. Bitcoin +Core should also work on most other Unix-like systems but is not as +frequently tested on them. It is not recommended to use Bitcoin Core on +unsupported systems. + +Notable changes +=============== + +### Wallet + +- #34156 wallet: fix unnamed legacy wallet migration failure +- #34215 wallettool: fix unnamed createfromdump failure walletsdir deletion +- #34221 test: migration, avoid backup name mismatch in default_wallet_failure + +### IPC + +- #33511 init: Fix Ctrl-C shutdown hangs during wait calls + +### Build + +- #33950 guix: reduce allowed exported symbols +- #34107 build: Update minimum required Boost version +- #34227 guix: Fix osslsigncode tests + +### Test + +- #34137 test: Avoid hard time.sleep(1) in feature_init.py +- #34226 wallet: test: Relative wallet failed migration cleanup + +### Fuzz + +- #34091 fuzz: doc: remove any mention to address_deserialize_v2 + +### Doc + +- #34182 doc: Update OpenBSD Build Guide + +### Misc + +- #34174 doc: update copyright year to 2026 + +Credits +======= + +Thanks to everyone who directly contributed to this release: + +- Ava Chow +- brunoerg +- davidgumberg +- fanquake +- furszy +- Hennadii Stepanov +- MarcoFalke +- Ryan Ofsky + +As well as to everyone that helped with translations on +[Transifex](https://explore.transifex.com/bitcoin/bitcoin/). diff --git a/depend/bitcoin/src/.clang-format b/depend/bitcoin/src/.clang-format index 4db09138..2b74e40b 100644 --- a/depend/bitcoin/src/.clang-format +++ b/depend/bitcoin/src/.clang-format @@ -142,6 +142,7 @@ LambdaBodyIndentation: Signature LineEnding: DeriveLF MacroBlockBegin: '' MacroBlockEnd: '' +MainIncludeChar: AngleBracket MaxEmptyLinesToKeep: 2 NamespaceIndentation: None ObjCBinPackProtocolList: Auto diff --git a/depend/bitcoin/src/.clang-tidy b/depend/bitcoin/src/.clang-tidy index 01153649..f54e07fa 100644 --- a/depend/bitcoin/src/.clang-tidy +++ b/depend/bitcoin/src/.clang-tidy @@ -24,6 +24,7 @@ performance-*, -performance-no-int-to-ptr, -performance-noexcept-move-constructor, -performance-unnecessary-value-param, +readability-avoid-const-params-in-decls, readability-const-return-type, readability-container-contains, readability-redundant-declaration, @@ -40,3 +41,5 @@ CheckOptions: value: false - key: bugprone-unused-return-value.CheckedReturnTypes value: '^::std::error_code$;^::std::error_condition$;^::std::errc$;^::std::expected$;^::util::Result$;^::util::Expected$' + - key: bugprone-unused-return-value.AllowCastToVoid + value: true # Can be removed with C++26 once the _ placeholder exists. diff --git a/depend/bitcoin/src/CMakeLists.txt b/depend/bitcoin/src/CMakeLists.txt index 43d67f40..cf1f26c9 100644 --- a/depend/bitcoin/src/CMakeLists.txt +++ b/depend/bitcoin/src/CMakeLists.txt @@ -106,8 +106,7 @@ add_library(bitcoin_common STATIC EXCLUDE_FROM_ALL common/system.cpp common/url.cpp compressor.cpp - core_read.cpp - core_write.cpp + core_io.cpp deploymentinfo.cpp external_signer.cpp init/common.cpp @@ -244,6 +243,7 @@ add_library(bitcoin_node STATIC EXCLUDE_FROM_ALL policy/rbf.cpp policy/settings.cpp policy/truc_policy.cpp + private_broadcast.cpp rest.cpp rpc/blockchain.cpp rpc/external_signer.cpp diff --git a/depend/bitcoin/src/addrman.h b/depend/bitcoin/src/addrman.h index 3a323014..8368e30b 100644 --- a/depend/bitcoin/src/addrman.h +++ b/depend/bitcoin/src/addrman.h @@ -172,7 +172,7 @@ class AddrMan * * @return A vector of randomly selected addresses from vRandom. */ - std::vector GetAddr(size_t max_addresses, size_t max_pct, std::optional network, const bool filtered = true) const; + std::vector GetAddr(size_t max_addresses, size_t max_pct, std::optional network, bool filtered = true) const; /** * Returns an information-location pair for all addresses in the selected addrman table. diff --git a/depend/bitcoin/src/addrman_impl.h b/depend/bitcoin/src/addrman_impl.h index f825d20b..c1716f89 100644 --- a/depend/bitcoin/src/addrman_impl.h +++ b/depend/bitcoin/src/addrman_impl.h @@ -135,7 +135,7 @@ class AddrManImpl std::pair Select(bool new_only, const std::unordered_set& networks) const EXCLUSIVE_LOCKS_REQUIRED(!cs); - std::vector GetAddr(size_t max_addresses, size_t max_pct, std::optional network, const bool filtered = true) const + std::vector GetAddr(size_t max_addresses, size_t max_pct, std::optional network, bool filtered = true) const EXCLUSIVE_LOCKS_REQUIRED(!cs); std::vector> GetEntries(bool from_tried) const @@ -267,7 +267,7 @@ class AddrManImpl * */ nid_type GetEntry(bool use_tried, size_t bucket, size_t position) const EXCLUSIVE_LOCKS_REQUIRED(cs); - std::vector GetAddr_(size_t max_addresses, size_t max_pct, std::optional network, const bool filtered = true) const EXCLUSIVE_LOCKS_REQUIRED(cs); + std::vector GetAddr_(size_t max_addresses, size_t max_pct, std::optional network, bool filtered = true) const EXCLUSIVE_LOCKS_REQUIRED(cs); std::vector> GetEntries_(bool from_tried) const EXCLUSIVE_LOCKS_REQUIRED(cs); diff --git a/depend/bitcoin/src/bench/CMakeLists.txt b/depend/bitcoin/src/bench/CMakeLists.txt index e0e03b1d..50b29a14 100644 --- a/depend/bitcoin/src/bench/CMakeLists.txt +++ b/depend/bitcoin/src/bench/CMakeLists.txt @@ -84,8 +84,4 @@ if(ENABLE_WALLET) target_link_libraries(bench_bitcoin bitcoin_wallet) endif() -add_test(NAME bench_sanity_check - COMMAND bench_bitcoin -sanity-check -) - install_binary_component(bench_bitcoin INTERNAL) diff --git a/depend/bitcoin/src/bench/addrman.cpp b/depend/bitcoin/src/bench/addrman.cpp index 4ba02242..907c7d2e 100644 --- a/depend/bitcoin/src/bench/addrman.cpp +++ b/depend/bitcoin/src/bench/addrman.cpp @@ -175,9 +175,9 @@ static void AddrManAddThenGood(benchmark::Bench& bench) }); } -BENCHMARK(AddrManAdd, benchmark::PriorityLevel::HIGH); -BENCHMARK(AddrManSelect, benchmark::PriorityLevel::HIGH); -BENCHMARK(AddrManSelectFromAlmostEmpty, benchmark::PriorityLevel::HIGH); -BENCHMARK(AddrManSelectByNetwork, benchmark::PriorityLevel::HIGH); -BENCHMARK(AddrManGetAddr, benchmark::PriorityLevel::HIGH); -BENCHMARK(AddrManAddThenGood, benchmark::PriorityLevel::HIGH); +BENCHMARK(AddrManAdd); +BENCHMARK(AddrManSelect); +BENCHMARK(AddrManSelectFromAlmostEmpty); +BENCHMARK(AddrManSelectByNetwork); +BENCHMARK(AddrManGetAddr); +BENCHMARK(AddrManAddThenGood); diff --git a/depend/bitcoin/src/bench/base58.cpp b/depend/bitcoin/src/bench/base58.cpp index bc82d739..0be16439 100644 --- a/depend/bitcoin/src/bench/base58.cpp +++ b/depend/bitcoin/src/bench/base58.cpp @@ -51,6 +51,6 @@ static void Base58Decode(benchmark::Bench& bench) } -BENCHMARK(Base58Encode, benchmark::PriorityLevel::HIGH); -BENCHMARK(Base58CheckEncode, benchmark::PriorityLevel::HIGH); -BENCHMARK(Base58Decode, benchmark::PriorityLevel::HIGH); +BENCHMARK(Base58Encode); +BENCHMARK(Base58CheckEncode); +BENCHMARK(Base58Decode); diff --git a/depend/bitcoin/src/bench/bech32.cpp b/depend/bitcoin/src/bench/bech32.cpp index 065ee9e7..c5e864ae 100644 --- a/depend/bitcoin/src/bench/bech32.cpp +++ b/depend/bitcoin/src/bench/bech32.cpp @@ -31,5 +31,5 @@ static void Bech32Decode(benchmark::Bench& bench) } -BENCHMARK(Bech32Encode, benchmark::PriorityLevel::HIGH); -BENCHMARK(Bech32Decode, benchmark::PriorityLevel::HIGH); +BENCHMARK(Bech32Encode); +BENCHMARK(Bech32Decode); diff --git a/depend/bitcoin/src/bench/bench.cpp b/depend/bitcoin/src/bench/bench.cpp index 3eb99ab5..0b2ee6e3 100644 --- a/depend/bitcoin/src/bench/bench.cpp +++ b/depend/bitcoin/src/bench/bench.cpp @@ -5,25 +5,20 @@ #include #include // IWYU pragma: keep -#include +#include #include -#include #include #include #include #include #include -#include -#include #include -#include -#include #include +#include #include using namespace std::chrono_literals; -using util::Join; const std::function G_TEST_LOG_FUN{}; @@ -69,37 +64,15 @@ void GenerateTemplateResults(const std::vector& bench namespace benchmark { -// map a label to one or multiple priority levels -std::map map_label_priority = { - {"high", PriorityLevel::HIGH}, - {"low", PriorityLevel::LOW}, - {"all", 0xff} -}; - -std::string ListPriorities() -{ - using item_t = std::pair; - auto sort_by_priority = [](item_t a, item_t b){ return a.second < b.second; }; - std::set sorted_priorities(map_label_priority.begin(), map_label_priority.end(), sort_by_priority); - return Join(sorted_priorities, ',', [](const auto& entry){ return entry.first; }); -} - -uint8_t StringToPriority(const std::string& str) -{ - auto it = map_label_priority.find(str); - if (it == map_label_priority.end()) throw std::runtime_error(strprintf("Unknown priority level %s", str)); - return it->second; -} - BenchRunner::BenchmarkMap& BenchRunner::benchmarks() { static BenchmarkMap benchmarks_map; return benchmarks_map; } -BenchRunner::BenchRunner(std::string name, BenchFunction func, PriorityLevel level) +BenchRunner::BenchRunner(std::string name, BenchFunction func) { - benchmarks().insert(std::make_pair(name, std::make_pair(func, level))); + Assert(benchmarks().try_emplace(std::move(name), std::move(func)).second); } void BenchRunner::RunAll(const Args& args) @@ -120,12 +93,7 @@ void BenchRunner::RunAll(const Args& args) }; std::vector benchmarkResults; - for (const auto& [name, bench_func] : benchmarks()) { - const auto& [func, priority_level] = bench_func; - - if (!(priority_level & args.priority)) { - continue; - } + for (const auto& [name, func] : benchmarks()) { if (!std::regex_match(name, baseMatch, reFilter)) { continue; diff --git a/depend/bitcoin/src/bench/bench.h b/depend/bitcoin/src/bench/bench.h index f6c41486..f7df42a3 100644 --- a/depend/bitcoin/src/bench/bench.h +++ b/depend/bitcoin/src/bench/bench.h @@ -10,11 +10,9 @@ #include #include -#include #include #include #include -#include #include /* @@ -40,17 +38,7 @@ namespace benchmark { using ankerl::nanobench::Bench; -typedef std::function BenchFunction; - -enum PriorityLevel : uint8_t -{ - LOW = 1 << 0, - HIGH = 1 << 2, -}; - -// List priority labels, comma-separated and sorted by increasing priority -std::string ListPriorities(); -uint8_t StringToPriority(const std::string& str); +using BenchFunction = std::function; struct Args { bool is_list_only; @@ -60,25 +48,24 @@ struct Args { fs::path output_csv; fs::path output_json; std::string regex_filter; - uint8_t priority; std::vector setup_args; }; class BenchRunner { - // maps from "name" -> (function, priority_level) - typedef std::map> BenchmarkMap; + // maps from "name" -> function + using BenchmarkMap = std::map; static BenchmarkMap& benchmarks(); public: - BenchRunner(std::string name, BenchFunction func, PriorityLevel level); + BenchRunner(std::string name, BenchFunction func); static void RunAll(const Args& args); }; } // namespace benchmark -// BENCHMARK(foo) expands to: benchmark::BenchRunner bench_11foo("foo", foo, priority_level); -#define BENCHMARK(n, priority_level) \ - benchmark::BenchRunner PASTE2(bench_, PASTE2(__LINE__, n))(STRINGIZE(n), n, priority_level); +// BENCHMARK(foo); expands to: benchmark::BenchRunner bench_runner_foo{"foo", foo}; +#define BENCHMARK(n) \ + benchmark::BenchRunner PASTE2(bench_runner_, n) { STRINGIZE(n), n } #endif // BITCOIN_BENCH_BENCH_H diff --git a/depend/bitcoin/src/bench/bench_bitcoin.cpp b/depend/bitcoin/src/bench/bench_bitcoin.cpp index 841d6258..987523a1 100644 --- a/depend/bitcoin/src/bench/bench_bitcoin.cpp +++ b/depend/bitcoin/src/bench/bench_bitcoin.cpp @@ -18,12 +18,8 @@ #include #include -using util::SplitString; - static const char* DEFAULT_BENCH_FILTER = ".*"; static constexpr int64_t DEFAULT_MIN_TIME_MS{10}; -/** Priority level default value, run "all" priority levels */ -static const std::string DEFAULT_PRIORITY{"all"}; static void SetupBenchArgs(ArgsManager& argsman) { @@ -37,8 +33,6 @@ static void SetupBenchArgs(ArgsManager& argsman) argsman.AddArg("-output-csv=", "Generate CSV file with the most important benchmark results", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); argsman.AddArg("-output-json=", "Generate JSON file with all benchmark results", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); argsman.AddArg("-sanity-check", "Run benchmarks for only one iteration with no output", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); - argsman.AddArg("-priority-level=", strprintf("Run benchmarks of one or multiple priority level(s) (%s), default: '%s'", - benchmark::ListPriorities(), DEFAULT_PRIORITY), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); } // parses a comma separated list like "10,20,30,50" @@ -54,14 +48,6 @@ static std::vector parseAsymptote(const std::string& str) { return numbers; } -static uint8_t parsePriorityLevel(const std::string& str) { - uint8_t levels{0}; - for (const auto& level: SplitString(str, ',')) { - levels |= benchmark::StringToPriority(level); - } - return levels; -} - static std::vector parseTestSetupArgs(const ArgsManager& argsman) { // Parses unit test framework arguments supported by the benchmark framework. @@ -144,7 +130,6 @@ int main(int argc, char** argv) args.output_json = argsman.GetPathArg("-output-json"); args.regex_filter = argsman.GetArg("-filter", DEFAULT_BENCH_FILTER); args.sanity_check = argsman.GetBoolArg("-sanity-check", false); - args.priority = parsePriorityLevel(argsman.GetArg("-priority-level", DEFAULT_PRIORITY)); args.setup_args = parseTestSetupArgs(argsman); benchmark::BenchRunner::RunAll(args); diff --git a/depend/bitcoin/src/bench/bip324_ecdh.cpp b/depend/bitcoin/src/bench/bip324_ecdh.cpp index b94c2bd2..65deb8b7 100644 --- a/depend/bitcoin/src/bench/bip324_ecdh.cpp +++ b/depend/bitcoin/src/bench/bip324_ecdh.cpp @@ -46,4 +46,4 @@ static void BIP324_ECDH(benchmark::Bench& bench) }); } -BENCHMARK(BIP324_ECDH, benchmark::PriorityLevel::HIGH); +BENCHMARK(BIP324_ECDH); diff --git a/depend/bitcoin/src/bench/block_assemble.cpp b/depend/bitcoin/src/bench/block_assemble.cpp index 4214d635..297465be 100644 --- a/depend/bitcoin/src/bench/block_assemble.cpp +++ b/depend/bitcoin/src/bench/block_assemble.cpp @@ -69,5 +69,5 @@ static void BlockAssemblerAddPackageTxns(benchmark::Bench& bench) }); } -BENCHMARK(AssembleBlock, benchmark::PriorityLevel::HIGH); -BENCHMARK(BlockAssemblerAddPackageTxns, benchmark::PriorityLevel::LOW); +BENCHMARK(AssembleBlock); +BENCHMARK(BlockAssemblerAddPackageTxns); diff --git a/depend/bitcoin/src/bench/blockencodings.cpp b/depend/bitcoin/src/bench/blockencodings.cpp index f12d22fa..3f6be56b 100644 --- a/depend/bitcoin/src/bench/blockencodings.cpp +++ b/depend/bitcoin/src/bench/blockencodings.cpp @@ -126,6 +126,6 @@ static void BlockEncodingLargeExtra(benchmark::Bench& bench) BlockEncodingBench(bench, 50000, 5000); } -BENCHMARK(BlockEncodingNoExtra, benchmark::PriorityLevel::HIGH); -BENCHMARK(BlockEncodingStdExtra, benchmark::PriorityLevel::HIGH); -BENCHMARK(BlockEncodingLargeExtra, benchmark::PriorityLevel::HIGH); +BENCHMARK(BlockEncodingNoExtra); +BENCHMARK(BlockEncodingStdExtra); +BENCHMARK(BlockEncodingLargeExtra); diff --git a/depend/bitcoin/src/bench/ccoins_caching.cpp b/depend/bitcoin/src/bench/ccoins_caching.cpp index 26d15fc2..2b7315f4 100644 --- a/depend/bitcoin/src/bench/ccoins_caching.cpp +++ b/depend/bitcoin/src/bench/ccoins_caching.cpp @@ -54,4 +54,4 @@ static void CCoinsCaching(benchmark::Bench& bench) }); } -BENCHMARK(CCoinsCaching, benchmark::PriorityLevel::HIGH); +BENCHMARK(CCoinsCaching); diff --git a/depend/bitcoin/src/bench/chacha20.cpp b/depend/bitcoin/src/bench/chacha20.cpp index cc029b1b..37165177 100644 --- a/depend/bitcoin/src/bench/chacha20.cpp +++ b/depend/bitcoin/src/bench/chacha20.cpp @@ -71,9 +71,9 @@ static void FSCHACHA20POLY1305_1MB(benchmark::Bench& bench) FSCHACHA20POLY1305(bench, BUFFER_SIZE_LARGE); } -BENCHMARK(CHACHA20_64BYTES, benchmark::PriorityLevel::HIGH); -BENCHMARK(CHACHA20_256BYTES, benchmark::PriorityLevel::HIGH); -BENCHMARK(CHACHA20_1MB, benchmark::PriorityLevel::HIGH); -BENCHMARK(FSCHACHA20POLY1305_64BYTES, benchmark::PriorityLevel::HIGH); -BENCHMARK(FSCHACHA20POLY1305_256BYTES, benchmark::PriorityLevel::HIGH); -BENCHMARK(FSCHACHA20POLY1305_1MB, benchmark::PriorityLevel::HIGH); +BENCHMARK(CHACHA20_64BYTES); +BENCHMARK(CHACHA20_256BYTES); +BENCHMARK(CHACHA20_1MB); +BENCHMARK(FSCHACHA20POLY1305_64BYTES); +BENCHMARK(FSCHACHA20POLY1305_256BYTES); +BENCHMARK(FSCHACHA20POLY1305_1MB); diff --git a/depend/bitcoin/src/bench/checkblock.cpp b/depend/bitcoin/src/bench/checkblock.cpp index acf29767..765b8b0d 100644 --- a/depend/bitcoin/src/bench/checkblock.cpp +++ b/depend/bitcoin/src/bench/checkblock.cpp @@ -60,5 +60,5 @@ static void DeserializeAndCheckBlockTest(benchmark::Bench& bench) }); } -BENCHMARK(DeserializeBlockTest, benchmark::PriorityLevel::HIGH); -BENCHMARK(DeserializeAndCheckBlockTest, benchmark::PriorityLevel::HIGH); +BENCHMARK(DeserializeBlockTest); +BENCHMARK(DeserializeAndCheckBlockTest); diff --git a/depend/bitcoin/src/bench/checkblockindex.cpp b/depend/bitcoin/src/bench/checkblockindex.cpp index a5c152b3..78e70a8d 100644 --- a/depend/bitcoin/src/bench/checkblockindex.cpp +++ b/depend/bitcoin/src/bench/checkblockindex.cpp @@ -19,4 +19,4 @@ static void CheckBlockIndex(benchmark::Bench& bench) } -BENCHMARK(CheckBlockIndex, benchmark::PriorityLevel::HIGH); +BENCHMARK(CheckBlockIndex); diff --git a/depend/bitcoin/src/bench/checkqueue.cpp b/depend/bitcoin/src/bench/checkqueue.cpp index 2aa715cb..2c9126dd 100644 --- a/depend/bitcoin/src/bench/checkqueue.cpp +++ b/depend/bitcoin/src/bench/checkqueue.cpp @@ -65,4 +65,4 @@ static void CCheckQueueSpeedPrevectorJob(benchmark::Bench& bench) control.Complete(); }); } -BENCHMARK(CCheckQueueSpeedPrevectorJob, benchmark::PriorityLevel::HIGH); +BENCHMARK(CCheckQueueSpeedPrevectorJob); diff --git a/depend/bitcoin/src/bench/cluster_linearize.cpp b/depend/bitcoin/src/bench/cluster_linearize.cpp index a856d247..88f8bf28 100644 --- a/depend/bitcoin/src/bench/cluster_linearize.cpp +++ b/depend/bitcoin/src/bench/cluster_linearize.cpp @@ -150,12 +150,12 @@ static void LinearizeOptimallyPerCost(benchmark::Bench& bench) BenchLinearizeOptimallyPerCost(bench, "LinearizeOptimallySyntheticPerCost", CLUSTERS_SYNTHETIC); } -BENCHMARK(PostLinearize16TxWorstCase, benchmark::PriorityLevel::HIGH); -BENCHMARK(PostLinearize32TxWorstCase, benchmark::PriorityLevel::HIGH); -BENCHMARK(PostLinearize48TxWorstCase, benchmark::PriorityLevel::HIGH); -BENCHMARK(PostLinearize64TxWorstCase, benchmark::PriorityLevel::HIGH); -BENCHMARK(PostLinearize75TxWorstCase, benchmark::PriorityLevel::HIGH); -BENCHMARK(PostLinearize99TxWorstCase, benchmark::PriorityLevel::HIGH); - -BENCHMARK(LinearizeOptimallyTotal, benchmark::PriorityLevel::HIGH); -BENCHMARK(LinearizeOptimallyPerCost, benchmark::PriorityLevel::HIGH); +BENCHMARK(PostLinearize16TxWorstCase); +BENCHMARK(PostLinearize32TxWorstCase); +BENCHMARK(PostLinearize48TxWorstCase); +BENCHMARK(PostLinearize64TxWorstCase); +BENCHMARK(PostLinearize75TxWorstCase); +BENCHMARK(PostLinearize99TxWorstCase); + +BENCHMARK(LinearizeOptimallyTotal); +BENCHMARK(LinearizeOptimallyPerCost); diff --git a/depend/bitcoin/src/bench/coin_selection.cpp b/depend/bitcoin/src/bench/coin_selection.cpp index 41d01dfc..72b3d70e 100644 --- a/depend/bitcoin/src/bench/coin_selection.cpp +++ b/depend/bitcoin/src/bench/coin_selection.cpp @@ -130,12 +130,12 @@ static void BnBExhaustion(benchmark::Bench& bench) bench.run([&] { // Benchmark CAmount target = make_hard_case(17, utxo_pool); - [[maybe_unused]] auto _{SelectCoinsBnB(utxo_pool, target, /*cost_of_change=*/0, MAX_STANDARD_TX_WEIGHT)}; // Should exhaust + (void)SelectCoinsBnB(utxo_pool, target, /*cost_of_change=*/0, MAX_STANDARD_TX_WEIGHT); // Should exhaust // Cleanup utxo_pool.clear(); }); } -BENCHMARK(CoinSelection, benchmark::PriorityLevel::HIGH); -BENCHMARK(BnBExhaustion, benchmark::PriorityLevel::HIGH); +BENCHMARK(CoinSelection); +BENCHMARK(BnBExhaustion); diff --git a/depend/bitcoin/src/bench/connectblock.cpp b/depend/bitcoin/src/bench/connectblock.cpp index cc972966..434bcdcb 100644 --- a/depend/bitcoin/src/bench/connectblock.cpp +++ b/depend/bitcoin/src/bench/connectblock.cpp @@ -126,6 +126,6 @@ static void ConnectBlockAllEcdsa(benchmark::Bench& bench) BenchmarkConnectBlock(bench, keys, outputs, *test_setup); } -BENCHMARK(ConnectBlockAllSchnorr, benchmark::PriorityLevel::HIGH); -BENCHMARK(ConnectBlockMixedEcdsaSchnorr, benchmark::PriorityLevel::HIGH); -BENCHMARK(ConnectBlockAllEcdsa, benchmark::PriorityLevel::HIGH); +BENCHMARK(ConnectBlockAllSchnorr); +BENCHMARK(ConnectBlockMixedEcdsaSchnorr); +BENCHMARK(ConnectBlockAllEcdsa); diff --git a/depend/bitcoin/src/bench/crypto_hash.cpp b/depend/bitcoin/src/bench/crypto_hash.cpp index 0fd7245b..666ff3c0 100644 --- a/depend/bitcoin/src/bench/crypto_hash.cpp +++ b/depend/bitcoin/src/bench/crypto_hash.cpp @@ -260,27 +260,27 @@ static void MuHashFinalize(benchmark::Bench& bench) }); } -BENCHMARK(BenchRIPEMD160, benchmark::PriorityLevel::HIGH); -BENCHMARK(SHA1, benchmark::PriorityLevel::HIGH); -BENCHMARK(SHA256_STANDARD, benchmark::PriorityLevel::HIGH); -BENCHMARK(SHA256_SSE4, benchmark::PriorityLevel::HIGH); -BENCHMARK(SHA256_AVX2, benchmark::PriorityLevel::HIGH); -BENCHMARK(SHA256_SHANI, benchmark::PriorityLevel::HIGH); -BENCHMARK(SHA512, benchmark::PriorityLevel::HIGH); -BENCHMARK(SHA3_256_1M, benchmark::PriorityLevel::HIGH); - -BENCHMARK(SHA256_32b_STANDARD, benchmark::PriorityLevel::HIGH); -BENCHMARK(SHA256_32b_SSE4, benchmark::PriorityLevel::HIGH); -BENCHMARK(SHA256_32b_AVX2, benchmark::PriorityLevel::HIGH); -BENCHMARK(SHA256_32b_SHANI, benchmark::PriorityLevel::HIGH); -BENCHMARK(SipHash_32b, benchmark::PriorityLevel::HIGH); -BENCHMARK(SHA256D64_1024_STANDARD, benchmark::PriorityLevel::HIGH); -BENCHMARK(SHA256D64_1024_SSE4, benchmark::PriorityLevel::HIGH); -BENCHMARK(SHA256D64_1024_AVX2, benchmark::PriorityLevel::HIGH); -BENCHMARK(SHA256D64_1024_SHANI, benchmark::PriorityLevel::HIGH); - -BENCHMARK(MuHash, benchmark::PriorityLevel::HIGH); -BENCHMARK(MuHashMul, benchmark::PriorityLevel::HIGH); -BENCHMARK(MuHashDiv, benchmark::PriorityLevel::HIGH); -BENCHMARK(MuHashPrecompute, benchmark::PriorityLevel::HIGH); -BENCHMARK(MuHashFinalize, benchmark::PriorityLevel::HIGH); +BENCHMARK(BenchRIPEMD160); +BENCHMARK(SHA1); +BENCHMARK(SHA256_STANDARD); +BENCHMARK(SHA256_SSE4); +BENCHMARK(SHA256_AVX2); +BENCHMARK(SHA256_SHANI); +BENCHMARK(SHA512); +BENCHMARK(SHA3_256_1M); + +BENCHMARK(SHA256_32b_STANDARD); +BENCHMARK(SHA256_32b_SSE4); +BENCHMARK(SHA256_32b_AVX2); +BENCHMARK(SHA256_32b_SHANI); +BENCHMARK(SipHash_32b); +BENCHMARK(SHA256D64_1024_STANDARD); +BENCHMARK(SHA256D64_1024_SSE4); +BENCHMARK(SHA256D64_1024_AVX2); +BENCHMARK(SHA256D64_1024_SHANI); + +BENCHMARK(MuHash); +BENCHMARK(MuHashMul); +BENCHMARK(MuHashDiv); +BENCHMARK(MuHashPrecompute); +BENCHMARK(MuHashFinalize); diff --git a/depend/bitcoin/src/bench/descriptors.cpp b/depend/bitcoin/src/bench/descriptors.cpp index 719e69e3..c375d312 100644 --- a/depend/bitcoin/src/bench/descriptors.cpp +++ b/depend/bitcoin/src/bench/descriptors.cpp @@ -35,4 +35,4 @@ static void ExpandDescriptor(benchmark::Bench& bench) }); } -BENCHMARK(ExpandDescriptor, benchmark::PriorityLevel::HIGH); +BENCHMARK(ExpandDescriptor); diff --git a/depend/bitcoin/src/bench/disconnected_transactions.cpp b/depend/bitcoin/src/bench/disconnected_transactions.cpp index e4c72aa5..4dd5de42 100644 --- a/depend/bitcoin/src/bench/disconnected_transactions.cpp +++ b/depend/bitcoin/src/bench/disconnected_transactions.cpp @@ -134,6 +134,6 @@ static void AddAndRemoveDisconnectedBlockTransactions10(benchmark::Bench& bench) }); } -BENCHMARK(AddAndRemoveDisconnectedBlockTransactionsAll, benchmark::PriorityLevel::HIGH); -BENCHMARK(AddAndRemoveDisconnectedBlockTransactions90, benchmark::PriorityLevel::HIGH); -BENCHMARK(AddAndRemoveDisconnectedBlockTransactions10, benchmark::PriorityLevel::HIGH); +BENCHMARK(AddAndRemoveDisconnectedBlockTransactionsAll); +BENCHMARK(AddAndRemoveDisconnectedBlockTransactions90); +BENCHMARK(AddAndRemoveDisconnectedBlockTransactions10); diff --git a/depend/bitcoin/src/bench/duplicate_inputs.cpp b/depend/bitcoin/src/bench/duplicate_inputs.cpp index 9bd7551d..5b1ca5f5 100644 --- a/depend/bitcoin/src/bench/duplicate_inputs.cpp +++ b/depend/bitcoin/src/bench/duplicate_inputs.cpp @@ -58,7 +58,7 @@ static void DuplicateInputs(benchmark::Bench& bench) naughtyTx.vout[0].nValue = 0; naughtyTx.vout[0].scriptPubKey = SCRIPT_PUB; - uint64_t n_inputs = (((MAX_BLOCK_SERIALIZED_SIZE / WITNESS_SCALE_FACTOR) - (CTransaction(coinbaseTx).GetTotalSize() + CTransaction(naughtyTx).GetTotalSize())) / 41) - 100; + uint64_t n_inputs = (((MAX_BLOCK_SERIALIZED_SIZE / WITNESS_SCALE_FACTOR) - (CTransaction(coinbaseTx).ComputeTotalSize() + CTransaction(naughtyTx).ComputeTotalSize())) / 41) - 100; for (uint64_t x = 0; x < (n_inputs - 1); ++x) { naughtyTx.vin.emplace_back(Txid::FromUint256(GetRandHash()), 0, CScript(), 0); } @@ -76,4 +76,4 @@ static void DuplicateInputs(benchmark::Bench& bench) }); } -BENCHMARK(DuplicateInputs, benchmark::PriorityLevel::HIGH); +BENCHMARK(DuplicateInputs); diff --git a/depend/bitcoin/src/bench/ellswift.cpp b/depend/bitcoin/src/bench/ellswift.cpp index 21868fb8..2daf1a9e 100644 --- a/depend/bitcoin/src/bench/ellswift.cpp +++ b/depend/bitcoin/src/bench/ellswift.cpp @@ -29,4 +29,4 @@ static void EllSwiftCreate(benchmark::Bench& bench) }); } -BENCHMARK(EllSwiftCreate, benchmark::PriorityLevel::HIGH); +BENCHMARK(EllSwiftCreate); diff --git a/depend/bitcoin/src/bench/examples.cpp b/depend/bitcoin/src/bench/examples.cpp index 0769b80d..07c0eabd 100644 --- a/depend/bitcoin/src/bench/examples.cpp +++ b/depend/bitcoin/src/bench/examples.cpp @@ -18,4 +18,4 @@ static void Trig(benchmark::Bench& bench) }); } -BENCHMARK(Trig, benchmark::PriorityLevel::HIGH); +BENCHMARK(Trig); diff --git a/depend/bitcoin/src/bench/gcs_filter.cpp b/depend/bitcoin/src/bench/gcs_filter.cpp index d66402da..ea48592a 100644 --- a/depend/bitcoin/src/bench/gcs_filter.cpp +++ b/depend/bitcoin/src/bench/gcs_filter.cpp @@ -86,8 +86,8 @@ static void GCSFilterMatch(benchmark::Bench& bench) filter.Match(GCSFilter::Element()); }); } -BENCHMARK(GCSBlockFilterGetHash, benchmark::PriorityLevel::HIGH); -BENCHMARK(GCSFilterConstruct, benchmark::PriorityLevel::HIGH); -BENCHMARK(GCSFilterDecode, benchmark::PriorityLevel::HIGH); -BENCHMARK(GCSFilterDecodeSkipCheck, benchmark::PriorityLevel::HIGH); -BENCHMARK(GCSFilterMatch, benchmark::PriorityLevel::HIGH); +BENCHMARK(GCSBlockFilterGetHash); +BENCHMARK(GCSFilterConstruct); +BENCHMARK(GCSFilterDecode); +BENCHMARK(GCSFilterDecodeSkipCheck); +BENCHMARK(GCSFilterMatch); diff --git a/depend/bitcoin/src/bench/hashpadding.cpp b/depend/bitcoin/src/bench/hashpadding.cpp index 74047a0c..4825c5f6 100644 --- a/depend/bitcoin/src/bench/hashpadding.cpp +++ b/depend/bitcoin/src/bench/hashpadding.cpp @@ -26,7 +26,7 @@ static void PrePadded(benchmark::Bench& bench) }); } -BENCHMARK(PrePadded, benchmark::PriorityLevel::HIGH); +BENCHMARK(PrePadded); static void RegularPadded(benchmark::Bench& bench) { @@ -44,4 +44,4 @@ static void RegularPadded(benchmark::Bench& bench) }); } -BENCHMARK(RegularPadded, benchmark::PriorityLevel::HIGH); +BENCHMARK(RegularPadded); diff --git a/depend/bitcoin/src/bench/index_blockfilter.cpp b/depend/bitcoin/src/bench/index_blockfilter.cpp index eac09688..ea40b132 100644 --- a/depend/bitcoin/src/bench/index_blockfilter.cpp +++ b/depend/bitcoin/src/bench/index_blockfilter.cpp @@ -56,4 +56,4 @@ static void BlockFilterIndexSync(benchmark::Bench& bench) }); } -BENCHMARK(BlockFilterIndexSync, benchmark::PriorityLevel::HIGH); +BENCHMARK(BlockFilterIndexSync); diff --git a/depend/bitcoin/src/bench/load_external.cpp b/depend/bitcoin/src/bench/load_external.cpp index 18f21be4..3350d16a 100644 --- a/depend/bitcoin/src/bench/load_external.cpp +++ b/depend/bitcoin/src/bench/load_external.cpp @@ -71,4 +71,4 @@ static void LoadExternalBlockFile(benchmark::Bench& bench) fs::remove(blkfile); } -BENCHMARK(LoadExternalBlockFile, benchmark::PriorityLevel::HIGH); +BENCHMARK(LoadExternalBlockFile); diff --git a/depend/bitcoin/src/bench/lockedpool.cpp b/depend/bitcoin/src/bench/lockedpool.cpp index 5f8834f5..27fd609a 100644 --- a/depend/bitcoin/src/bench/lockedpool.cpp +++ b/depend/bitcoin/src/bench/lockedpool.cpp @@ -38,4 +38,4 @@ static void BenchLockedPool(benchmark::Bench& bench) addr.clear(); } -BENCHMARK(BenchLockedPool, benchmark::PriorityLevel::HIGH); +BENCHMARK(BenchLockedPool); diff --git a/depend/bitcoin/src/bench/logging.cpp b/depend/bitcoin/src/bench/logging.cpp index 487ddcf3..498469dc 100644 --- a/depend/bitcoin/src/bench/logging.cpp +++ b/depend/bitcoin/src/bench/logging.cpp @@ -57,8 +57,8 @@ static void LogWithoutWriteToFile(benchmark::Bench& bench) }); } -BENCHMARK(LogWithDebug, benchmark::PriorityLevel::HIGH); -BENCHMARK(LogWithoutDebug, benchmark::PriorityLevel::HIGH); -BENCHMARK(LogWithThreadNames, benchmark::PriorityLevel::HIGH); -BENCHMARK(LogWithoutThreadNames, benchmark::PriorityLevel::HIGH); -BENCHMARK(LogWithoutWriteToFile, benchmark::PriorityLevel::HIGH); +BENCHMARK(LogWithDebug); +BENCHMARK(LogWithoutDebug); +BENCHMARK(LogWithThreadNames); +BENCHMARK(LogWithoutThreadNames); +BENCHMARK(LogWithoutWriteToFile); diff --git a/depend/bitcoin/src/bench/mempool_ephemeral_spends.cpp b/depend/bitcoin/src/bench/mempool_ephemeral_spends.cpp index a572d945..2f89f0da 100644 --- a/depend/bitcoin/src/bench/mempool_ephemeral_spends.cpp +++ b/depend/bitcoin/src/bench/mempool_ephemeral_spends.cpp @@ -84,4 +84,4 @@ static void MempoolCheckEphemeralSpends(benchmark::Bench& bench) }); } -BENCHMARK(MempoolCheckEphemeralSpends, benchmark::PriorityLevel::HIGH); +BENCHMARK(MempoolCheckEphemeralSpends); diff --git a/depend/bitcoin/src/bench/mempool_eviction.cpp b/depend/bitcoin/src/bench/mempool_eviction.cpp index 7e64592d..ad3ab08a 100644 --- a/depend/bitcoin/src/bench/mempool_eviction.cpp +++ b/depend/bitcoin/src/bench/mempool_eviction.cpp @@ -144,4 +144,4 @@ static void MempoolEviction(benchmark::Bench& bench) }); } -BENCHMARK(MempoolEviction, benchmark::PriorityLevel::HIGH); +BENCHMARK(MempoolEviction); diff --git a/depend/bitcoin/src/bench/mempool_stress.cpp b/depend/bitcoin/src/bench/mempool_stress.cpp index 3e83b2c2..768913ac 100644 --- a/depend/bitcoin/src/bench/mempool_stress.cpp +++ b/depend/bitcoin/src/bench/mempool_stress.cpp @@ -140,7 +140,7 @@ static void ComplexMemPool(benchmark::Bench& bench) // Add all transactions to the mempool. // Also store the first 10 transactions from each cluster as the - // transactions we'll "mine" in the the benchmark. + // transactions we'll "mine" in the benchmark. int tx_count = 0; for (auto& tx : transactions) { if (tx_count < 10) { @@ -208,7 +208,7 @@ static void MempoolCheck(benchmark::Bench& bench) }); } -BENCHMARK(MemPoolAncestorsDescendants, benchmark::PriorityLevel::HIGH); -BENCHMARK(MemPoolAddTransactions, benchmark::PriorityLevel::HIGH); -BENCHMARK(ComplexMemPool, benchmark::PriorityLevel::HIGH); -BENCHMARK(MempoolCheck, benchmark::PriorityLevel::HIGH); +BENCHMARK(MemPoolAncestorsDescendants); +BENCHMARK(MemPoolAddTransactions); +BENCHMARK(ComplexMemPool); +BENCHMARK(MempoolCheck); diff --git a/depend/bitcoin/src/bench/merkle_root.cpp b/depend/bitcoin/src/bench/merkle_root.cpp index f9c933ec..17f7fa86 100644 --- a/depend/bitcoin/src/bench/merkle_root.cpp +++ b/depend/bitcoin/src/bench/merkle_root.cpp @@ -7,21 +7,33 @@ #include #include +#include #include static void MerkleRoot(benchmark::Bench& bench) { - FastRandomContext rng(true); - std::vector leaves; - leaves.resize(9001); - for (auto& item : leaves) { + FastRandomContext rng{/*fDeterministic=*/true}; + + std::vector hashes{}; + hashes.resize(9001); + for (auto& item : hashes) { item = rng.rand256(); } - bench.batch(leaves.size()).unit("leaf").run([&] { - bool mutation = false; - uint256 hash = ComputeMerkleRoot(std::vector(leaves), &mutation); - leaves[mutation] = hash; - }); + + constexpr uint256 expected_root{"d8d4dfd014a533bc3941b8663fa6e7f3a8707af124f713164d75b0c3179ecb08"}; + for (bool mutate : {false, true}) { + bench.name(mutate ? "MerkleRootWithMutation" : "MerkleRoot").batch(hashes.size()).unit("leaf").run([&] { + std::vector leaves; + leaves.reserve((hashes.size() + 1) & ~1ULL); // capacity rounded up to even + for (const auto& hash : hashes) { + leaves.push_back(hash); + } + + bool mutated{false}; + const uint256 root{ComputeMerkleRoot(std::move(leaves), mutate ? &mutated : nullptr)}; + assert(root == expected_root); + }); + } } -BENCHMARK(MerkleRoot, benchmark::PriorityLevel::HIGH); +BENCHMARK(MerkleRoot); diff --git a/depend/bitcoin/src/bench/obfuscation.cpp b/depend/bitcoin/src/bench/obfuscation.cpp index 178be56a..c7392e03 100644 --- a/depend/bitcoin/src/bench/obfuscation.cpp +++ b/depend/bitcoin/src/bench/obfuscation.cpp @@ -22,4 +22,4 @@ static void ObfuscationBench(benchmark::Bench& bench) }); } -BENCHMARK(ObfuscationBench, benchmark::PriorityLevel::HIGH); +BENCHMARK(ObfuscationBench); diff --git a/depend/bitcoin/src/bench/parse_hex.cpp b/depend/bitcoin/src/bench/parse_hex.cpp index fa08f5d8..928176bd 100644 --- a/depend/bitcoin/src/bench/parse_hex.cpp +++ b/depend/bitcoin/src/bench/parse_hex.cpp @@ -34,4 +34,4 @@ static void HexParse(benchmark::Bench& bench) }); } -BENCHMARK(HexParse, benchmark::PriorityLevel::HIGH); +BENCHMARK(HexParse); diff --git a/depend/bitcoin/src/bench/peer_eviction.cpp b/depend/bitcoin/src/bench/peer_eviction.cpp index 43d819cc..2360fb49 100644 --- a/depend/bitcoin/src/bench/peer_eviction.cpp +++ b/depend/bitcoin/src/bench/peer_eviction.cpp @@ -140,15 +140,15 @@ static void EvictionProtection3Networks250Candidates(benchmark::Bench& bench) // - 250 candidates is the number of peers reported by operators of busy nodes // No disadvantaged networks, with 250 eviction candidates. -BENCHMARK(EvictionProtection0Networks250Candidates, benchmark::PriorityLevel::HIGH); +BENCHMARK(EvictionProtection0Networks250Candidates); // 1 disadvantaged network (Tor) with 250 eviction candidates. -BENCHMARK(EvictionProtection1Networks250Candidates, benchmark::PriorityLevel::HIGH); +BENCHMARK(EvictionProtection1Networks250Candidates); // 2 disadvantaged networks (I2P, Tor) with 250 eviction candidates. -BENCHMARK(EvictionProtection2Networks250Candidates, benchmark::PriorityLevel::HIGH); +BENCHMARK(EvictionProtection2Networks250Candidates); // 3 disadvantaged networks (I2P/localhost/Tor) with 50/100/250 eviction candidates. -BENCHMARK(EvictionProtection3Networks050Candidates, benchmark::PriorityLevel::HIGH); -BENCHMARK(EvictionProtection3Networks100Candidates, benchmark::PriorityLevel::HIGH); -BENCHMARK(EvictionProtection3Networks250Candidates, benchmark::PriorityLevel::HIGH); +BENCHMARK(EvictionProtection3Networks050Candidates); +BENCHMARK(EvictionProtection3Networks100Candidates); +BENCHMARK(EvictionProtection3Networks250Candidates); diff --git a/depend/bitcoin/src/bench/poly1305.cpp b/depend/bitcoin/src/bench/poly1305.cpp index eaa7857f..e782164a 100644 --- a/depend/bitcoin/src/bench/poly1305.cpp +++ b/depend/bitcoin/src/bench/poly1305.cpp @@ -41,6 +41,6 @@ static void POLY1305_1MB(benchmark::Bench& bench) POLY1305(bench, BUFFER_SIZE_LARGE); } -BENCHMARK(POLY1305_64BYTES, benchmark::PriorityLevel::HIGH); -BENCHMARK(POLY1305_256BYTES, benchmark::PriorityLevel::HIGH); -BENCHMARK(POLY1305_1MB, benchmark::PriorityLevel::HIGH); +BENCHMARK(POLY1305_64BYTES); +BENCHMARK(POLY1305_256BYTES); +BENCHMARK(POLY1305_1MB); diff --git a/depend/bitcoin/src/bench/pool.cpp b/depend/bitcoin/src/bench/pool.cpp index b31046cf..cf4ba132 100644 --- a/depend/bitcoin/src/bench/pool.cpp +++ b/depend/bitcoin/src/bench/pool.cpp @@ -49,5 +49,5 @@ static void PoolAllocator_StdUnorderedMapWithPoolResource(benchmark::Bench& benc BenchFillClearMap(bench, map); } -BENCHMARK(PoolAllocator_StdUnorderedMap, benchmark::PriorityLevel::HIGH); -BENCHMARK(PoolAllocator_StdUnorderedMapWithPoolResource, benchmark::PriorityLevel::HIGH); +BENCHMARK(PoolAllocator_StdUnorderedMap); +BENCHMARK(PoolAllocator_StdUnorderedMapWithPoolResource); diff --git a/depend/bitcoin/src/bench/prevector.cpp b/depend/bitcoin/src/bench/prevector.cpp index 85ef196e..8d386ec2 100644 --- a/depend/bitcoin/src/bench/prevector.cpp +++ b/depend/bitcoin/src/bench/prevector.cpp @@ -116,12 +116,12 @@ static void PrevectorFillVectorIndirect(benchmark::Bench& bench) { \ Prevector##name(bench); \ } \ - BENCHMARK(Prevector##name##Nontrivial, benchmark::PriorityLevel::HIGH); \ + BENCHMARK(Prevector##name##Nontrivial); \ static void Prevector##name##Trivial(benchmark::Bench& bench) \ { \ Prevector##name(bench); \ } \ - BENCHMARK(Prevector##name##Trivial, benchmark::PriorityLevel::HIGH); + BENCHMARK(Prevector##name##Trivial); PREVECTOR_TEST(Clear) PREVECTOR_TEST(Destructor) diff --git a/depend/bitcoin/src/bench/random.cpp b/depend/bitcoin/src/bench/random.cpp index c2aa6685..c3ac72ea 100644 --- a/depend/bitcoin/src/bench/random.cpp +++ b/depend/bitcoin/src/bench/random.cpp @@ -86,20 +86,20 @@ void InsecureRandom_stdshuffle100(benchmark::Bench& bench) { BenchRandom_stdshuf } // namespace -BENCHMARK(FastRandom_rand64, benchmark::PriorityLevel::HIGH); -BENCHMARK(FastRandom_rand32, benchmark::PriorityLevel::HIGH); -BENCHMARK(FastRandom_randbool, benchmark::PriorityLevel::HIGH); -BENCHMARK(FastRandom_randbits, benchmark::PriorityLevel::HIGH); -BENCHMARK(FastRandom_randrange100, benchmark::PriorityLevel::HIGH); -BENCHMARK(FastRandom_randrange1000, benchmark::PriorityLevel::HIGH); -BENCHMARK(FastRandom_randrange1000000, benchmark::PriorityLevel::HIGH); -BENCHMARK(FastRandom_stdshuffle100, benchmark::PriorityLevel::HIGH); +BENCHMARK(FastRandom_rand64); +BENCHMARK(FastRandom_rand32); +BENCHMARK(FastRandom_randbool); +BENCHMARK(FastRandom_randbits); +BENCHMARK(FastRandom_randrange100); +BENCHMARK(FastRandom_randrange1000); +BENCHMARK(FastRandom_randrange1000000); +BENCHMARK(FastRandom_stdshuffle100); -BENCHMARK(InsecureRandom_rand64, benchmark::PriorityLevel::HIGH); -BENCHMARK(InsecureRandom_rand32, benchmark::PriorityLevel::HIGH); -BENCHMARK(InsecureRandom_randbool, benchmark::PriorityLevel::HIGH); -BENCHMARK(InsecureRandom_randbits, benchmark::PriorityLevel::HIGH); -BENCHMARK(InsecureRandom_randrange100, benchmark::PriorityLevel::HIGH); -BENCHMARK(InsecureRandom_randrange1000, benchmark::PriorityLevel::HIGH); -BENCHMARK(InsecureRandom_randrange1000000, benchmark::PriorityLevel::HIGH); -BENCHMARK(InsecureRandom_stdshuffle100, benchmark::PriorityLevel::HIGH); +BENCHMARK(InsecureRandom_rand64); +BENCHMARK(InsecureRandom_rand32); +BENCHMARK(InsecureRandom_randbool); +BENCHMARK(InsecureRandom_randbits); +BENCHMARK(InsecureRandom_randrange100); +BENCHMARK(InsecureRandom_randrange1000); +BENCHMARK(InsecureRandom_randrange1000000); +BENCHMARK(InsecureRandom_stdshuffle100); diff --git a/depend/bitcoin/src/bench/readwriteblock.cpp b/depend/bitcoin/src/bench/readwriteblock.cpp index d756789b..e1372a26 100644 --- a/depend/bitcoin/src/bench/readwriteblock.cpp +++ b/depend/bitcoin/src/bench/readwriteblock.cpp @@ -63,6 +63,6 @@ static void ReadRawBlockBench(benchmark::Bench& bench) }); } -BENCHMARK(WriteBlockBench, benchmark::PriorityLevel::HIGH); -BENCHMARK(ReadBlockBench, benchmark::PriorityLevel::HIGH); -BENCHMARK(ReadRawBlockBench, benchmark::PriorityLevel::HIGH); +BENCHMARK(WriteBlockBench); +BENCHMARK(ReadBlockBench); +BENCHMARK(ReadRawBlockBench); diff --git a/depend/bitcoin/src/bench/rollingbloom.cpp b/depend/bitcoin/src/bench/rollingbloom.cpp index a9b7806e..8331eb6a 100644 --- a/depend/bitcoin/src/bench/rollingbloom.cpp +++ b/depend/bitcoin/src/bench/rollingbloom.cpp @@ -34,5 +34,5 @@ static void RollingBloomReset(benchmark::Bench& bench) }); } -BENCHMARK(RollingBloom, benchmark::PriorityLevel::HIGH); -BENCHMARK(RollingBloomReset, benchmark::PriorityLevel::HIGH); +BENCHMARK(RollingBloom); +BENCHMARK(RollingBloomReset); diff --git a/depend/bitcoin/src/bench/rpc_blockchain.cpp b/depend/bitcoin/src/bench/rpc_blockchain.cpp index 0dc217ea..0e89ac78 100644 --- a/depend/bitcoin/src/bench/rpc_blockchain.cpp +++ b/depend/bitcoin/src/bench/rpc_blockchain.cpp @@ -70,9 +70,9 @@ static void BlockToJsonVerbosity3(benchmark::Bench& bench) BlockToJson(bench, TxVerbosity::SHOW_DETAILS_AND_PREVOUT); } -BENCHMARK(BlockToJsonVerbosity1, benchmark::PriorityLevel::HIGH); -BENCHMARK(BlockToJsonVerbosity2, benchmark::PriorityLevel::HIGH); -BENCHMARK(BlockToJsonVerbosity3, benchmark::PriorityLevel::HIGH); +BENCHMARK(BlockToJsonVerbosity1); +BENCHMARK(BlockToJsonVerbosity2); +BENCHMARK(BlockToJsonVerbosity3); static void BlockToJsonVerboseWrite(benchmark::Bench& bench) { @@ -85,4 +85,4 @@ static void BlockToJsonVerboseWrite(benchmark::Bench& bench) }); } -BENCHMARK(BlockToJsonVerboseWrite, benchmark::PriorityLevel::HIGH); +BENCHMARK(BlockToJsonVerboseWrite); diff --git a/depend/bitcoin/src/bench/rpc_mempool.cpp b/depend/bitcoin/src/bench/rpc_mempool.cpp index c710c2c8..b27a7e72 100644 --- a/depend/bitcoin/src/bench/rpc_mempool.cpp +++ b/depend/bitcoin/src/bench/rpc_mempool.cpp @@ -48,4 +48,4 @@ static void RpcMempool(benchmark::Bench& bench) }); } -BENCHMARK(RpcMempool, benchmark::PriorityLevel::HIGH); +BENCHMARK(RpcMempool); diff --git a/depend/bitcoin/src/bench/sign_transaction.cpp b/depend/bitcoin/src/bench/sign_transaction.cpp index f4294389..96af48c5 100644 --- a/depend/bitcoin/src/bench/sign_transaction.cpp +++ b/depend/bitcoin/src/bench/sign_transaction.cpp @@ -100,7 +100,7 @@ static void SignSchnorrWithNullMerkleRoot(benchmark::Bench& bench) SignSchnorrTapTweakBenchmark(bench, /*use_null_merkle_root=*/true); } -BENCHMARK(SignTransactionECDSA, benchmark::PriorityLevel::HIGH); -BENCHMARK(SignTransactionSchnorr, benchmark::PriorityLevel::HIGH); -BENCHMARK(SignSchnorrWithMerkleRoot, benchmark::PriorityLevel::HIGH); -BENCHMARK(SignSchnorrWithNullMerkleRoot, benchmark::PriorityLevel::HIGH); +BENCHMARK(SignTransactionECDSA); +BENCHMARK(SignTransactionSchnorr); +BENCHMARK(SignSchnorrWithMerkleRoot); +BENCHMARK(SignSchnorrWithNullMerkleRoot); diff --git a/depend/bitcoin/src/bench/streams_findbyte.cpp b/depend/bitcoin/src/bench/streams_findbyte.cpp index 9c52a72a..45e93d77 100644 --- a/depend/bitcoin/src/bench/streams_findbyte.cpp +++ b/depend/bitcoin/src/bench/streams_findbyte.cpp @@ -30,4 +30,4 @@ static void FindByte(benchmark::Bench& bench) assert(file.fclose() == 0); } -BENCHMARK(FindByte, benchmark::PriorityLevel::HIGH); +BENCHMARK(FindByte); diff --git a/depend/bitcoin/src/bench/strencodings.cpp b/depend/bitcoin/src/bench/strencodings.cpp index 38af7ad7..a0767b49 100644 --- a/depend/bitcoin/src/bench/strencodings.cpp +++ b/depend/bitcoin/src/bench/strencodings.cpp @@ -18,4 +18,4 @@ static void HexStrBench(benchmark::Bench& bench) }); } -BENCHMARK(HexStrBench, benchmark::PriorityLevel::HIGH); +BENCHMARK(HexStrBench); diff --git a/depend/bitcoin/src/bench/txgraph.cpp b/depend/bitcoin/src/bench/txgraph.cpp index 70824c2a..078f77b4 100644 --- a/depend/bitcoin/src/bench/txgraph.cpp +++ b/depend/bitcoin/src/bench/txgraph.cpp @@ -123,4 +123,4 @@ void BenchTxGraphTrim(benchmark::Bench& bench) static void TxGraphTrim(benchmark::Bench& bench) { BenchTxGraphTrim(bench); } -BENCHMARK(TxGraphTrim, benchmark::PriorityLevel::HIGH); +BENCHMARK(TxGraphTrim); diff --git a/depend/bitcoin/src/bench/txorphanage.cpp b/depend/bitcoin/src/bench/txorphanage.cpp index dd614fa3..1f94553b 100644 --- a/depend/bitcoin/src/bench/txorphanage.cpp +++ b/depend/bitcoin/src/bench/txorphanage.cpp @@ -262,7 +262,7 @@ static void OrphanageEraseForPeer(benchmark::Bench& bench) OrphanageEraseAll(bench, /*block_or_disconnect=*/false); } -BENCHMARK(OrphanageSinglePeerEviction, benchmark::PriorityLevel::LOW); -BENCHMARK(OrphanageMultiPeerEviction, benchmark::PriorityLevel::LOW); -BENCHMARK(OrphanageEraseForBlock, benchmark::PriorityLevel::LOW); -BENCHMARK(OrphanageEraseForPeer, benchmark::PriorityLevel::LOW); +BENCHMARK(OrphanageSinglePeerEviction); +BENCHMARK(OrphanageMultiPeerEviction); +BENCHMARK(OrphanageEraseForBlock); +BENCHMARK(OrphanageEraseForPeer); diff --git a/depend/bitcoin/src/bench/util_time.cpp b/depend/bitcoin/src/bench/util_time.cpp index a4f30516..bc3e3892 100644 --- a/depend/bitcoin/src/bench/util_time.cpp +++ b/depend/bitcoin/src/bench/util_time.cpp @@ -36,7 +36,7 @@ static void BenchTimeMillisSys(benchmark::Bench& bench) }); } -BENCHMARK(BenchTimeDeprecated, benchmark::PriorityLevel::HIGH); -BENCHMARK(BenchTimeMillis, benchmark::PriorityLevel::HIGH); -BENCHMARK(BenchTimeMillisSys, benchmark::PriorityLevel::HIGH); -BENCHMARK(BenchTimeMock, benchmark::PriorityLevel::HIGH); +BENCHMARK(BenchTimeDeprecated); +BENCHMARK(BenchTimeMillis); +BENCHMARK(BenchTimeMillisSys); +BENCHMARK(BenchTimeMock); diff --git a/depend/bitcoin/src/bench/verify_script.cpp b/depend/bitcoin/src/bench/verify_script.cpp index 1266f6dd..e740f86c 100644 --- a/depend/bitcoin/src/bench/verify_script.cpp +++ b/depend/bitcoin/src/bench/verify_script.cpp @@ -87,5 +87,5 @@ static void VerifyNestedIfScript(benchmark::Bench& bench) }); } -BENCHMARK(VerifyScriptBench, benchmark::PriorityLevel::HIGH); -BENCHMARK(VerifyNestedIfScript, benchmark::PriorityLevel::HIGH); +BENCHMARK(VerifyScriptBench); +BENCHMARK(VerifyNestedIfScript); diff --git a/depend/bitcoin/src/bench/wallet_balance.cpp b/depend/bitcoin/src/bench/wallet_balance.cpp index 5f3711ad..03774ef5 100644 --- a/depend/bitcoin/src/bench/wallet_balance.cpp +++ b/depend/bitcoin/src/bench/wallet_balance.cpp @@ -64,8 +64,8 @@ static void WalletBalanceClean(benchmark::Bench& bench) { WalletBalance(bench, / static void WalletBalanceMine(benchmark::Bench& bench) { WalletBalance(bench, /*set_dirty=*/false, /*add_mine=*/true); } static void WalletBalanceWatch(benchmark::Bench& bench) { WalletBalance(bench, /*set_dirty=*/false, /*add_mine=*/false); } -BENCHMARK(WalletBalanceDirty, benchmark::PriorityLevel::HIGH); -BENCHMARK(WalletBalanceClean, benchmark::PriorityLevel::HIGH); -BENCHMARK(WalletBalanceMine, benchmark::PriorityLevel::HIGH); -BENCHMARK(WalletBalanceWatch, benchmark::PriorityLevel::HIGH); +BENCHMARK(WalletBalanceDirty); +BENCHMARK(WalletBalanceClean); +BENCHMARK(WalletBalanceMine); +BENCHMARK(WalletBalanceWatch); } // namespace wallet diff --git a/depend/bitcoin/src/bench/wallet_create.cpp b/depend/bitcoin/src/bench/wallet_create.cpp index 9d3527e7..1c92bedd 100644 --- a/depend/bitcoin/src/bench/wallet_create.cpp +++ b/depend/bitcoin/src/bench/wallet_create.cpp @@ -60,7 +60,7 @@ static void WalletCreate(benchmark::Bench& bench, bool encrypted) static void WalletCreatePlain(benchmark::Bench& bench) { WalletCreate(bench, /*encrypted=*/false); } static void WalletCreateEncrypted(benchmark::Bench& bench) { WalletCreate(bench, /*encrypted=*/true); } -BENCHMARK(WalletCreatePlain, benchmark::PriorityLevel::LOW); -BENCHMARK(WalletCreateEncrypted, benchmark::PriorityLevel::LOW); +BENCHMARK(WalletCreatePlain); +BENCHMARK(WalletCreateEncrypted); } // namespace wallet diff --git a/depend/bitcoin/src/bench/wallet_create_tx.cpp b/depend/bitcoin/src/bench/wallet_create_tx.cpp index cd9ffd10..8ff1e39a 100644 --- a/depend/bitcoin/src/bench/wallet_create_tx.cpp +++ b/depend/bitcoin/src/bench/wallet_create_tx.cpp @@ -215,6 +215,6 @@ static void WalletCreateTxUsePresetInputsAndCoinSelection(benchmark::Bench& benc static void WalletAvailableCoins(benchmark::Bench& bench) { AvailableCoins(bench, {OutputType::BECH32M}); } -BENCHMARK(WalletCreateTxUseOnlyPresetInputs, benchmark::PriorityLevel::LOW) -BENCHMARK(WalletCreateTxUsePresetInputsAndCoinSelection, benchmark::PriorityLevel::LOW) -BENCHMARK(WalletAvailableCoins, benchmark::PriorityLevel::LOW); +BENCHMARK(WalletCreateTxUseOnlyPresetInputs); +BENCHMARK(WalletCreateTxUsePresetInputsAndCoinSelection); +BENCHMARK(WalletAvailableCoins); diff --git a/depend/bitcoin/src/bench/wallet_ismine.cpp b/depend/bitcoin/src/bench/wallet_ismine.cpp index aa0fd276..d26f893b 100644 --- a/depend/bitcoin/src/bench/wallet_ismine.cpp +++ b/depend/bitcoin/src/bench/wallet_ismine.cpp @@ -66,6 +66,6 @@ static void WalletIsMine(benchmark::Bench& bench, int num_combo = 0) static void WalletIsMineDescriptors(benchmark::Bench& bench) { WalletIsMine(bench); } static void WalletIsMineMigratedDescriptors(benchmark::Bench& bench) { WalletIsMine(bench, /*num_combo=*/2000); } -BENCHMARK(WalletIsMineDescriptors, benchmark::PriorityLevel::LOW); -BENCHMARK(WalletIsMineMigratedDescriptors, benchmark::PriorityLevel::LOW); +BENCHMARK(WalletIsMineDescriptors); +BENCHMARK(WalletIsMineMigratedDescriptors); } // namespace wallet diff --git a/depend/bitcoin/src/bench/wallet_loading.cpp b/depend/bitcoin/src/bench/wallet_loading.cpp index dffc76e1..f7c78806 100644 --- a/depend/bitcoin/src/bench/wallet_loading.cpp +++ b/depend/bitcoin/src/bench/wallet_loading.cpp @@ -64,5 +64,5 @@ static void WalletLoadingDescriptors(benchmark::Bench& bench) }); } -BENCHMARK(WalletLoadingDescriptors, benchmark::PriorityLevel::HIGH); +BENCHMARK(WalletLoadingDescriptors); } // namespace wallet diff --git a/depend/bitcoin/src/bench/wallet_migration.cpp b/depend/bitcoin/src/bench/wallet_migration.cpp index f38f2165..910ad1e9 100644 --- a/depend/bitcoin/src/bench/wallet_migration.cpp +++ b/depend/bitcoin/src/bench/wallet_migration.cpp @@ -74,6 +74,6 @@ static void WalletMigration(benchmark::Bench& bench) }); } -BENCHMARK(WalletMigration, benchmark::PriorityLevel::LOW); +BENCHMARK(WalletMigration); } // namespace wallet diff --git a/depend/bitcoin/src/bitcoin-chainstate.cpp b/depend/bitcoin/src/bitcoin-chainstate.cpp index 91c5639e..ae215c19 100644 --- a/depend/bitcoin/src/bitcoin-chainstate.cpp +++ b/depend/bitcoin/src/bitcoin-chainstate.cpp @@ -57,7 +57,7 @@ class TestValidationInterface : public ValidationInterface std::optional m_expected_valid_block = std::nullopt; - void BlockChecked(const Block block, const BlockValidationState state) override + void BlockChecked(Block block, BlockValidationStateView state) override { auto mode{state.GetValidationMode()}; switch (mode) { @@ -144,16 +144,18 @@ class TestKernelNotifications : public KernelNotifications int main(int argc, char* argv[]) { // SETUP: Argument parsing and handling - if (argc != 2) { + const bool has_regtest_flag{argc == 3 && std::string(argv[1]) == "-regtest"}; + if (argc < 2 || argc > 3 || (argc == 3 && !has_regtest_flag)) { std::cerr - << "Usage: " << argv[0] << " DATADIR" << std::endl + << "Usage: " << argv[0] << " [-regtest] DATADIR" << std::endl << "Display DATADIR information, and process hex-encoded blocks on standard input." << std::endl + << "Uses mainnet parameters by default, regtest with -regtest flag" << std::endl << std::endl << "IMPORTANT: THIS EXECUTABLE IS EXPERIMENTAL, FOR TESTING ONLY, AND EXPECTED TO" << std::endl << " BREAK IN FUTURE VERSIONS. DO NOT USE ON YOUR ACTUAL DATADIR." << std::endl; return 1; } - std::filesystem::path abs_datadir{std::filesystem::absolute(argv[1])}; + std::filesystem::path abs_datadir{std::filesystem::absolute(argv[argc-1])}; std::filesystem::create_directories(abs_datadir); btck_LoggingOptions logging_options = { @@ -169,7 +171,7 @@ int main(int argc, char* argv[]) Logger logger{std::make_unique()}; ContextOptions options{}; - ChainParams params{ChainType::MAINNET}; + ChainParams params{has_regtest_flag ? ChainType::REGTEST : ChainType::MAINNET}; options.SetChainParams(params); options.SetNotifications(std::make_shared()); diff --git a/depend/bitcoin/src/bitcoin-cli.cpp b/depend/bitcoin/src/bitcoin-cli.cpp index 88d0665e..724620aa 100644 --- a/depend/bitcoin/src/bitcoin-cli.cpp +++ b/depend/bitcoin/src/bitcoin-cli.cpp @@ -452,6 +452,7 @@ class NetinfoRequestHandler : public BaseRequestHandler if (conn_type == "block-relay-only") return "block"; if (conn_type == "manual" || conn_type == "feeler") return conn_type; if (conn_type == "addr-fetch") return "addr"; + if (conn_type == "private-broadcast") return "priv"; return ""; } std::string FormatServices(const UniValue& services) @@ -703,6 +704,7 @@ class NetinfoRequestHandler : public BaseRequestHandler " \"manual\" - peer we manually added using RPC addnode or the -addnode/-connect config options\n" " \"feeler\" - short-lived connection for testing addresses\n" " \"addr\" - address fetch; short-lived connection for requesting addresses\n" + " \"priv\" - private broadcast; short-lived connection for broadcasting our transactions\n" " net Network the peer connected through (\"ipv4\", \"ipv6\", \"onion\", \"i2p\", \"cjdns\", or \"npr\" (not publicly routable))\n" " serv Services offered by the peer\n" " \"n\" - NETWORK: peer can serve the full block chain\n" diff --git a/depend/bitcoin/src/blockencodings.cpp b/depend/bitcoin/src/blockencodings.cpp index 49900482..fd528309 100644 --- a/depend/bitcoin/src/blockencodings.cpp +++ b/depend/bitcoin/src/blockencodings.cpp @@ -192,40 +192,44 @@ ReadStatus PartiallyDownloadedBlock::FillBlock(CBlock& block, const std::vector< { if (header.IsNull()) return READ_STATUS_INVALID; - uint256 hash = header.GetHash(); block = header; block.vtx.resize(txn_available.size()); - unsigned int tx_missing_size = 0; size_t tx_missing_offset = 0; for (size_t i = 0; i < txn_available.size(); i++) { if (!txn_available[i]) { - if (vtx_missing.size() <= tx_missing_offset) + if (tx_missing_offset >= vtx_missing.size()) { return READ_STATUS_INVALID; + } block.vtx[i] = vtx_missing[tx_missing_offset++]; - tx_missing_size += block.vtx[i]->GetTotalSize(); - } else + } else { block.vtx[i] = std::move(txn_available[i]); + } } // Make sure we can't call FillBlock again. header.SetNull(); txn_available.clear(); - if (vtx_missing.size() != tx_missing_offset) + if (vtx_missing.size() != tx_missing_offset) { return READ_STATUS_INVALID; + } // Check for possible mutations early now that we have a seemingly good block IsBlockMutatedFn check_mutated{m_check_block_mutated_mock ? m_check_block_mutated_mock : IsBlockMutated}; - if (check_mutated(/*block=*/block, - /*check_witness_root=*/segwit_active)) { + if (check_mutated(/*block=*/block, /*check_witness_root=*/segwit_active)) { return READ_STATUS_FAILED; // Possible Short ID collision } - LogDebug(BCLog::CMPCTBLOCK, "Successfully reconstructed block %s with %u txn prefilled, %u txn from mempool (incl at least %u from extra pool) and %u txn (%u bytes) requested\n", hash.ToString(), prefilled_count, mempool_count, extra_count, vtx_missing.size(), tx_missing_size); - if (vtx_missing.size() < 5) { - for (const auto& tx : vtx_missing) { - LogDebug(BCLog::CMPCTBLOCK, "Reconstructed block %s required tx %s\n", hash.ToString(), tx->GetHash().ToString()); + if (LogAcceptCategory(BCLog::CMPCTBLOCK, BCLog::Level::Debug)) { + const uint256 hash{block.GetHash()}; + uint32_t tx_missing_size{0}; + for (const auto& tx : vtx_missing) tx_missing_size += tx->ComputeTotalSize(); + LogDebug(BCLog::CMPCTBLOCK, "Successfully reconstructed block %s with %u txn prefilled, %u txn from mempool (incl at least %u from extra pool) and %u txn (%u bytes) requested\n", hash.ToString(), prefilled_count, mempool_count, extra_count, vtx_missing.size(), tx_missing_size); + if (vtx_missing.size() < 5) { + for (const auto& tx : vtx_missing) { + LogDebug(BCLog::CMPCTBLOCK, "Reconstructed block %s required tx %s\n", hash.ToString(), tx->GetHash().ToString()); + } } } diff --git a/depend/bitcoin/src/chain.cpp b/depend/bitcoin/src/chain.cpp index 64ea44bb..46a51ac8 100644 --- a/depend/bitcoin/src/chain.cpp +++ b/depend/bitcoin/src/chain.cpp @@ -118,12 +118,12 @@ void CBlockIndex::BuildSkip() pskip = pprev->GetAncestor(GetSkipHeight(nHeight)); } -arith_uint256 GetBlockProof(const CBlockIndex& block) +arith_uint256 GetBitsProof(uint32_t bits) { arith_uint256 bnTarget; bool fNegative; bool fOverflow; - bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow); + bnTarget.SetCompact(bits, &fNegative, &fOverflow); if (fNegative || fOverflow || bnTarget == 0) return 0; // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256 diff --git a/depend/bitcoin/src/chain.h b/depend/bitcoin/src/chain.h index 466276c0..eb4ff719 100644 --- a/depend/bitcoin/src/chain.h +++ b/depend/bitcoin/src/chain.h @@ -299,7 +299,15 @@ class CBlockIndex CBlockIndex& operator=(CBlockIndex&&) = delete; }; -arith_uint256 GetBlockProof(const CBlockIndex& block); +/** Compute how much work an nBits value corresponds to. */ +arith_uint256 GetBitsProof(uint32_t bits); + +/** Compute how much work a block index entry corresponds to. */ +inline arith_uint256 GetBlockProof(const CBlockIndex& block) { return GetBitsProof(block.nBits); } + +/** Compute how much work a block header corresponds to. */ +inline arith_uint256 GetBlockProof(const CBlockHeader& header) { return GetBitsProof(header.nBits); } + /** Return the time it would take to redo the work difference between from and to, assuming the current hashrate corresponds to the difficulty at tip, in seconds. */ int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params&); /** Find the forking point between two chain tips. */ diff --git a/depend/bitcoin/src/chainparams.h b/depend/bitcoin/src/chainparams.h index 571e9e17..732949e8 100644 --- a/depend/bitcoin/src/chainparams.h +++ b/depend/bitcoin/src/chainparams.h @@ -15,7 +15,7 @@ class ArgsManager; /** * Creates and returns a std::unique_ptr of the chosen chain. */ -std::unique_ptr CreateChainParams(const ArgsManager& args, const ChainType chain); +std::unique_ptr CreateChainParams(const ArgsManager& args, ChainType chain); /** * Return the currently selected parameters. This won't change after app @@ -26,6 +26,6 @@ const CChainParams &Params(); /** * Sets the params returned by Params() to those for the given chain type. */ -void SelectParams(const ChainType chain); +void SelectParams(ChainType chain); #endif // BITCOIN_CHAINPARAMS_H diff --git a/depend/bitcoin/src/chainparamsbase.h b/depend/bitcoin/src/chainparamsbase.h index 37e69b32..1407f196 100644 --- a/depend/bitcoin/src/chainparamsbase.h +++ b/depend/bitcoin/src/chainparamsbase.h @@ -35,7 +35,7 @@ class CBaseChainParams /** * Creates and returns a std::unique_ptr of the chosen chain. */ -std::unique_ptr CreateBaseChainParams(const ChainType chain); +std::unique_ptr CreateBaseChainParams(ChainType chain); /** *Set the arguments for chainparams @@ -49,7 +49,7 @@ void SetupChainParamsBaseOptions(ArgsManager& argsman); const CBaseChainParams& BaseParams(); /** Sets the params returned by Params() to those for the given chain. */ -void SelectBaseParams(const ChainType chain); +void SelectBaseParams(ChainType chain); /** List of possible chain / network names */ #define LIST_CHAIN_NAMES "main, test, testnet4, signet, regtest" diff --git a/depend/bitcoin/src/cluster_linearize.h b/depend/bitcoin/src/cluster_linearize.h index d65e61d4..8be16625 100644 --- a/depend/bitcoin/src/cluster_linearize.h +++ b/depend/bitcoin/src/cluster_linearize.h @@ -38,7 +38,7 @@ class DepGraph /** All descendants of the transaction (including itself). */ SetType descendants; - /** Equality operator (primarily for for testing purposes). */ + /** Equality operator (primarily for testing purposes). */ friend bool operator==(const Entry&, const Entry&) noexcept = default; /** Construct an empty entry. */ @@ -479,7 +479,7 @@ std::vector ChunkLinearization(const DepGraph& depgraph, std:: * feerate, each individually sorted in an arbitrary but topological (= no child before parent) * way. * - * We define three quality properties the state can have, each being stronger than the previous: + * We define four quality properties the state can have: * * - acyclic: The state is acyclic whenever no cycle of active dependencies exists within the * graph, ignoring the parent/child direction. This is equivalent to saying that within @@ -529,7 +529,19 @@ std::vector ChunkLinearization(const DepGraph& depgraph, std:: * satisfied. Thus, the state being optimal is more a "the eventual output is *known* * to be optimal". * - * The algorithm terminates whenever an optimal state is reached. + * - minimal: We say the state is minimal when it is: + * - acyclic + * - topological, except that inactive dependencies between equal-feerate chunks are + * allowed as long as they do not form a loop. + * - like optimal, no active dependencies whose top feerate is strictly higher than + * the bottom feerate are allowed. + * - no chunk contains a proper non-empty subset which includes all its own in-chunk + * dependencies of the same feerate as the chunk itself. + * + * A minimal state effectively corresponds to an optimal state, where every chunk has + * been split into its minimal equal-feerate components. + * + * The algorithm terminates whenever a minimal state is reached. * * * This leads to the following high-level algorithm: @@ -539,6 +551,10 @@ std::vector ChunkLinearization(const DepGraph& depgraph, std:: * - Loop until optimal (no dependencies with higher-feerate top than bottom), or time runs out: * - Deactivate a violating dependency, potentially making the state non-topological. * - Activate other dependencies to make the state topological again. + * - If there is time left and the state is optimal: + * - Attempt to split chunks into equal-feerate parts without mutual dependencies between them. + * When this succeeds, recurse into them. + * - If no such chunks can be found, the state is minimal. * - Output the chunks from high to low feerate, each internally sorted topologically. * * When merging, we always either: @@ -558,6 +574,7 @@ std::vector ChunkLinearization(const DepGraph& depgraph, std:: * - Deactivate D, causing the chunk it is in to split into top T and bottom B. * - Do an upwards merge of T, if possible. If so, repeat the same with the merged result. * - Do a downwards merge of B, if possible. If so, repeat the same with the merged result. + * - Split chunks further to obtain a minimal state, see below. * - Output the chunks from high to low feerate, each internally sorted topologically. * * Instead of performing merges arbitrarily to make the initial state topological, it is possible @@ -569,6 +586,21 @@ std::vector ChunkLinearization(const DepGraph& depgraph, std:: * - Do an upwards merge of C, if possible. If so, repeat the same with the merged result. * No downwards merges are needed in this case. * + * After reaching an optimal state, it can be transformed into a minimal state by attempting to + * split chunks further into equal-feerate parts. To do so, pick a specific transaction in each + * chunk (the pivot), and rerun the above split-then-merge procedure again: + * - first, while pretending the pivot transaction has an infinitesimally higher (or lower) fee + * than it really has. If a split exists with the pivot in the top part (or bottom part), this + * will find it. + * - if that fails to split, repeat while pretending the pivot transaction has an infinitesimally + * lower (or higher) fee. If a split exists with the pivot in the bottom part (or top part), this + * will find it. + * - if either succeeds, repeat the procedure for the newly found chunks to split them further. + * If not, the chunk is already minimal. + * If the chunk can be split into equal-feerate parts, then the pivot must exist in either the top + * or bottom part of that potential split. By trying both with the same pivot, if a split exists, + * it will be found. + * * What remains to be specified are a number of heuristics: * * - How to decide which chunks to merge: @@ -644,10 +676,30 @@ class SpanningForestState std::vector m_dep_data; /** A FIFO of chunk representatives of chunks that may be improved still. */ VecDeque m_suboptimal_chunks; + /** A FIFO of chunk representatives with a pivot transaction in them, and a flag to indicate + * their status: + * - bit 1: currently attempting to move the pivot down, rather than up. + * - bit 2: this is the second stage, so we have already tried moving the pivot in the other + * direction. + */ + VecDeque> m_nonminimal_chunks; /** The number of updated transactions in activations/deactivations. */ uint64_t m_cost{0}; + /** Pick a random transaction within a set (which must be non-empty). */ + TxIdx PickRandomTx(const SetType& tx_idxs) noexcept + { + Assume(tx_idxs.Any()); + unsigned pos = m_rng.randrange(tx_idxs.Count()); + for (auto tx_idx : tx_idxs) { + if (pos == 0) return tx_idx; + --pos; + } + Assume(false); + return TxIdx(-1); + } + /** Update a chunk: * - All transactions have their chunk representative set to `chunk_rep`. * - All dependencies which have `query` in their top_setinfo get `dep_change` added to it @@ -769,8 +821,9 @@ class SpanningForestState /*chunk_rep=*/bottom_rep, /*dep_change=*/top_part); } - /** Activate a dependency from the chunk represented by bottom_rep to the chunk represented by - * top_rep, which must exist. Return the representative of the merged chunk. */ + /** Activate a dependency from the chunk represented by bottom_idx to the chunk represented by + * top_idx. Return the representative of the merged chunk, or TxIdx(-1) if no merge is + * possible. */ TxIdx MergeChunks(TxIdx top_rep, TxIdx bottom_rep) noexcept { auto& top_chunk = m_tx_data[top_rep]; @@ -783,7 +836,7 @@ class SpanningForestState auto& tx_data = m_tx_data[tx]; num_deps += (tx_data.children & bottom_chunk.chunk_setinfo.transactions).Count(); } - Assume(num_deps > 0); + if (num_deps == 0) return TxIdx(-1); // Uniformly randomly pick one of them and activate it. TxIdx pick = m_rng.randrange(num_deps); for (auto tx : top_chunk.chunk_setinfo.transactions) { @@ -1068,6 +1121,119 @@ class SpanningForestState return false; } + /** Initialize data structure for minimizing the chunks. Can only be called if state is known + * to be optimal. OptimizeStep() cannot be called anymore afterwards. */ + void StartMinimizing() noexcept + { + m_nonminimal_chunks.clear(); + m_nonminimal_chunks.reserve(m_transaction_idxs.Count()); + // Gather all chunks, and for each, add it with a random pivot in it, and a random initial + // direction, to m_nonminimal_chunks. + for (auto tx : m_transaction_idxs) { + auto& tx_data = m_tx_data[tx]; + if (tx_data.chunk_rep == tx) { + TxIdx pivot_idx = PickRandomTx(tx_data.chunk_setinfo.transactions); + m_nonminimal_chunks.emplace_back(tx, pivot_idx, m_rng.randbits<1>()); + // Randomize the initial order of nonminimal chunks in the queue. + TxIdx j = m_rng.randrange(m_nonminimal_chunks.size()); + if (j != m_nonminimal_chunks.size() - 1) { + std::swap(m_nonminimal_chunks.back(), m_nonminimal_chunks[j]); + } + } + } + } + + /** Try to reduce a chunk's size. Returns false if all chunks are minimal, true otherwise. */ + bool MinimizeStep() noexcept + { + // If the queue of potentially-non-minimal chunks is empty, we are done. + if (m_nonminimal_chunks.empty()) return false; + // Pop an entry from the potentially-non-minimal chunk queue. + auto [chunk_rep, pivot_idx, flags] = m_nonminimal_chunks.front(); + m_nonminimal_chunks.pop_front(); + auto& chunk_data = m_tx_data[chunk_rep]; + Assume(chunk_data.chunk_rep == chunk_rep); + /** Whether to move the pivot down rather than up. */ + bool move_pivot_down = flags & 1; + /** Whether this is already the second stage. */ + bool second_stage = flags & 2; + + // Find a random dependency whose top and bottom set feerates are equal, and which has + // pivot in bottom set (if move_pivot_down) or in top set (if !move_pivot_down). + DepIdx candidate_dep = DepIdx(-1); + uint64_t candidate_tiebreak{0}; + bool have_any = false; + // Iterate over all transactions. + for (auto tx_idx : chunk_data.chunk_setinfo.transactions) { + const auto& tx_data = m_tx_data[tx_idx]; + // Iterate over all active child dependencies of the transaction. + for (auto dep_idx : tx_data.child_deps) { + auto& dep_data = m_dep_data[dep_idx]; + // Skip inactive child dependencies. + if (!dep_data.active) continue; + // Skip if this dependency does not have equal top and bottom set feerates. Note + // that the top cannot have higher feerate than the bottom, or OptimizeSteps would + // have dealt with it. + if (dep_data.top_setinfo.feerate << chunk_data.chunk_setinfo.feerate) continue; + have_any = true; + // Skip if this dependency does not have pivot in the right place. + if (move_pivot_down == dep_data.top_setinfo.transactions[pivot_idx]) continue; + // Remember this as our chosen dependency if it has a better tiebreak. + uint64_t tiebreak = m_rng.rand64() | 1; + if (tiebreak > candidate_tiebreak) { + candidate_tiebreak = tiebreak; + candidate_dep = dep_idx; + } + } + } + // If no dependencies have equal top and bottom set feerate, this chunk is minimal. + if (!have_any) return true; + // If all found dependencies have the pivot in the wrong place, try moving it in the other + // direction. If this was the second stage already, we are done. + if (candidate_tiebreak == 0) { + // Switch to other direction, and to second phase. + flags ^= 3; + if (!second_stage) m_nonminimal_chunks.emplace_back(chunk_rep, pivot_idx, flags); + return true; + } + + // Otherwise, deactivate the dependency that was found. + Deactivate(candidate_dep); + auto& dep_data = m_dep_data[candidate_dep]; + auto parent_chunk_rep = m_tx_data[dep_data.parent].chunk_rep; + auto child_chunk_rep = m_tx_data[dep_data.child].chunk_rep; + // Try to activate a dependency between the new bottom and the new top (opposite from the + // dependency that was just deactivated). + auto merged_chunk_rep = MergeChunks(child_chunk_rep, parent_chunk_rep); + if (merged_chunk_rep != TxIdx(-1)) { + // A self-merge happened. + // Re-insert the chunk into the queue, in the same direction. Note that the chunk_rep + // will have changed. + m_nonminimal_chunks.emplace_back(merged_chunk_rep, pivot_idx, flags); + } else { + // No self-merge happens, and thus we have found a way to split the chunk. Create two + // smaller chunks, and add them to the queue. The one that contains the current pivot + // gets to continue with it in the same direction, to minimize the number of times we + // alternate direction. If we were in the second phase already, the newly created chunk + // inherits that too, because we know no split with the pivot on the other side is + // possible already. The new chunk without the current pivot gets a new randomly-chosen + // one. + if (move_pivot_down) { + auto parent_pivot_idx = PickRandomTx(m_tx_data[parent_chunk_rep].chunk_setinfo.transactions); + m_nonminimal_chunks.emplace_back(parent_chunk_rep, parent_pivot_idx, m_rng.randbits<1>()); + m_nonminimal_chunks.emplace_back(child_chunk_rep, pivot_idx, flags); + } else { + auto child_pivot_idx = PickRandomTx(m_tx_data[child_chunk_rep].chunk_setinfo.transactions); + m_nonminimal_chunks.emplace_back(parent_chunk_rep, pivot_idx, flags); + m_nonminimal_chunks.emplace_back(child_chunk_rep, child_pivot_idx, m_rng.randbits<1>()); + } + if (m_rng.randbool()) { + std::swap(m_nonminimal_chunks.back(), m_nonminimal_chunks[m_nonminimal_chunks.size() - 2]); + } + } + return true; + } + /** Construct a topologically-valid linearization from the current forest state. Must be * topological. */ std::vector GetLinearization() noexcept @@ -1182,6 +1348,10 @@ class SpanningForestState * After an OptimizeStep(), the diagram will always be at least as good as before. Once * OptimizeStep() returns false, the diagram will be equivalent to that produced by * GetLinearization(), and optimal. + * + * After a MinimizeStep(), the diagram cannot change anymore (in the CompareChunks() sense), + * but its number of segments can increase still. Once MinimizeStep() returns false, the number + * of chunks of the produced linearization will match the number of segments in the diagram. */ std::vector GetDiagram() const noexcept { @@ -1328,6 +1498,19 @@ class SpanningForestState auto tx_idx = m_suboptimal_chunks[i]; assert(m_transaction_idxs[tx_idx]); } + + // + // Verify m_nonminimal_chunks. + // + SetType nonminimal_reps; + for (size_t i = 0; i < m_nonminimal_chunks.size(); ++i) { + auto [chunk_rep, pivot, flags] = m_nonminimal_chunks[i]; + assert(m_tx_data[chunk_rep].chunk_rep == chunk_rep); + assert(m_tx_data[pivot].chunk_rep == chunk_rep); + assert(!nonminimal_reps[chunk_rep]); + nonminimal_reps.Set(chunk_rep); + } + assert(nonminimal_reps.IsSubsetOf(m_transaction_idxs)); } }; @@ -1338,32 +1521,42 @@ class SpanningForestState * @param[in] rng_seed A random number seed to control search order. This prevents peers * from predicting exactly which clusters would be hard for us to * linearize. - * @param[in] old_linearization An existing linearization for the cluster (which must be - * topologically valid), or empty. + * @param[in] old_linearization An existing linearization for the cluster, or empty. + * @param[in] is_topological (Only relevant if old_linearization is not empty) Whether + * old_linearization is topologically valid. * @return A tuple of: * - The resulting linearization. It is guaranteed to be at least as * good (in the feerate diagram sense) as old_linearization. * - A boolean indicating whether the result is guaranteed to be - * optimal. + * optimal with minimal chunks. * - How many optimization steps were actually performed. */ template -std::tuple, bool, uint64_t> Linearize(const DepGraph& depgraph, uint64_t max_iterations, uint64_t rng_seed, std::span old_linearization = {}) noexcept +std::tuple, bool, uint64_t> Linearize(const DepGraph& depgraph, uint64_t max_iterations, uint64_t rng_seed, std::span old_linearization = {}, bool is_topological = true) noexcept { /** Initialize a spanning forest data structure for this cluster. */ SpanningForestState forest(depgraph, rng_seed); if (!old_linearization.empty()) { forest.LoadLinearization(old_linearization); + if (!is_topological) forest.MakeTopological(); } else { forest.MakeTopological(); } // Make improvement steps to it until we hit the max_iterations limit, or an optimal result // is found. - bool optimal = false; if (forest.GetCost() < max_iterations) { forest.StartOptimizing(); do { - if (!forest.OptimizeStep()) { + if (!forest.OptimizeStep()) break; + } while (forest.GetCost() < max_iterations); + } + // Make chunk minimization steps until we hit the max_iterations limit, or all chunks are + // minimal. + bool optimal = false; + if (forest.GetCost() < max_iterations) { + forest.StartMinimizing(); + do { + if (!forest.MinimizeStep()) { optimal = true; break; } @@ -1573,38 +1766,6 @@ void PostLinearize(const DepGraph& depgraph, std::span l } } -/** Make linearization topological, retaining its ordering where possible. */ -template -void FixLinearization(const DepGraph& depgraph, std::span linearization) noexcept -{ - // This algorithm can be summarized as moving every element in the linearization backwards - // until it is placed after all its ancestors. - SetType done; - const auto len = linearization.size(); - // Iterate over the elements of linearization from back to front (i is distance from back). - for (DepGraphIndex i = 0; i < len; ++i) { - /** The element at that position. */ - DepGraphIndex elem = linearization[len - 1 - i]; - /** j represents how far from the back of the linearization elem should be placed. */ - DepGraphIndex j = i; - // Figure out which elements need to be moved before elem. - SetType place_before = done & depgraph.Ancestors(elem); - // Find which position to place elem in (updating j), continuously moving the elements - // in between forward. - while (place_before.Any()) { - // j cannot be 0 here; if it was, then there was necessarily nothing earlier which - // elem needs to be placed before anymore, and place_before would be empty. - Assume(j > 0); - auto to_swap = linearization[len - 1 - (j - 1)]; - place_before.Reset(to_swap); - linearization[len - 1 - (j--)] = to_swap; - } - // Put elem in its final position and mark it as done. - linearization[len - 1 - j] = elem; - done.Set(elem); - } -} - } // namespace cluster_linearize #endif // BITCOIN_CLUSTER_LINEARIZE_H diff --git a/depend/bitcoin/src/coins.cpp b/depend/bitcoin/src/coins.cpp index 14381ecb..7f2ffc38 100644 --- a/depend/bitcoin/src/coins.cpp +++ b/depend/bitcoin/src/coins.cpp @@ -16,7 +16,11 @@ TRACEPOINT_SEMAPHORE(utxocache, uncache); std::optional CCoinsView::GetCoin(const COutPoint& outpoint) const { return std::nullopt; } uint256 CCoinsView::GetBestBlock() const { return uint256(); } std::vector CCoinsView::GetHeadBlocks() const { return std::vector(); } -bool CCoinsView::BatchWrite(CoinsViewCacheCursor& cursor, const uint256 &hashBlock) { return false; } +void CCoinsView::BatchWrite(CoinsViewCacheCursor& cursor, const uint256& hashBlock) +{ + for (auto it{cursor.Begin()}; it != cursor.End(); it = cursor.NextAndMaybeErase(*it)) { } +} + std::unique_ptr CCoinsView::Cursor() const { return nullptr; } bool CCoinsView::HaveCoin(const COutPoint &outpoint) const @@ -30,7 +34,7 @@ bool CCoinsViewBacked::HaveCoin(const COutPoint &outpoint) const { return base-> uint256 CCoinsViewBacked::GetBestBlock() const { return base->GetBestBlock(); } std::vector CCoinsViewBacked::GetHeadBlocks() const { return base->GetHeadBlocks(); } void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; } -bool CCoinsViewBacked::BatchWrite(CoinsViewCacheCursor& cursor, const uint256 &hashBlock) { return base->BatchWrite(cursor, hashBlock); } +void CCoinsViewBacked::BatchWrite(CoinsViewCacheCursor& cursor, const uint256& hashBlock) { base->BatchWrite(cursor, hashBlock); } std::unique_ptr CCoinsViewBacked::Cursor() const { return base->Cursor(); } size_t CCoinsViewBacked::EstimateSize() const { return base->EstimateSize(); } @@ -183,7 +187,8 @@ void CCoinsViewCache::SetBestBlock(const uint256 &hashBlockIn) { hashBlock = hashBlockIn; } -bool CCoinsViewCache::BatchWrite(CoinsViewCacheCursor& cursor, const uint256 &hashBlockIn) { +void CCoinsViewCache::BatchWrite(CoinsViewCacheCursor& cursor, const uint256& hashBlockIn) +{ for (auto it{cursor.Begin()}; it != cursor.End(); it = cursor.NextAndMaybeErase(*it)) { if (!it->second.IsDirty()) { // TODO a cursor can only contain dirty entries continue; @@ -246,33 +251,27 @@ bool CCoinsViewCache::BatchWrite(CoinsViewCacheCursor& cursor, const uint256 &ha } } hashBlock = hashBlockIn; - return true; } -bool CCoinsViewCache::Flush(bool will_reuse_cache) { +void CCoinsViewCache::Flush(bool will_reuse_cache) +{ auto cursor{CoinsViewCacheCursor(m_sentinel, cacheCoins, /*will_erase=*/true)}; - bool fOk = base->BatchWrite(cursor, hashBlock); - if (fOk) { - cacheCoins.clear(); - if (will_reuse_cache) { - ReallocateCache(); - } - cachedCoinsUsage = 0; + base->BatchWrite(cursor, hashBlock); + cacheCoins.clear(); + if (will_reuse_cache) { + ReallocateCache(); } - return fOk; + cachedCoinsUsage = 0; } -bool CCoinsViewCache::Sync() +void CCoinsViewCache::Sync() { auto cursor{CoinsViewCacheCursor(m_sentinel, cacheCoins, /*will_erase=*/false)}; - bool fOk = base->BatchWrite(cursor, hashBlock); - if (fOk) { - if (m_sentinel.second.Next() != &m_sentinel) { - /* BatchWrite must clear flags of all entries */ - throw std::logic_error("Not all unspent flagged entries were cleared"); - } + base->BatchWrite(cursor, hashBlock); + if (m_sentinel.second.Next() != &m_sentinel) { + /* BatchWrite must clear flags of all entries */ + throw std::logic_error("Not all unspent flagged entries were cleared"); } - return fOk; } void CCoinsViewCache::Uncache(const COutPoint& hash) diff --git a/depend/bitcoin/src/coins.h b/depend/bitcoin/src/coins.h index 8d07f7fe..6da53829 100644 --- a/depend/bitcoin/src/coins.h +++ b/depend/bitcoin/src/coins.h @@ -324,7 +324,7 @@ class CCoinsView //! Do a bulk modification (multiple Coin changes + BestBlock change). //! The passed cursor is used to iterate through the coins. - virtual bool BatchWrite(CoinsViewCacheCursor& cursor, const uint256& hashBlock); + virtual void BatchWrite(CoinsViewCacheCursor& cursor, const uint256& hashBlock); //! Get a cursor to iterate over the whole state virtual std::unique_ptr Cursor() const; @@ -350,7 +350,7 @@ class CCoinsViewBacked : public CCoinsView uint256 GetBestBlock() const override; std::vector GetHeadBlocks() const override; void SetBackend(CCoinsView &viewIn); - bool BatchWrite(CoinsViewCacheCursor& cursor, const uint256 &hashBlock) override; + void BatchWrite(CoinsViewCacheCursor& cursor, const uint256& hashBlock) override; std::unique_ptr Cursor() const override; size_t EstimateSize() const override; }; @@ -389,7 +389,7 @@ class CCoinsViewCache : public CCoinsViewBacked bool HaveCoin(const COutPoint &outpoint) const override; uint256 GetBestBlock() const override; void SetBestBlock(const uint256 &hashBlock); - bool BatchWrite(CoinsViewCacheCursor& cursor, const uint256 &hashBlock) override; + void BatchWrite(CoinsViewCacheCursor& cursor, const uint256& hashBlock) override; std::unique_ptr Cursor() const override { throw std::logic_error("CCoinsViewCache cursor iteration not supported."); } @@ -441,18 +441,16 @@ class CCoinsViewCache : public CCoinsViewBacked * to be forgotten. * If will_reuse_cache is false, the cache will retain the same memory footprint * after flushing and should be destroyed to deallocate. - * If false is returned, the state of this cache (and its backing view) will be undefined. */ - bool Flush(bool will_reuse_cache = true); + void Flush(bool will_reuse_cache = true); /** * Push the modifications applied to this cache to its base while retaining * the contents of this cache (except for spent coins, which we erase). * Failure to call this method or Flush() before destruction will cause the changes * to be forgotten. - * If false is returned, the state of this cache (and its backing view) will be undefined. */ - bool Sync(); + void Sync(); /** * Removes the UTXO with the given outpoint from the cache, if it is diff --git a/depend/bitcoin/src/common/bloom.h b/depend/bitcoin/src/common/bloom.h index bff96a23..97007e1f 100644 --- a/depend/bitcoin/src/common/bloom.h +++ b/depend/bitcoin/src/common/bloom.h @@ -61,7 +61,7 @@ class CBloomFilter * It should generally always be a random value (and is largely only exposed for unit testing) * nFlags should be one of the BLOOM_UPDATE_* enums (not _MASK) */ - CBloomFilter(const unsigned int nElements, const double nFPRate, const unsigned int nTweak, unsigned char nFlagsIn); + CBloomFilter(unsigned int nElements, double nFPRate, unsigned int nTweak, unsigned char nFlagsIn); CBloomFilter() : nHashFuncs(0), nTweak(0), nFlags(0) {} SERIALIZE_METHODS(CBloomFilter, obj) { READWRITE(obj.vData, obj.nHashFuncs, obj.nTweak, obj.nFlags); } @@ -108,7 +108,7 @@ class CBloomFilter class CRollingBloomFilter { public: - CRollingBloomFilter(const unsigned int nElements, const double nFPRate); + CRollingBloomFilter(unsigned int nElements, double nFPRate); void insert(std::span vKey); bool contains(std::span vKey) const; diff --git a/depend/bitcoin/src/common/messages.h b/depend/bitcoin/src/common/messages.h index 4cabdc79..60fdaa18 100644 --- a/depend/bitcoin/src/common/messages.h +++ b/depend/bitcoin/src/common/messages.h @@ -31,7 +31,7 @@ std::string FeeModeInfo(std::pair& mode); std::string FeeModesDetail(std::string default_info); std::string InvalidEstimateModeErrorMessage(); bilingual_str PSBTErrorString(PSBTError error); -bilingual_str TransactionErrorString(const node::TransactionError error); +bilingual_str TransactionErrorString(node::TransactionError error); bilingual_str ResolveErrMsg(const std::string& optname, const std::string& strBind); bilingual_str InvalidPortErrMsg(const std::string& optname, const std::string& strPort); bilingual_str AmountHighWarn(const std::string& optname); diff --git a/depend/bitcoin/src/common/signmessage.h b/depend/bitcoin/src/common/signmessage.h index 4533875a..c2152f35 100644 --- a/depend/bitcoin/src/common/signmessage.h +++ b/depend/bitcoin/src/common/signmessage.h @@ -72,6 +72,6 @@ bool MessageSign( */ uint256 MessageHash(const std::string& message); -std::string SigningResultString(const SigningResult res); +std::string SigningResultString(SigningResult res); #endif // BITCOIN_COMMON_SIGNMESSAGE_H diff --git a/depend/bitcoin/src/compat/compat.h b/depend/bitcoin/src/compat/compat.h index b7fe6b98..3f0e1276 100644 --- a/depend/bitcoin/src/compat/compat.h +++ b/depend/bitcoin/src/compat/compat.h @@ -38,6 +38,18 @@ typedef u_short sa_family_t; #endif +// Brace style in the IN6ADDR_*_INIT macros differs across platforms. +#if defined(__illumos__) +#define COMPAT_IN6ADDR_ANY_INIT {{IN6ADDR_ANY_INIT}} +#else +#define COMPAT_IN6ADDR_ANY_INIT IN6ADDR_ANY_INIT +#endif +#if defined(__illumos__) || defined(_MSC_VER) +#define COMPAT_IN6ADDR_LOOPBACK_INIT {{IN6ADDR_LOOPBACK_INIT}} +#else +#define COMPAT_IN6ADDR_LOOPBACK_INIT IN6ADDR_LOOPBACK_INIT +#endif + // We map Linux / BSD error functions and codes, to the equivalent // Windows definitions, and use the WSA* names throughout our code. // Note that glibc defines EWOULDBLOCK as EAGAIN (see errno.h). diff --git a/depend/bitcoin/src/consensus/merkle.cpp b/depend/bitcoin/src/consensus/merkle.cpp index 84ff352d..c6ae81c6 100644 --- a/depend/bitcoin/src/consensus/merkle.cpp +++ b/depend/bitcoin/src/consensus/merkle.cpp @@ -66,9 +66,9 @@ uint256 ComputeMerkleRoot(std::vector hashes, bool* mutated) { uint256 BlockMerkleRoot(const CBlock& block, bool* mutated) { std::vector leaves; - leaves.resize(block.vtx.size()); + leaves.reserve((block.vtx.size() + 1) & ~1ULL); // capacity rounded up to even for (size_t s = 0; s < block.vtx.size(); s++) { - leaves[s] = block.vtx[s]->GetHash().ToUint256(); + leaves.push_back(block.vtx[s]->GetHash().ToUint256()); } return ComputeMerkleRoot(std::move(leaves), mutated); } @@ -76,10 +76,10 @@ uint256 BlockMerkleRoot(const CBlock& block, bool* mutated) uint256 BlockWitnessMerkleRoot(const CBlock& block) { std::vector leaves; - leaves.resize(block.vtx.size()); - leaves[0].SetNull(); // The witness hash of the coinbase is 0. + leaves.reserve((block.vtx.size() + 1) & ~1ULL); // capacity rounded up to even + leaves.emplace_back(); // The witness hash of the coinbase is 0. for (size_t s = 1; s < block.vtx.size(); s++) { - leaves[s] = block.vtx[s]->GetWitnessHash().ToUint256(); + leaves.push_back(block.vtx[s]->GetWitnessHash().ToUint256()); } return ComputeMerkleRoot(std::move(leaves)); } diff --git a/depend/bitcoin/src/core_write.cpp b/depend/bitcoin/src/core_io.cpp similarity index 54% rename from depend/bitcoin/src/core_write.cpp rename to depend/bitcoin/src/core_io.cpp index e4f23458..a4b726cd 100644 --- a/depend/bitcoin/src/core_write.cpp +++ b/depend/bitcoin/src/core_io.cpp @@ -4,25 +4,286 @@ #include -#include +#include +#include #include #include #include +#include #include +// IWYU incorrectly suggests replacing this header +// with forward declarations. +// See https://github.com/include-what-you-use/include-what-you-use/issues/1886. +#include // IWYU pragma: keep +#include #include