diff --git a/.github/actions/configure-environment/action.yml b/.github/actions/configure-environment/action.yml index e2a26b7184d1..d3c928cf3f53 100644 --- a/.github/actions/configure-environment/action.yml +++ b/.github/actions/configure-environment/action.yml @@ -7,7 +7,9 @@ runs: shell: bash run: | echo "BASE_ROOT_DIR=${{ runner.temp }}" >> "$GITHUB_ENV" - echo "BASE_BUILD_DIR=${{ runner.temp }}/build" >> "$GITHUB_ENV" + # Space and non-ASCII symbols mimic BASE_SCRATCH_DIR in ci/test/00_setup_env.sh, + # to test word-splitting and UTF-8 path handling on CI. + echo "BASE_BUILD_DIR=${{ runner.temp }}/build_ ₿🧪_" >> "$GITHUB_ENV" echo "CCACHE_DIR=${{ runner.temp }}/ccache_dir" >> $GITHUB_ENV echo "DEPENDS_DIR=${{ runner.temp }}/depends" >> "$GITHUB_ENV" echo "BASE_CACHE=${{ runner.temp }}/depends/built" >> $GITHUB_ENV diff --git a/.tx/config b/.tx/config index 41051254f32f..a43890a3b92d 100644 --- a/.tx/config +++ b/.tx/config @@ -1,7 +1,7 @@ [main] host = https://www.transifex.com -[o:bitcoin:p:bitcoin:r:qt-translation-031x] -file_filter = src/qt/locale/bitcoin_.xlf -source_file = src/qt/locale/bitcoin_en.xlf +[o:bitcoin:p:bitcoin:r:qt-translation-032x] +file_filter = src/qt/locale/bitcoin_.ts +source_file = src/qt/locale/bitcoin_en.ts source_lang = en diff --git a/CMakeLists.txt b/CMakeLists.txt index ffd2da14dbce..fec2b1a3fa08 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -471,7 +471,6 @@ if(MSVC) try_append_cxx_flags("/wd4805" TARGET warn_interface SKIP_LINK) target_compile_definitions(warn_interface INTERFACE _CRT_SECURE_NO_WARNINGS - _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING ) else() try_append_cxx_flags("-Wall" TARGET warn_interface SKIP_LINK) @@ -601,6 +600,7 @@ endif() if(REDUCE_EXPORTS) set(CMAKE_CXX_VISIBILITY_PRESET hidden) + set(CMAKE_VISIBILITY_INLINES_HIDDEN ON) try_append_linker_flag("-Wl,--exclude-libs,ALL" TARGET core_interface) try_append_linker_flag("-Wl,-no_exported_symbols" VAR CMAKE_EXE_LINKER_FLAGS) endif() diff --git a/ci/lint/requirements.txt b/ci/lint/requirements.txt index e9459225fb0a..157845381d00 100644 --- a/ci/lint/requirements.txt +++ b/ci/lint/requirements.txt @@ -1,3 +1,4 @@ +# lief version should match the version used in Guix lief==0.17.5 mypy==2.3.0 pyzmq==27.1.0 diff --git a/ci/test/00_setup_env_freebsd_cross.sh b/ci/test/00_setup_env_freebsd_cross.sh index 29602ae2ebd3..9a22cb6f96f6 100755 --- a/ci/test/00_setup_env_freebsd_cross.sh +++ b/ci/test/00_setup_env_freebsd_cross.sh @@ -12,6 +12,7 @@ export APT_LLVM_V="22" export HOST=x86_64-unknown-freebsd export FREEBSD_VERSION=15.1 export FREEBSD_SDK_BASENAME="freebsd-${HOST}-${FREEBSD_VERSION}" +export FREEBSD_SDK_SHA256=3768988b151c20f965679062b065c63a977d6bbb9f47fd83695ec2c40790c18f export PACKAGES="clang-${APT_LLVM_V} llvm-${APT_LLVM_V} lld-${APT_LLVM_V}" export SYSROOT="--sysroot=${DEPENDS_DIR}/SDKs/${FREEBSD_SDK_BASENAME}" export DEP_OPTS="build_CC=clang build_CXX=clang++ \ diff --git a/ci/test/00_setup_env_mac_cross.sh b/ci/test/00_setup_env_mac_cross.sh index 63d89fb9b927..80c6f878eb08 100755 --- a/ci/test/00_setup_env_mac_cross.sh +++ b/ci/test/00_setup_env_mac_cross.sh @@ -14,6 +14,7 @@ export HOST=arm64-apple-darwin export PACKAGES="clang lld llvm zip" export XCODE_VERSION=26.1.1 export XCODE_BUILD_ID=17B100 +export OSX_SDK_SHA256=9600fa93644df674ee916b5e2c8a6ba8dacf631996a65dc922d003b98b5ea3b1 export RUN_UNIT_TESTS=false export RUN_FUNCTIONAL_TESTS=false export GOAL="deploy" diff --git a/ci/test/00_setup_env_mac_cross_intel.sh b/ci/test/00_setup_env_mac_cross_intel.sh index 4b07e14b8195..e679c957d810 100755 --- a/ci/test/00_setup_env_mac_cross_intel.sh +++ b/ci/test/00_setup_env_mac_cross_intel.sh @@ -14,6 +14,7 @@ export HOST=x86_64-apple-darwin export PACKAGES="clang lld llvm zip" export XCODE_VERSION=26.1.1 export XCODE_BUILD_ID=17B100 +export OSX_SDK_SHA256=9600fa93644df674ee916b5e2c8a6ba8dacf631996a65dc922d003b98b5ea3b1 export RUN_UNIT_TESTS=false export RUN_FUNCTIONAL_TESTS=false export GOAL="deploy" diff --git a/ci/test/00_setup_env_netbsd_cross.sh b/ci/test/00_setup_env_netbsd_cross.sh index 9fb4c18ac1b4..e817473f7a7a 100755 --- a/ci/test/00_setup_env_netbsd_cross.sh +++ b/ci/test/00_setup_env_netbsd_cross.sh @@ -10,8 +10,11 @@ export CONTAINER_NAME=ci_netbsd_cross export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:26.04" export APT_LLVM_V="22" export HOST=x86_64-unknown-netbsd -export NETBSD_VERSION=11.0_RC6 +export NETBSD_VERSION=11.0 export NETBSD_SDK_BASENAME="netbsd-${HOST}-${NETBSD_VERSION}" +export NETBSD_SDK_SHA512SUMS="\ +e8871bbedb8c3e0f696cc2596ced0c1e6497939f725fb3495b8d2c168430325907550f5f840f4dd0e3c73e6090394747c5e54762f2737de81177b984403522a8 base.tar.xz\n\ +d8df6c07e9142dd8189292b769ac312f86185a6a278a752c18c840f7cd3a8dd3c535f9b0c8e06b62d556b2c75b97a01d786184e8a18f5e080ccd213591c8628f comp.tar.xz" export PACKAGES="clang-${APT_LLVM_V} llvm-${APT_LLVM_V} lld-${APT_LLVM_V}" export SYSROOT="--sysroot=${DEPENDS_DIR}/SDKs/${NETBSD_SDK_BASENAME}" export DEP_OPTS="build_CC=clang build_CXX=clang++ \ diff --git a/ci/test/00_setup_env_openbsd_cross.sh b/ci/test/00_setup_env_openbsd_cross.sh index 1732aef36ea5..f9d75e47d70b 100755 --- a/ci/test/00_setup_env_openbsd_cross.sh +++ b/ci/test/00_setup_env_openbsd_cross.sh @@ -12,6 +12,9 @@ export APT_LLVM_V="22" export HOST=x86_64-unknown-openbsd export OPENBSD_VERSION=7.9 export OPENBSD_SDK_BASENAME="openbsd-${HOST}-${OPENBSD_VERSION}" +export OPENBSD_SDK_SHA256SUMS="\ +923d2e03f06408d50d4848334398c6d04b5514dcac7917badfc178a0eef248de base79.tgz\n\ +21a67af20aebcabf85b09f4206fc95b4cae0a35d42b154b976f0159f457724f9 comp79.tgz" export PACKAGES="clang-${APT_LLVM_V} llvm-${APT_LLVM_V} lld-${APT_LLVM_V}" export SYSROOT="--sysroot=${DEPENDS_DIR}/SDKs/${OPENBSD_SDK_BASENAME}" export DEP_OPTS="NO_QT=1 build_CC=clang build_CXX=clang++ \ diff --git a/ci/test/01_base_install.sh b/ci/test/01_base_install.sh index f619a088efaa..0c3dfc424471 100755 --- a/ci/test/01_base_install.sh +++ b/ci/test/01_base_install.sh @@ -88,8 +88,16 @@ if [[ -n "${USE_INSTRUMENTED_LIBCPP}" ]]; then fi if [[ ${BARE_METAL_RISCV} == "true" ]]; then + # Use a mirror for these submodules as sourceware blocks too many requests combating AI. ${CI_RETRY_EXE} git clone --depth=1 https://github.com/riscv-collab/riscv-gnu-toolchain -b 2026.06.06 /riscv/gcc ( cd /riscv/gcc; + export GIT_CONFIG_COUNT=3 + export GIT_CONFIG_KEY_0=url.https://git.fish.foo/mirrors/binutils-gdb.git.insteadOf + export GIT_CONFIG_VALUE_0=https://sourceware.org/git/binutils-gdb.git + export GIT_CONFIG_KEY_1=url.https://git.fish.foo/mirrors/glibc.git.insteadOf + export GIT_CONFIG_VALUE_1=https://sourceware.org/git/glibc.git + export GIT_CONFIG_KEY_2=url.https://git.fish.foo/mirrors/newlib-cygwin.git.insteadOf + export GIT_CONFIG_VALUE_2=https://sourceware.org/git/newlib-cygwin.git ./configure --prefix=/opt/riscv-ilp32 --with-arch=rv32gc --with-abi=ilp32 --disable-gdb; make "$MAKEJOBS"; ) rm -rf /riscv/gcc @@ -115,18 +123,20 @@ if [ -n "$XCODE_VERSION" ] && [ ! -d "${DEPENDS_DIR}/SDKs/${OSX_SDK_BASENAME}" ] if [ ! -f "$OSX_SDK_PATH" ]; then ${CI_RETRY_EXE} curl --location --fail "${SDK_URL}/${OSX_SDK_FILENAME}" -o "$OSX_SDK_PATH" fi + sha256sum -c <<<"${OSX_SDK_SHA256} ${OSX_SDK_PATH}" tar -C "${DEPENDS_DIR}/SDKs" -xf "$OSX_SDK_PATH" fi if [ -n "$NETBSD_VERSION" ] && [ ! -d "${DEPENDS_DIR}/SDKs/${NETBSD_SDK_BASENAME}" ]; then mkdir -p "${DEPENDS_DIR}/SDKs/${NETBSD_SDK_BASENAME}" - for NETBSD_SDK_FILENAME in base.tar.xz comp.tar.xz; do + while read -r NETBSD_SDK_SHA512 NETBSD_SDK_FILENAME; do NETBSD_SDK_PATH="${DEPENDS_DIR}/sdk-sources/${NETBSD_SDK_FILENAME}" if [ ! -f "$NETBSD_SDK_PATH" ]; then ${CI_RETRY_EXE} curl --location --fail "https://cdn.netbsd.org/pub/NetBSD/NetBSD-${NETBSD_VERSION}/amd64/binary/sets/${NETBSD_SDK_FILENAME}" -o "$NETBSD_SDK_PATH" fi + sha512sum -c <<<"${NETBSD_SDK_SHA512} ${NETBSD_SDK_PATH}" tar -C "${DEPENDS_DIR}/SDKs/${NETBSD_SDK_BASENAME}" -xf "$NETBSD_SDK_PATH" - done + done < <(printf '%b\n' "${NETBSD_SDK_SHA512SUMS}") fi if [ -n "$FREEBSD_VERSION" ] && [ ! -d "${DEPENDS_DIR}/SDKs/${FREEBSD_SDK_BASENAME}" ]; then @@ -135,27 +145,29 @@ if [ -n "$FREEBSD_VERSION" ] && [ ! -d "${DEPENDS_DIR}/SDKs/${FREEBSD_SDK_BASENA if [ ! -f "$FREEBSD_SDK_PATH" ]; then ${CI_RETRY_EXE} curl --location --fail "https://download.freebsd.org/releases/amd64/${FREEBSD_VERSION}-RELEASE/base.txz" -o "$FREEBSD_SDK_PATH" fi + sha256sum -c <<<"${FREEBSD_SDK_SHA256} ${FREEBSD_SDK_PATH}" mkdir -p "${DEPENDS_DIR}/SDKs/${FREEBSD_SDK_BASENAME}" tar -C "${DEPENDS_DIR}/SDKs/${FREEBSD_SDK_BASENAME}" -xf "$FREEBSD_SDK_PATH" fi if [ -n "$OPENBSD_VERSION" ] && [ ! -d "${DEPENDS_DIR}/SDKs/${OPENBSD_SDK_BASENAME}" ]; then mkdir -p "${DEPENDS_DIR}/SDKs/${OPENBSD_SDK_BASENAME}" - for OPENBSD_SDK_FILENAME in base79.tgz comp79.tgz; do + while read -r OPENBSD_SDK_SHA256 OPENBSD_SDK_FILENAME; do OPENBSD_SDK_PATH="${DEPENDS_DIR}/sdk-sources/${OPENBSD_SDK_FILENAME}" if [ ! -f "$OPENBSD_SDK_PATH" ]; then ${CI_RETRY_EXE} curl --location --fail "https://cdn.openbsd.org/pub/OpenBSD/${OPENBSD_VERSION}/amd64/${OPENBSD_SDK_FILENAME}" -o "$OPENBSD_SDK_PATH" fi + sha256sum -c <<<"${OPENBSD_SDK_SHA256} ${OPENBSD_SDK_PATH}" tar -C "${DEPENDS_DIR}/SDKs/${OPENBSD_SDK_BASENAME}" -xf "$OPENBSD_SDK_PATH" - ( - # The SDK has versioned shared libs, but no unversioned libfoo.so symlink, - # which breaks linking the kernel with lld. Create the symlinks. - cd "${DEPENDS_DIR}/SDKs/${OPENBSD_SDK_BASENAME}/usr/lib" - ln -sf libc++abi.so.*.* libc++abi.so - ln -sf libc++.so.*.* libc++.so - ln -sf libpthread.so.*.* libpthread.so - ) - done + done < <(printf '%b\n' "${OPENBSD_SDK_SHA256SUMS}") + ( + # The SDK has versioned shared libs, but no unversioned libfoo.so symlink, + # which breaks linking the kernel with lld. Create the symlinks. + cd "${DEPENDS_DIR}/SDKs/${OPENBSD_SDK_BASENAME}/usr/lib" + ln -sf libc++abi.so.*.* libc++abi.so + ln -sf libc++.so.*.* libc++.so + ln -sf libpthread.so.*.* libpthread.so + ) fi echo -n "done" > "${CFG_DONE}" diff --git a/ci/test/03_test_script.sh b/ci/test/03_test_script.sh index 7650ab7d86b6..abc501d1d0b4 100755 --- a/ci/test/03_test_script.sh +++ b/ci/test/03_test_script.sh @@ -234,7 +234,7 @@ fi if [[ "${RUN_IWYU}" == true ]]; then # TODO: Consider enforcing IWYU across the entire codebase. - FILES_WITH_ENFORCED_IWYU="/src/(((bench|crypto|index|kernel|primitives|script|univalue/(lib|test)|util|zmq)/.*|common/license_info|node/(blockstorage|interfaces|miner|mining_args|utxo_snapshot)|rpc/mining|clientversion|core_io|signet|init)\\.cpp)" + FILES_WITH_ENFORCED_IWYU='/src/((bench|common|consensus|crypto|index|kernel|primitives|script|univalue/(lib|test)|util|zmq)/.*|node/(blockstorage|interfaces|miner|mining_args|utxo_snapshot)|rpc/mining|clientversion|core_io|signet|init)\.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" @@ -247,7 +247,9 @@ if [[ "${RUN_IWYU}" == true ]]; then -p "${BASE_BUILD_DIR}" "${MAKEJOBS}" \ -- -Xiwyu --cxx17ns -Xiwyu --mapping_file="${BASE_ROOT_DIR}/contrib/devtools/iwyu/bitcoin.core.imp" \ -Xiwyu --max_line_length=160 \ - -Xiwyu --check_also="*/primitives/*.h" \ + -Xiwyu --check_also='*/common/types\.h' \ + -Xiwyu --check_also='*/consensus/*\.h' \ + -Xiwyu --check_also='*/primitives/transaction_identifier\.h' \ 2>&1 || true } | tee /tmp/iwyu_ci.out python3 "/include-what-you-use/fix_includes.py" --nosafe_headers < /tmp/iwyu_ci.out diff --git a/cmake/introspection.cmake b/cmake/introspection.cmake index d6083f5243ab..612362795a34 100644 --- a/cmake/introspection.cmake +++ b/cmake/introspection.cmake @@ -24,8 +24,7 @@ endif() # Even though ::system is part of the standard library, we still check # for it, to support building targets that don't have it, such as iOS. check_cxx_symbol_exists(std::system "cstdlib" HAVE_STD_SYSTEM) -check_cxx_symbol_exists(::_wsystem "stdlib.h" HAVE__WSYSTEM) -if(HAVE_STD_SYSTEM OR HAVE__WSYSTEM) +if(HAVE_STD_SYSTEM) set(HAVE_SYSTEM 1) endif() diff --git a/cmake/module/GenerateSetupNsi.cmake b/cmake/module/GenerateSetupNsi.cmake deleted file mode 100644 index c8d5bd67c5f1..000000000000 --- a/cmake/module/GenerateSetupNsi.cmake +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (c) 2023-present The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or https://opensource.org/license/mit/. - -function(generate_setup_nsi) - set(abs_top_srcdir ${PROJECT_SOURCE_DIR}) - set(abs_top_builddir ${PROJECT_BINARY_DIR}) - set(CLIENT_URL ${PROJECT_HOMEPAGE_URL}) - set(CLIENT_TARNAME "bitcoin") - set(BITCOIN_WRAPPER_NAME "bitcoin") - set(BITCOIN_GUI_NAME "bitcoin-qt") - set(BITCOIN_DAEMON_NAME "bitcoind") - set(BITCOIN_CLI_NAME "bitcoin-cli") - set(BITCOIN_TX_NAME "bitcoin-tx") - set(BITCOIN_WALLET_TOOL_NAME "bitcoin-wallet") - set(BITCOIN_TEST_NAME "test_bitcoin") - set(EXEEXT ${CMAKE_EXECUTABLE_SUFFIX}) - configure_file(${PROJECT_SOURCE_DIR}/share/setup.nsi.in ${PROJECT_BINARY_DIR}/bitcoin-win64-setup.nsi USE_SOURCE_PERMISSIONS @ONLY) -endfunction() diff --git a/cmake/module/Maintenance.cmake b/cmake/module/Maintenance.cmake index 15fbf2bea8e5..43e145d63f4b 100644 --- a/cmake/module/Maintenance.cmake +++ b/cmake/module/Maintenance.cmake @@ -19,32 +19,21 @@ function(setup_split_debug_script) endfunction() function(add_windows_deploy_target) + configure_file(${PROJECT_SOURCE_DIR}/cmake/script/GenerateWindowsInstaller.cmake.in ${PROJECT_BINARY_DIR}/GenerateWindowsInstaller.cmake USE_SOURCE_PERMISSIONS @ONLY) if(MINGW AND TARGET bitcoin AND TARGET bitcoin-qt AND TARGET bitcoind AND TARGET bitcoin-cli AND TARGET bitcoin-tx AND TARGET bitcoin-wallet AND TARGET bitcoin-util AND TARGET test_bitcoin) - find_program(MAKENSIS_EXECUTABLE makensis) - if(NOT MAKENSIS_EXECUTABLE) - add_custom_target(deploy - COMMAND ${CMAKE_COMMAND} -E echo "Error: NSIS not found" - ) - return() - endif() - - # TODO: Consider replacing this code with the CPack NSIS Generator. - # See https://cmake.org/cmake/help/latest/cpack_gen/nsis.html - include(GenerateSetupNsi) - generate_setup_nsi() add_custom_command( OUTPUT ${PROJECT_BINARY_DIR}/bitcoin-win64-setup.exe - COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/release - COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ - COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ - COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ - COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ - COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ - COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ - COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ - COMMAND ${CMAKE_STRIP} $ -o ${PROJECT_BINARY_DIR}/release/$ - COMMAND ${MAKENSIS_EXECUTABLE} -V2 ${PROJECT_BINARY_DIR}/bitcoin-win64-setup.nsi - VERBATIM + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E make_directory release + COMMAND ${CMAKE_STRIP} $ -o release/$ + COMMAND ${CMAKE_STRIP} $ -o release/$ + COMMAND ${CMAKE_STRIP} $ -o release/$ + COMMAND ${CMAKE_STRIP} $ -o release/$ + COMMAND ${CMAKE_STRIP} $ -o release/$ + COMMAND ${CMAKE_STRIP} $ -o release/$ + COMMAND ${CMAKE_STRIP} $ -o release/$ + COMMAND ${CMAKE_STRIP} $ -o release/$ + COMMAND ${CMAKE_COMMAND} -D BIN_DIR=release -D LIBEXEC_DIR=release -P GenerateWindowsInstaller.cmake ) add_custom_target(deploy DEPENDS ${PROJECT_BINARY_DIR}/bitcoin-win64-setup.exe) endif() diff --git a/cmake/script/GenerateWindowsInstaller.cmake.in b/cmake/script/GenerateWindowsInstaller.cmake.in new file mode 100644 index 000000000000..16ebdd49b8ff --- /dev/null +++ b/cmake/script/GenerateWindowsInstaller.cmake.in @@ -0,0 +1,40 @@ +# Copyright (c) 2026-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +find_program(MAKENSIS_EXECUTABLE makensis REQUIRED) + +# Project variables. +set(CLIENT_NAME "@CLIENT_NAME@") +set(CLIENT_VERSION_MAJOR @CLIENT_VERSION_MAJOR@) +set(CLIENT_VERSION_MINOR @CLIENT_VERSION_MINOR@) +set(CLIENT_VERSION_BUILD @CLIENT_VERSION_BUILD@) +set(CLIENT_VERSION_STRING "@CLIENT_VERSION_STRING@") +set(CLIENT_URL "@PROJECT_HOMEPAGE_URL@") +set(COPYRIGHT_YEAR "@COPYRIGHT_YEAR@") +set(COPYRIGHT_HOLDERS_FINAL "@COPYRIGHT_HOLDERS_FINAL@") +set(abs_top_srcdir @PROJECT_SOURCE_DIR@) +set(EXEEXT @CMAKE_EXECUTABLE_SUFFIX@) + +# Script variables. +cmake_path(ABSOLUTE_PATH BIN_DIR NORMALIZE) +cmake_path(ABSOLUTE_PATH LIBEXEC_DIR NORMALIZE) + +# Other variables required by the `setup.nsi.in` template. +set(CLIENT_TARNAME "bitcoin") +set(BITCOIN_WRAPPER_NAME "bitcoin") +set(BITCOIN_GUI_NAME "bitcoin-qt") +set(BITCOIN_DAEMON_NAME "bitcoind") +set(BITCOIN_CLI_NAME "bitcoin-cli") +set(BITCOIN_TX_NAME "bitcoin-tx") +set(BITCOIN_WALLET_TOOL_NAME "bitcoin-wallet") +set(BITCOIN_TEST_NAME "test_bitcoin") +configure_file(@PROJECT_SOURCE_DIR@/share/setup.nsi.in ${CMAKE_CURRENT_LIST_DIR}/bitcoin-win64-setup.nsi + USE_SOURCE_PERMISSIONS @ONLY +) + +execute_process( + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} + COMMAND ${MAKENSIS_EXECUTABLE} -V2 bitcoin-win64-setup.nsi + COMMAND_ERROR_IS_FATAL ANY +) diff --git a/contrib/guix/guix-attest b/contrib/guix/guix-attest index 3d70731cbdb4..06925ffbede3 100755 --- a/contrib/guix/guix-attest +++ b/contrib/guix/guix-attest @@ -1,6 +1,9 @@ #!/usr/bin/env bash -export LC_ALL=C -set -e -o pipefail +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail # Source the common prelude, which: # 1. Checks if we're at the top directory of the Bitcoin Core repository diff --git a/contrib/guix/guix-build b/contrib/guix/guix-build index 1ab9cc7e4556..9afe00a067db 100755 --- a/contrib/guix/guix-build +++ b/contrib/guix/guix-build @@ -1,6 +1,9 @@ #!/usr/bin/env bash -export LC_ALL=C -set -e -o pipefail +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail # Source the common prelude, which: # 1. Checks if we're at the top directory of the Bitcoin Core repository @@ -337,8 +340,8 @@ INFO: Building ${VERSION:?not set} for platform triple ${HOST:?not set}: ADDITIONAL_GUIX_TIMEMACHINE_FLAGS: ${ADDITIONAL_GUIX_TIMEMACHINE_FLAGS} EOF - # Run the build script 'contrib/guix/libexec/build.sh' in the build - # container specified by 'contrib/guix/manifest.scm'. + # Run the build scripts 'contrib/guix/libexec/*.sh' in the build + # containers specified by 'contrib/guix/manifest*.scm'. # # Explanation of `guix shell` flags: # @@ -403,39 +406,73 @@ EOF # substitutes (pre-built packages) from servers that the user trusts. # Please read the README.md in the same directory as this file for # more information. - # - # shellcheck disable=SC2086 - time-machine shell --manifest="${PWD}/contrib/guix/manifest_build.scm" \ - --container \ - --writable-root \ - --pure \ - --no-cwd \ - --share="$PWD"=/bitcoin \ - --share="$DISTSRC_BASE"=/distsrc-base \ - --share="$OUTDIR_BASE"=/outdir-base \ - --expose="$(git rev-parse --git-common-dir)" \ - ${SOURCES_PATH:+--share="$SOURCES_PATH"} \ - ${BASE_CACHE:+--share="$BASE_CACHE"} \ - ${SDK_PATH:+--share="$SDK_PATH"} \ - --cores="$JOBS" \ - --keep-failed \ - --fallback \ - --link-profile \ - --root="$(profiledir_for_host "${HOST}")" \ - ${SUBSTITUTE_URLS:+--substitute-urls="$SUBSTITUTE_URLS"} \ - ${ADDITIONAL_GUIX_COMMON_FLAGS} ${ADDITIONAL_GUIX_ENVIRONMENT_FLAGS} \ - -- env HOST="$host" \ - DISTNAME="$DISTNAME" \ - JOBS="$JOBS" \ - SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:?unable to determine value}" \ - ${V:+V=1} \ - ${SOURCES_PATH:+SOURCES_PATH="$SOURCES_PATH"} \ - ${BASE_CACHE:+BASE_CACHE="$BASE_CACHE"} \ - ${SDK_PATH:+SDK_PATH="$SDK_PATH"} \ - DISTSRC="$(distsrc_for_host "$HOST" "" /distsrc-base)" \ - OUTDIR="$(outdir_for_host "$HOST" "" /outdir-base)" \ - DIST_ARCHIVE_BASE=/outdir-base/dist-archive \ - bash -c "cd /bitcoin && bash contrib/guix/libexec/build.sh" + read -ra _guix_common_flags <<< "$ADDITIONAL_GUIX_COMMON_FLAGS" + read -ra _guix_env_flags <<< "$ADDITIONAL_GUIX_ENVIRONMENT_FLAGS" + + shell_opts=( + --manifest="${PWD}/contrib/guix/manifest_build.scm" + --container + --writable-root + --pure + --no-cwd + --share="$PWD=/bitcoin" + --share="$DISTSRC_BASE=/distsrc-base" + --share="$OUTDIR_BASE=/outdir-base" + --expose="$(git rev-parse --git-common-dir)" + ${SOURCES_PATH:+--share="$SOURCES_PATH"} + ${BASE_CACHE:+--share="$BASE_CACHE"} + ${SDK_PATH:+--share="$SDK_PATH"} + --cores="$JOBS" + --keep-failed + --fallback + --link-profile + ${SUBSTITUTE_URLS:+--substitute-urls="$SUBSTITUTE_URLS"} + "${_guix_common_flags[@]}" "${_guix_env_flags[@]}" + -- env HOST="$host" \ + DISTNAME="$DISTNAME" + JOBS="$JOBS" + SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:?unable to determine value}" + ${V:+V=1} + ${SOURCES_PATH:+SOURCES_PATH="$SOURCES_PATH"} + ${BASE_CACHE:+BASE_CACHE="$BASE_CACHE"} + ${SDK_PATH:+SDK_PATH="$SDK_PATH"} + DISTSRC="$(distsrc_for_host "$HOST" "" /distsrc-base)" + OUTDIR="$(outdir_for_host "$HOST" "" /outdir-base)" + DIST_ARCHIVE_BASE=/outdir-base/dist-archive + ) + + case "$HOST" in + *linux*) + time-machine shell --root="$(profiledir_for_host "${HOST}")" \ + "${shell_opts[@]}" \ + bash -c "cd /bitcoin && bash contrib/guix/libexec/build_linux.sh" + + time-machine shell --manifest="${PWD}/contrib/guix/manifest_gui.scm" \ + --root="$(profiledir_for_host "${HOST}"_gui)" \ + "${shell_opts[@]}" \ + bash -c "cd /bitcoin && bash contrib/guix/libexec/build_linux_gui.sh" + ;; + *darwin*) + time-machine shell --root="$(profiledir_for_host "${HOST}")" \ + "${shell_opts[@]}" \ + bash -c "cd /bitcoin && bash contrib/guix/libexec/build_macos.sh" + + time-machine shell --manifest="${PWD}/contrib/guix/manifest_gui.scm" \ + --root="$(profiledir_for_host "${HOST}"_gui)" \ + "${shell_opts[@]}" \ + bash -c "cd /bitcoin && bash contrib/guix/libexec/build_macos_gui.sh" + ;; + *mingw*) + time-machine shell --root="$(profiledir_for_host "${HOST}")" \ + "${shell_opts[@]}" \ + bash -c "cd /bitcoin && bash contrib/guix/libexec/build_win.sh" + + time-machine shell --manifest="${PWD}/contrib/guix/manifest_gui.scm" \ + --root="$(profiledir_for_host "${HOST}"_gui)" \ + "${shell_opts[@]}" \ + bash -c "cd /bitcoin && bash contrib/guix/libexec/build_win_gui.sh" + ;; + esac ) done diff --git a/contrib/guix/guix-clean b/contrib/guix/guix-clean index 32258cd7477e..a72a26445a8b 100755 --- a/contrib/guix/guix-clean +++ b/contrib/guix/guix-clean @@ -1,6 +1,9 @@ #!/usr/bin/env bash -export LC_ALL=C -set -e -o pipefail +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail # Source the common prelude, which: # 1. Checks if we're at the top directory of the Bitcoin Core repository diff --git a/contrib/guix/guix-codesign b/contrib/guix/guix-codesign index 8cc6993b824d..179041c140a8 100755 --- a/contrib/guix/guix-codesign +++ b/contrib/guix/guix-codesign @@ -1,6 +1,9 @@ #!/usr/bin/env bash -export LC_ALL=C -set -e -o pipefail +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail # Source the common prelude, which: # 1. Checks if we're at the top directory of the Bitcoin Core repository diff --git a/contrib/guix/guix-verify b/contrib/guix/guix-verify index 02ae022741ba..82e740036ba8 100755 --- a/contrib/guix/guix-verify +++ b/contrib/guix/guix-verify @@ -1,6 +1,9 @@ #!/usr/bin/env bash -export LC_ALL=C -set -e -o pipefail +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail # Source the common prelude, which: # 1. Checks if we're at the top directory of the Bitcoin Core repository diff --git a/contrib/guix/libexec/build.sh b/contrib/guix/libexec/build.sh deleted file mode 100755 index 0ec058b8de32..000000000000 --- a/contrib/guix/libexec/build.sh +++ /dev/null @@ -1,207 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2019-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. -export LC_ALL=C -set -e -o pipefail - -# shellcheck source=setup.sh -source "$(dirname "${BASH_SOURCE[0]}")/setup.sh" - -# Set environment variables to point the NATIVE toolchain to the right -# includes/libs -NATIVE_GCC="$(store_path gcc-toolchain)" - -# Set native toolchain -build_CC="${NATIVE_GCC}/bin/gcc -isystem ${NATIVE_GCC}/include" -build_CXX="${NATIVE_GCC}/bin/g++ -isystem ${NATIVE_GCC}/include/c++ -isystem ${NATIVE_GCC}/include" - -case "$HOST" in - *darwin*) export LIBRARY_PATH="${NATIVE_GCC}/lib" ;; # Required for native packages - *mingw*) export LIBRARY_PATH="${NATIVE_GCC}/lib" ;; - *) - NATIVE_GCC_STATIC="$(store_path gcc-toolchain static)" - export LIBRARY_PATH="${NATIVE_GCC}/lib:${NATIVE_GCC_STATIC}/lib" - ;; -esac - -# Set environment variables to point the CROSS toolchain to the right -# includes/libs for $HOST -case "$HOST" in - *mingw*) - # Determine output paths to use in CROSS_* environment variables - CROSS_GLIBC="$(store_path "mingw-w64-x86_64-winpthreads")" - CROSS_GCC="$(store_path "gcc-cross-${HOST}")" - CROSS_GCC_LIB_STORE="$(store_path "gcc-cross-${HOST}" lib)" - CROSS_GCC_LIBS=( "${CROSS_GCC_LIB_STORE}/lib/gcc/${HOST}"/* ) # This expands to an array of directories... - CROSS_GCC_LIB="${CROSS_GCC_LIBS[0]}" # ...we just want the first one (there should only be one) - - # The search path ordering is generally: - # 1. gcc-related search paths - # 2. libc-related search paths - # 2. kernel-header-related search paths (not applicable to mingw-w64 hosts) - export CROSS_C_INCLUDE_PATH="${CROSS_GCC_LIB}/include:${CROSS_GCC_LIB}/include-fixed:${CROSS_GLIBC}/include" - export CROSS_CPLUS_INCLUDE_PATH="${CROSS_GCC}/include/c++:${CROSS_GCC}/include/c++/${HOST}:${CROSS_GCC}/include/c++/backward:${CROSS_C_INCLUDE_PATH}" - export CROSS_LIBRARY_PATH="${CROSS_GCC_LIB_STORE}/lib:${CROSS_GCC_LIB}:${CROSS_GLIBC}/lib" - ;; - *darwin*) - # The CROSS toolchain for darwin uses the SDK and ignores environment variables. - # See depends/hosts/darwin.mk for more details. - ;; - *linux*) - CROSS_GLIBC="$(store_path "glibc-cross-${HOST}")" - CROSS_GLIBC_STATIC="$(store_path "glibc-cross-${HOST}" static)" - CROSS_KERNEL="$(store_path "linux-libre-headers-cross-${HOST}")" - CROSS_GCC="$(store_path "gcc-cross-${HOST}")" - CROSS_GCC_LIB_STORE="$(store_path "gcc-cross-${HOST}" lib)" - CROSS_GCC_LIBS=( "${CROSS_GCC_LIB_STORE}/lib/gcc/${HOST}"/* ) # This expands to an array of directories... - CROSS_GCC_LIB="${CROSS_GCC_LIBS[0]}" # ...we just want the first one (there should only be one) - - export CROSS_C_INCLUDE_PATH="${CROSS_GCC_LIB}/include:${CROSS_GCC_LIB}/include-fixed:${CROSS_GLIBC}/include:${CROSS_KERNEL}/include" - export CROSS_CPLUS_INCLUDE_PATH="${CROSS_GCC}/include/c++:${CROSS_GCC}/include/c++/${HOST}:${CROSS_GCC}/include/c++/backward:${CROSS_C_INCLUDE_PATH}" - export CROSS_LIBRARY_PATH="${CROSS_GCC_LIB_STORE}/lib:${CROSS_GCC_LIB}:${CROSS_GLIBC}/lib:${CROSS_GLIBC_STATIC}/lib" - ;; - *) - exit 1 ;; -esac - -# Sanity check CROSS_*_PATH directories -IFS=':' read -ra PATHS <<< "${CROSS_C_INCLUDE_PATH}:${CROSS_CPLUS_INCLUDE_PATH}:${CROSS_LIBRARY_PATH}" -for p in "${PATHS[@]}"; do - if [ -n "$p" ] && [ ! -d "$p" ]; then - echo "'$p' doesn't exist or isn't a directory... Aborting..." - exit 1 - fi -done - -# Determine the correct value for -Wl,--dynamic-linker for the current $HOST -case "$HOST" in - *linux*) - glibc_dynamic_linker=$( - case "$HOST" in - x86_64-linux-gnu) echo /lib64/ld-linux-x86-64.so.2 ;; - arm-linux-gnueabihf) echo /lib/ld-linux-armhf.so.3 ;; - aarch64-linux-gnu) echo /lib/ld-linux-aarch64.so.1 ;; - riscv64-linux-gnu) echo /lib/ld-linux-riscv64-lp64d.so.1 ;; - powerpc64-linux-gnu) echo /lib64/ld64.so.1;; - powerpc64le-linux-gnu) echo /lib64/ld64.so.2;; - *) exit 1 ;; - esac - ) - ;; -esac - -#################### -# Depends Building # -#################### - -# Build the depends tree, overriding variables that assume multilib gcc -make -C depends --jobs="$JOBS" HOST="$HOST" \ - ${V:+V=1} \ - ${SOURCES_PATH+SOURCES_PATH="$SOURCES_PATH"} \ - ${BASE_CACHE+BASE_CACHE="$BASE_CACHE"} \ - ${SDK_PATH+SDK_PATH="$SDK_PATH"} \ - ${build_CC+build_CC="$build_CC"} \ - ${build_CXX+build_CXX="$build_CXX"} \ - x86_64_linux_CC=x86_64-linux-gnu-gcc \ - x86_64_linux_CXX=x86_64-linux-gnu-g++ \ - x86_64_linux_AR=x86_64-linux-gnu-gcc-ar \ - x86_64_linux_RANLIB=x86_64-linux-gnu-gcc-ranlib \ - x86_64_linux_NM=x86_64-linux-gnu-gcc-nm \ - x86_64_linux_STRIP=x86_64-linux-gnu-strip - -case "$HOST" in - *darwin*) - # Unset now that Qt is built - unset LIBRARY_PATH - ;; -esac - -########################### -# Binary Tarball Building # -########################### - -# CONFIGFLAGS -CONFIGFLAGS="-DREDUCE_EXPORTS=ON -DBUILD_BENCH=OFF -DBUILD_GUI_TESTS=OFF -DBUILD_FUZZ_BINARY=OFF -DCMAKE_SKIP_RPATH=TRUE" - -# CFLAGS -HOST_CFLAGS="-O2 -g" -HOST_CFLAGS+=$(find /gnu/store -maxdepth 1 -mindepth 1 -type d -exec echo -n " -ffile-prefix-map={}=/usr" \;) -HOST_CFLAGS+=" -fdebug-prefix-map=${DISTSRC}/src=." -case "$HOST" in - *mingw*) HOST_CFLAGS+=" -fno-ident" ;; - *darwin*) unset HOST_CFLAGS ;; -esac - -# CXXFLAGS -HOST_CXXFLAGS="$HOST_CFLAGS" - -case "$HOST" in - arm-linux-gnueabihf) HOST_CXXFLAGS="${HOST_CXXFLAGS} -Wno-psabi" ;; -esac - -# LDFLAGS -case "$HOST" in - *linux*) HOST_LDFLAGS="-Wl,--as-needed -Wl,--dynamic-linker=$glibc_dynamic_linker -Wl,-O2" ;; - *mingw*) HOST_LDFLAGS="-Wl,--no-insert-timestamp" ;; -esac - -# EXE FLAGS -case "$HOST" in - *linux*) CMAKE_EXE_LINKER_FLAGS="-DCMAKE_EXE_LINKER_FLAGS=${HOST_LDFLAGS} -static-libstdc++ -static-libgcc" ;; -esac - -mkdir -p "$DISTSRC" -( - cd "$DISTSRC" - - # Extract the source tarball - tar --strip-components=1 -xf "${GIT_ARCHIVE}" - - # Configure this DISTSRC for $HOST - # shellcheck disable=SC2086 - env CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}" LDFLAGS="${HOST_LDFLAGS}" \ - cmake -S . -B build \ - --toolchain "${BASEPREFIX}/${HOST}/toolchain.cmake" \ - -DWITH_CCACHE=OFF \ - -Werror=dev \ - ${CONFIGFLAGS} \ - ${CMAKE_EXE_LINKER_FLAGS+"$CMAKE_EXE_LINKER_FLAGS"} - - # Build Bitcoin Core - cmake --build build -j "$JOBS" - - mkdir -p "$OUTDIR" - - # Make the os-specific installers - case "$HOST" in - *mingw*) - cmake --build build -j "$JOBS" -t deploy - mv build/bitcoin-win64-setup.exe "${OUTDIR}/${DISTNAME}-win64-setup-unsigned.exe" - ;; - esac - - # Setup the directory where our Bitcoin Core build for HOST will be - # installed. This directory will also later serve as the input for our - # binary tarballs. - mkdir -p "${INSTALLPATH}" - # Install built Bitcoin Core to $INSTALLPATH - case "$HOST" in - *darwin*) - cmake --install build --strip --prefix "${INSTALLPATH}" - ;; - *) - cmake --install build --prefix "${INSTALLPATH}" - ;; - esac - - # Perform basic security checks on installed executables. - echo "Checking binary security on installed executables..." - python3 "${DISTSRC}/contrib/guix/security-check.py" "${INSTALLPATH}/bin/"* "${INSTALLPATH}/libexec/"* - # Check that executables only contain allowed version symbols. - echo "Running symbol and dynamic library checks on installed executables..." - python3 "${DISTSRC}/contrib/guix/symbol-check.py" "${INSTALLPATH}/bin/"* "${INSTALLPATH}/libexec/"* -) # $DISTSRC - -# shellcheck source=package.sh -source "$(dirname "${BASH_SOURCE[0]}")/package.sh" diff --git a/contrib/guix/libexec/build_linux.sh b/contrib/guix/libexec/build_linux.sh new file mode 100755 index 000000000000..b84fcdde5fad --- /dev/null +++ b/contrib/guix/libexec/build_linux.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail + +# shellcheck source=setup.sh +source "$(dirname "${BASH_SOURCE[0]}")/setup.sh" + +# setup gcc toolchain +gcc_toolchain + +# Build the depends tree, overriding variables that assume multilib gcc +make -C depends --jobs="$JOBS" HOST="$HOST" \ + ${V:+V=1} \ + ${SOURCES_PATH+SOURCES_PATH="$SOURCES_PATH"} \ + ${BASE_CACHE+BASE_CACHE="$BASE_CACHE"} \ + ${build_CC+build_CC="$build_CC"} \ + ${build_CXX+build_CXX="$build_CXX"} \ + x86_64_linux_CC=x86_64-linux-gnu-gcc \ + x86_64_linux_CXX=x86_64-linux-gnu-g++ \ + x86_64_linux_AR=x86_64-linux-gnu-gcc-ar \ + x86_64_linux_RANLIB=x86_64-linux-gnu-gcc-ranlib \ + x86_64_linux_NM=x86_64-linux-gnu-gcc-nm \ + x86_64_linux_STRIP=x86_64-linux-gnu-strip \ + NO_QT=1 + +# CFLAGS +HOST_CFLAGS="-O2 -g" +HOST_CFLAGS+=$(find /gnu/store -maxdepth 1 -mindepth 1 -type d -exec echo -n " -ffile-prefix-map={}=/usr" \;) +HOST_CFLAGS+=" -fdebug-prefix-map=${DISTSRC}/src=." + +# CXXFLAGS +HOST_CXXFLAGS="$HOST_CFLAGS" + +case "$HOST" in + arm-linux-gnueabihf) HOST_CXXFLAGS="${HOST_CXXFLAGS} -Wno-psabi" ;; +esac + +# LDFLAGS +HOST_LDFLAGS="-Wl,--as-needed -Wl,--dynamic-linker=$(glibc_dynamic_linker "$HOST") -Wl,-O2" + +# Use LINK_WARNING_AS_ERROR when using CMake 4.x +case "$HOST" in + riscv64-linux-gnu) ;; # https://github.com/boostorg/test/issues/345 + *) HOST_LDFLAGS="${HOST_LDFLAGS} -Wl,--fatal-warnings" ;; +esac + +mkdir -p "$DISTSRC" +( + cd "$DISTSRC" + + # Extract the source tarball + tar --strip-components=1 -xf "${GIT_ARCHIVE}" + + # Configure this DISTSRC for $HOST + env CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}" LDFLAGS="${HOST_LDFLAGS}" \ + cmake -S . -B build \ + --toolchain "${BASEPREFIX}/${HOST}/toolchain.cmake" \ + -DBUILD_BENCH=OFF \ + -DBUILD_FUZZ_BINARY=OFF \ + -DBUILD_GUI=OFF \ + -DBUILD_GUI_TESTS=OFF \ + -DCMAKE_EXE_LINKER_FLAGS="${HOST_LDFLAGS} -static-libstdc++ -static-libgcc" \ + -DCMAKE_INSTALL_PREFIX="${INSTALLPATH}" \ + -DCMAKE_SKIP_RPATH=TRUE \ + -DREDUCE_EXPORTS=ON \ + -DWITH_CCACHE=OFF + + # Build Bitcoin Core + cmake --build build -j "$JOBS" + + # Install built Bitcoin Core + cmake --install build +) + +rm -rf "$DISTSRC"/build + +exit 0 diff --git a/contrib/guix/libexec/build_linux_gui.sh b/contrib/guix/libexec/build_linux_gui.sh new file mode 100755 index 000000000000..f069d4b4f1b4 --- /dev/null +++ b/contrib/guix/libexec/build_linux_gui.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail + +# shellcheck source=setup.sh +source "$(dirname "${BASH_SOURCE[0]}")/setup.sh" + +# setup gcc toolchain +gcc_toolchain + +# Build the depends tree, overriding variables that assume multilib gcc +make -C depends --jobs="$JOBS" HOST="$HOST" \ + ${V:+V=1} \ + ${SOURCES_PATH+SOURCES_PATH="$SOURCES_PATH"} \ + ${BASE_CACHE+BASE_CACHE="$BASE_CACHE"} \ + ${build_CC+build_CC="$build_CC"} \ + ${build_CXX+build_CXX="$build_CXX"} \ + x86_64_linux_CC=x86_64-linux-gnu-gcc \ + x86_64_linux_CXX=x86_64-linux-gnu-g++ \ + x86_64_linux_AR=x86_64-linux-gnu-gcc-ar \ + x86_64_linux_RANLIB=x86_64-linux-gnu-gcc-ranlib \ + x86_64_linux_NM=x86_64-linux-gnu-gcc-nm \ + x86_64_linux_STRIP=x86_64-linux-gnu-strip + +# CFLAGS +HOST_CFLAGS="-O2 -g" +HOST_CFLAGS+=$(find /gnu/store -maxdepth 1 -mindepth 1 -type d -exec echo -n " -ffile-prefix-map={}=/usr" \;) +HOST_CFLAGS+=" -fdebug-prefix-map=${DISTSRC}/src=." + +# CXXFLAGS +HOST_CXXFLAGS="$HOST_CFLAGS" + +case "$HOST" in + arm-linux-gnueabihf) HOST_CXXFLAGS="${HOST_CXXFLAGS} -Wno-psabi" ;; +esac + +# LDFLAGS +HOST_LDFLAGS="-Wl,--as-needed -Wl,--dynamic-linker=$(glibc_dynamic_linker "$HOST") -Wl,-O2" + +mkdir -p "$DISTSRC" +( + cd "$DISTSRC" + + # Extract the source tarball + tar --strip-components=1 -xf "${GIT_ARCHIVE}" + + # Configure this DISTSRC for $HOST + env CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}" LDFLAGS="${HOST_LDFLAGS}" \ + cmake -S . -B build \ + --toolchain "${BASEPREFIX}/${HOST}/toolchain.cmake" \ + -DBUILD_BENCH=OFF \ + -DBUILD_BITCOIN_BIN=OFF \ + -DBUILD_CLI=OFF \ + -DBUILD_DAEMON=OFF \ + -DBUILD_FUZZ_BINARY=OFF \ + -DBUILD_GUI_TESTS=OFF \ + -DBUILD_TESTS=OFF \ + -DBUILD_TX=OFF \ + -DBUILD_UTIL=OFF \ + -DBUILD_WALLET_TOOL=OFF \ + -DCMAKE_EXE_LINKER_FLAGS="${HOST_LDFLAGS} -static-libstdc++ -static-libgcc" \ + -DCMAKE_INSTALL_PREFIX="${INSTALLPATH}" \ + -DCMAKE_SKIP_RPATH=TRUE \ + -DREDUCE_EXPORTS=ON \ + -DWITH_CCACHE=OFF \ + -Werror=dev + + # Build Bitcoin Core + cmake --build build -j "$JOBS" --target bitcoin-gui bitcoin-qt + + # Install built Bitcoin Core + cmake --install build --component bitcoin-gui + cmake --install build --component bitcoin-qt +) # $DISTSRC + +# shellcheck source=package.sh +source "$(dirname "${BASH_SOURCE[0]}")/package.sh" diff --git a/contrib/guix/libexec/build_macos.sh b/contrib/guix/libexec/build_macos.sh new file mode 100755 index 000000000000..a782d80ed622 --- /dev/null +++ b/contrib/guix/libexec/build_macos.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail + +# shellcheck source=setup.sh +source "$(dirname "${BASH_SOURCE[0]}")/setup.sh" + +# Setup toolchain +llvm_toolchain + +# Build the depends tree +make -C depends --jobs="$JOBS" HOST="$HOST" \ + ${V:+V=1} \ + ${SOURCES_PATH+SOURCES_PATH="$SOURCES_PATH"} \ + ${BASE_CACHE+BASE_CACHE="$BASE_CACHE"} \ + ${SDK_PATH+SDK_PATH="$SDK_PATH"} \ + ${build_CC+build_CC="$build_CC"} \ + ${build_CXX+build_CXX="$build_CXX"} \ + ${build_LDFLAGS+build_LDFLAGS="$build_LDFLAGS"} \ + ${build_AR+build_AR="$build_AR"} \ + ${build_RANLIB+build_RANLIB="$build_RANLIB"} \ + ${build_OBJDUMP+build_OBJDUMP="$build_OBJDUMP"} \ + ${build_NM+build_NM="$build_NM"} \ + ${build_STRIP+build_STRIP="$build_STRIP"} \ + NO_QT=1 + +mkdir -p "$DISTSRC" +( + cd "$DISTSRC" + + # Extract the source tarball + tar --strip-components=1 -xf "${GIT_ARCHIVE}" + + # Configure this DISTSRC for $HOST + env cmake -S . -B build \ + --toolchain "${BASEPREFIX}/${HOST}/toolchain.cmake" \ + -DBUILD_BENCH=OFF \ + -DBUILD_FUZZ_BINARY=OFF \ + -DBUILD_GUI=OFF \ + -DBUILD_GUI_TESTS=OFF \ + -DCMAKE_INSTALL_PREFIX="${INSTALLPATH}" \ + -DCMAKE_SKIP_RPATH=TRUE \ + -DREDUCE_EXPORTS=ON \ + -DWITH_CCACHE=OFF + + # Build Bitcoin Core + cmake --build build -j "$JOBS" + + # Install built Bitcoin Core + cmake --install build --strip +) + +rm -rf "$DISTSRC"/build + +exit 0 diff --git a/contrib/guix/libexec/build_macos_gui.sh b/contrib/guix/libexec/build_macos_gui.sh new file mode 100755 index 000000000000..1f2dbc6468df --- /dev/null +++ b/contrib/guix/libexec/build_macos_gui.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail + +# shellcheck source=setup.sh +source "$(dirname "${BASH_SOURCE[0]}")/setup.sh" + +# Setup toolchain +llvm_toolchain + +# Build the depends tree +make -C depends --jobs="$JOBS" HOST="$HOST" \ + ${V:+V=1} \ + ${SOURCES_PATH+SOURCES_PATH="$SOURCES_PATH"} \ + ${BASE_CACHE+BASE_CACHE="$BASE_CACHE"} \ + ${SDK_PATH+SDK_PATH="$SDK_PATH"} \ + ${build_CC+build_CC="$build_CC"} \ + ${build_CXX+build_CXX="$build_CXX"} \ + ${build_LDFLAGS+build_LDFLAGS="$build_LDFLAGS"} \ + ${build_AR+build_AR="$build_AR"} \ + ${build_RANLIB+build_RANLIB="$build_RANLIB"} \ + ${build_OBJDUMP+build_OBJDUMP="$build_OBJDUMP"} \ + ${build_NM+build_NM="$build_NM"} \ + ${build_STRIP+build_STRIP="$build_STRIP"} + +mkdir -p "$DISTSRC" +( + cd "$DISTSRC" + + # Extract the source tarball + tar --strip-components=1 -xf "${GIT_ARCHIVE}" + + # Configure this DISTSRC for $HOST + env cmake -S . -B build \ + --toolchain "${BASEPREFIX}/${HOST}/toolchain.cmake" \ + -DBUILD_BENCH=OFF \ + -DBUILD_BITCOIN_BIN=OFF \ + -DBUILD_CLI=OFF \ + -DBUILD_DAEMON=OFF \ + -DBUILD_FUZZ_BINARY=OFF \ + -DBUILD_GUI_TESTS=OFF \ + -DBUILD_TESTS=OFF \ + -DBUILD_TX=OFF \ + -DBUILD_UTIL=OFF \ + -DBUILD_WALLET_TOOL=OFF \ + -DCMAKE_INSTALL_PREFIX="${INSTALLPATH}" \ + -DCMAKE_SKIP_RPATH=TRUE \ + -DREDUCE_EXPORTS=ON \ + -DWITH_CCACHE=OFF \ + -Werror=dev + + # Build Bitcoin Core + cmake --build build -j "$JOBS" --target bitcoin-gui bitcoin-qt + + # Install built Bitcoin Core + cmake --install build --strip --component bitcoin-gui + cmake --install build --strip --component bitcoin-qt +) + +# shellcheck source=package.sh +source "$(dirname "${BASH_SOURCE[0]}")/package.sh" diff --git a/contrib/guix/libexec/build_win.sh b/contrib/guix/libexec/build_win.sh new file mode 100755 index 000000000000..7dd6e9fc36d1 --- /dev/null +++ b/contrib/guix/libexec/build_win.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail + +# shellcheck source=setup.sh +source "$(dirname "${BASH_SOURCE[0]}")/setup.sh" + +# setup mingw-w64 toolchain +mingw_w64_toolchain + +# Build the depends tree +make -C depends --jobs="$JOBS" HOST="$HOST" \ + ${V:+V=1} \ + ${SOURCES_PATH+SOURCES_PATH="$SOURCES_PATH"} \ + ${BASE_CACHE+BASE_CACHE="$BASE_CACHE"} \ + ${build_CC+build_CC="$build_CC"} \ + ${build_CXX+build_CXX="$build_CXX"} \ + NO_QT=1 + +# CFLAGS +HOST_CFLAGS="-O2 -g" +HOST_CFLAGS+=$(find /gnu/store -maxdepth 1 -mindepth 1 -type d -exec echo -n " -ffile-prefix-map={}=/usr" \;) +HOST_CFLAGS+=" -fdebug-prefix-map=${DISTSRC}/src=." +HOST_CFLAGS+=" -fno-ident" + +# CXXFLAGS +HOST_CXXFLAGS="$HOST_CFLAGS" + +# LDFLAGS +HOST_LDFLAGS="-Wl,--no-insert-timestamp -Wl,--fatal-warnings" + +mkdir -p "$DISTSRC" +( + cd "$DISTSRC" + + # Extract the source tarball + tar --strip-components=1 -xf "${GIT_ARCHIVE}" + + # Configure this DISTSRC for $HOST + env CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}" LDFLAGS="${HOST_LDFLAGS}" \ + cmake -S . -B build \ + --toolchain "${BASEPREFIX}/${HOST}/toolchain.cmake" \ + -DBUILD_BENCH=OFF \ + -DBUILD_FUZZ_BINARY=OFF \ + -DBUILD_GUI=OFF \ + -DBUILD_GUI_TESTS=OFF \ + -DCMAKE_INSTALL_PREFIX="${INSTALLPATH}" \ + -DREDUCE_EXPORTS=ON \ + -DWITH_CCACHE=OFF + + # Build Bitcoin Core + cmake --build build -j "$JOBS" + + # Install built Bitcoin Core + cmake --install build +) + +rm -rf "$DISTSRC"/build + +exit 0 diff --git a/contrib/guix/libexec/build_win_gui.sh b/contrib/guix/libexec/build_win_gui.sh new file mode 100755 index 000000000000..65696a2fb431 --- /dev/null +++ b/contrib/guix/libexec/build_win_gui.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail + +# shellcheck source=setup.sh +source "$(dirname "${BASH_SOURCE[0]}")/setup.sh" + +# setup mingw-w64 toolchain +mingw_w64_toolchain + +# Build the depends tree +make -C depends --jobs="$JOBS" HOST="$HOST" \ + ${V:+V=1} \ + ${SOURCES_PATH+SOURCES_PATH="$SOURCES_PATH"} \ + ${BASE_CACHE+BASE_CACHE="$BASE_CACHE"} \ + ${build_CC+build_CC="$build_CC"} \ + ${build_CXX+build_CXX="$build_CXX"} + +# CFLAGS +HOST_CFLAGS="-O2 -g" +HOST_CFLAGS+=$(find /gnu/store -maxdepth 1 -mindepth 1 -type d -exec echo -n " -ffile-prefix-map={}=/usr" \;) +HOST_CFLAGS+=" -fdebug-prefix-map=${DISTSRC}/src=." +HOST_CFLAGS+=" -fno-ident" + +# CXXFLAGS +HOST_CXXFLAGS="$HOST_CFLAGS" + +# LDFLAGS +HOST_LDFLAGS="-Wl,--no-insert-timestamp -Wl,--fatal-warnings" + +mkdir -p "$DISTSRC" +( + cd "$DISTSRC" + + # Extract the source tarball + tar --strip-components=1 -xf "${GIT_ARCHIVE}" + + # Configure this DISTSRC for $HOST + env CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}" LDFLAGS="${HOST_LDFLAGS}" \ + cmake -S . -B build \ + --toolchain "${BASEPREFIX}/${HOST}/toolchain.cmake" \ + -DBUILD_BENCH=OFF \ + -DBUILD_BITCOIN_BIN=OFF \ + -DBUILD_CLI=OFF \ + -DBUILD_DAEMON=OFF \ + -DBUILD_FUZZ_BINARY=OFF \ + -DBUILD_GUI_TESTS=OFF \ + -DBUILD_TESTS=OFF \ + -DBUILD_TX=OFF \ + -DBUILD_UTIL=OFF \ + -DBUILD_WALLET_TOOL=OFF \ + -DCMAKE_INSTALL_PREFIX="${INSTALLPATH}" \ + -DREDUCE_EXPORTS=ON \ + -DWITH_CCACHE=OFF \ + -Werror=dev + + # Build Bitcoin Core + cmake --build build -j "$JOBS" --target bitcoin-qt + + # Install built Bitcoin Core + cmake --install build --component bitcoin-qt +) + +# shellcheck source=package.sh +source "$(dirname "${BASH_SOURCE[0]}")/package.sh" diff --git a/contrib/guix/libexec/codesign.sh b/contrib/guix/libexec/codesign.sh index 9b7f085d3ab9..21f4c110661f 100755 --- a/contrib/guix/libexec/codesign.sh +++ b/contrib/guix/libexec/codesign.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -# Copyright (c) 2021-present The Bitcoin Core developers +# Copyright (c) The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. -export LC_ALL=C -set -e -o pipefail +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail # Environment variables for determinism export TAR_OPTIONS="--owner=0 --group=0 --numeric-owner --mtime='@${SOURCE_DATE_EPOCH}' --sort=name" diff --git a/contrib/guix/libexec/package.sh b/contrib/guix/libexec/package.sh index 7228346abe7a..05f5e61f744c 100755 --- a/contrib/guix/libexec/package.sh +++ b/contrib/guix/libexec/package.sh @@ -2,12 +2,19 @@ # Copyright (c) The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or https://opensource.org/license/mit. -export LC_ALL=C -set -e -o pipefail +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail ( cd "$DISTSRC" + # Perform basic security checks on installed executables. + echo "Checking binary security on installed executables..." + python3 "${DISTSRC}/contrib/guix/security-check.py" "${INSTALLPATH}/bin/"* "${INSTALLPATH}/libexec/"* + # Check that executables only contain allowed version symbols. + echo "Running symbol and dynamic library checks on installed executables..." + python3 "${DISTSRC}/contrib/guix/symbol-check.py" "${INSTALLPATH}/bin/"* "${INSTALLPATH}/libexec/"* + ( cd installed @@ -32,7 +39,7 @@ set -e -o pipefail esac # copy over the example bitcoin.conf file. if contrib/devtools/gen-bitcoin-conf.sh - # has not been run before buildling, this file will be a stub + # has not been run before building, this file will be a stub cp "${DISTSRC}/share/examples/bitcoin.conf" "${DISTNAME}/" cp -r "${DISTSRC}/share/rpcauth" "${DISTNAME}/share/" @@ -79,6 +86,10 @@ set -e -o pipefail # Finally make tarballs for codesigning case "$HOST" in *mingw*) + # Make the installer + cmake -D BIN_DIR="${INSTALLPATH}/bin" -D LIBEXEC_DIR="${INSTALLPATH}/libexec" -P build/GenerateWindowsInstaller.cmake + mv build/bitcoin-win64-setup.exe "${OUTDIR}/${DISTNAME}-win64-setup-unsigned.exe" + cp -rf --target-directory=. contrib/windeploy ( cd ./windeploy diff --git a/contrib/guix/libexec/prelude.bash b/contrib/guix/libexec/prelude.bash index 238527678979..2fe5c73867ee 100644 --- a/contrib/guix/libexec/prelude.bash +++ b/contrib/guix/libexec/prelude.bash @@ -1,6 +1,9 @@ #!/usr/bin/env bash -export LC_ALL=C -set -e -o pipefail +# Copyright (c) The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail source contrib/shell/realpath.bash source contrib/shell/git-utils.bash diff --git a/contrib/guix/libexec/setup.sh b/contrib/guix/libexec/setup.sh index 37388f985538..2e3eb159838b 100755 --- a/contrib/guix/libexec/setup.sh +++ b/contrib/guix/libexec/setup.sh @@ -2,8 +2,8 @@ # Copyright (c) The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or https://opensource.org/license/mit. -export LC_ALL=C -set -e -o pipefail +export LC_ALL=C.UTF-8 +set -o errexit -o pipefail # Environment variables for determinism export TAR_OPTIONS="--no-same-owner --owner=0 --group=0 --numeric-owner --mtime='@${SOURCE_DATE_EPOCH}' --sort=name" @@ -61,6 +61,109 @@ store_path() { --expression='s|"[[:space:]]*$||' } +# Sanity check CROSS_*_PATH directories +check_cross_paths() { + local p paths + IFS=':' read -ra paths <<< "$1" + for p in "${paths[@]}"; do + if [ -n "$p" ] && [ ! -d "$p" ]; then + echo "'$p' doesn't exist or isn't a directory... Aborting..." >&2 + return 1 + fi + done +} + +# Given a hostname, determine the correct value for -Wl,--dynamic-linker. +glibc_dynamic_linker() { + case "$1" in + x86_64-linux-gnu) echo /lib64/ld-linux-x86-64.so.2 ;; + arm-linux-gnueabihf) echo /lib/ld-linux-armhf.so.3 ;; + aarch64-linux-gnu) echo /lib/ld-linux-aarch64.so.1 ;; + riscv64-linux-gnu) echo /lib/ld-linux-riscv64-lp64d.so.1 ;; + powerpc64-linux-gnu) echo /lib64/ld64.so.1 ;; + powerpc64le-linux-gnu) echo /lib64/ld64.so.2 ;; + *) exit 1 ;; + esac +} + +gcc_toolchain() { + # Set environment variables to point the NATIVE toolchain to the right + # includes/libs + local NATIVE_GCC NATIVE_GCC_STATIC CROSS_GLIBC CROSS_GLIBC_STATIC CROSS_KERNEL CROSS_GCC CROSS_GCC_LIB_STORE CROSS_GCC_LIBS CROSS_GCC_LIB + + NATIVE_GCC="$(store_path gcc-toolchain)" + + # Set native toolchain + export build_CC="${NATIVE_GCC}/bin/gcc -isystem ${NATIVE_GCC}/include" + export build_CXX="${NATIVE_GCC}/bin/g++ -isystem ${NATIVE_GCC}/include/c++ -isystem ${NATIVE_GCC}/include" + + NATIVE_GCC_STATIC="$(store_path gcc-toolchain static)" + export LIBRARY_PATH="${NATIVE_GCC}/lib:${NATIVE_GCC_STATIC}/lib" + + # Set environment variables to point the CROSS toolchain to the right + # includes/libs for $HOST + CROSS_GLIBC="$(store_path "glibc-cross-${HOST}")" + CROSS_GLIBC_STATIC="$(store_path "glibc-cross-${HOST}" static)" + CROSS_KERNEL="$(store_path "linux-libre-headers-cross-${HOST}")" + CROSS_GCC="$(store_path "gcc-cross-${HOST}")" + CROSS_GCC_LIB_STORE="$(store_path "gcc-cross-${HOST}" lib)" + CROSS_GCC_LIBS=( "${CROSS_GCC_LIB_STORE}/lib/gcc/${HOST}"/* ) # This expands to an array of directories... + CROSS_GCC_LIB="${CROSS_GCC_LIBS[0]}" # ...we just want the first one (there should only be one) + + export CROSS_C_INCLUDE_PATH="${CROSS_GCC_LIB}/include:${CROSS_GCC_LIB}/include-fixed:${CROSS_GLIBC}/include:${CROSS_KERNEL}/include" + export CROSS_CPLUS_INCLUDE_PATH="${CROSS_GCC}/include/c++:${CROSS_GCC}/include/c++/${HOST}:${CROSS_GCC}/include/c++/backward:${CROSS_C_INCLUDE_PATH}" + export CROSS_LIBRARY_PATH="${CROSS_GCC_LIB_STORE}/lib:${CROSS_GCC_LIB}:${CROSS_GLIBC}/lib:${CROSS_GLIBC_STATIC}/lib" + + check_cross_paths "${CROSS_C_INCLUDE_PATH}:${CROSS_CPLUS_INCLUDE_PATH}:${CROSS_LIBRARY_PATH}" +} + +llvm_toolchain() { + local CLANG_TOOLCHAIN LIB_CXX + + CLANG_TOOLCHAIN="$(store_path clang-toolchain)" + LIB_CXX="$(store_path libcxx)" + + export build_CC="${CLANG_TOOLCHAIN}/bin/clang -isystem ${CLANG_TOOLCHAIN}/include" + export build_CXX="${CLANG_TOOLCHAIN}/bin/clang++ -stdlib=libc++ -isystem ${LIB_CXX}/include/c++/v1 -isystem ${CLANG_TOOLCHAIN}/include" + export build_LDFLAGS="-fuse-ld=lld -rtlib=compiler-rt -unwindlib=libunwind -L${LIB_CXX}/lib -Wl,-rpath,${LIB_CXX}/lib" + export build_AR="${CLANG_TOOLCHAIN}/bin/llvm-ar" + export build_RANLIB="${CLANG_TOOLCHAIN}/bin/llvm-ranlib" + export build_OBJDUMP="${CLANG_TOOLCHAIN}/bin/llvm-objdump" + export build_NM="${CLANG_TOOLCHAIN}/bin/llvm-nm" + export build_STRIP="${CLANG_TOOLCHAIN}/bin/llvm-strip" +} + +mingw_w64_toolchain() { + # Set environment variables to point the NATIVE toolchain to the right + # includes/libs + local NATIVE_GCC CROSS_GLIBC CROSS_GCC CROSS_GCC_LIB_STORE CROSS_GCC_LIBS CROSS_GCC_LIB + + NATIVE_GCC="$(store_path gcc-toolchain)" + + # Set native toolchain + export build_CC="${NATIVE_GCC}/bin/gcc -isystem ${NATIVE_GCC}/include" + export build_CXX="${NATIVE_GCC}/bin/g++ -isystem ${NATIVE_GCC}/include/c++ -isystem ${NATIVE_GCC}/include" + + # Set environment variables to point the CROSS toolchain to the right + # includes/libs for $HOST + # Determine output paths to use in CROSS_* environment variables + CROSS_GLIBC="$(store_path "mingw-w64-x86_64-winpthreads")" + CROSS_GCC="$(store_path "gcc-cross-${HOST}")" + CROSS_GCC_LIB_STORE="$(store_path "gcc-cross-${HOST}" lib)" + CROSS_GCC_LIBS=( "${CROSS_GCC_LIB_STORE}/lib/gcc/${HOST}"/* ) # This expands to an array of directories... + CROSS_GCC_LIB="${CROSS_GCC_LIBS[0]}" # ...we just want the first one (there should only be one) + + # The search path ordering is generally: + # 1. gcc-related search paths + # 2. libc-related search paths + # 2. kernel-header-related search paths (not applicable to mingw-w64 hosts) + export CROSS_C_INCLUDE_PATH="${CROSS_GCC_LIB}/include:${CROSS_GCC_LIB}/include-fixed:${CROSS_GLIBC}/include" + export CROSS_CPLUS_INCLUDE_PATH="${CROSS_GCC}/include/c++:${CROSS_GCC}/include/c++/${HOST}:${CROSS_GCC}/include/c++/backward:${CROSS_C_INCLUDE_PATH}" + export CROSS_LIBRARY_PATH="${CROSS_GCC_LIB_STORE}/lib:${CROSS_GCC_LIB}:${CROSS_GLIBC}/lib" + + check_cross_paths "${CROSS_C_INCLUDE_PATH}:${CROSS_CPLUS_INCLUDE_PATH}:${CROSS_LIBRARY_PATH}" +} + # Disable Guix ld auto-rpath behavior export GUIX_LD_WRAPPER_DISABLE_RPATH=yes diff --git a/contrib/guix/manifest_build.scm b/contrib/guix/manifest_build.scm index 576021e60d7f..33d11b9cf82b 100644 --- a/contrib/guix/manifest_build.scm +++ b/contrib/guix/manifest_build.scm @@ -1,26 +1,18 @@ (use-modules (gnu packages) ((gnu packages bash) #:select (bash-minimal)) - (gnu packages bison) ((gnu packages cmake) #:select (cmake-minimal)) (gnu packages commencement) - ((gnu packages compression) #:select (gzip xz zip)) + ((gnu packages compression) #:select (gzip)) (gnu packages cross-base) - (gnu packages gawk) (gnu packages gcc) - ((gnu packages installers) #:select (nsis-x86_64)) ((gnu packages linux) #:select (linux-libre-headers-6.1)) (gnu packages llvm) (gnu packages mingw) - (gnu packages ninja) - (gnu packages pkg-config) - ((gnu packages python) #:select (python-minimal)) - ((gnu packages python-xyz) #:select (python-lief)) ((gnu packages version-control) #:select (git-minimal)) (guix build-system trivial) (guix download) (guix gexp) (guix git-download) - ((guix licenses) #:prefix license:) (guix packages) ((guix utils) #:select (substitute-keyword-arguments))) @@ -171,14 +163,18 @@ chain for " target " development.")) (arguments (substitute-keyword-arguments (package-arguments base-gcc) ((#:configure-flags flags) - `(append ,flags + #~(append #$flags ;; 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))))))) + (list "--enable-default-ssp=yes" + "--enable-gprofng=no" + "--enable-host-bind-now=yes" + "--enable-threads=posix" + "--disable-gcov" + "--disable-libgomp" + "--disable-libsanitizer" + "--disable-lto" + "--disable-nls" + #$building-on))))))) (define-public linux-base-gcc (package @@ -186,22 +182,25 @@ chain for " target " development.")) (arguments (substitute-keyword-arguments (package-arguments base-gcc) ((#:configure-flags flags) - `(append ,flags + #~(append #$flags ;; https://gcc.gnu.org/install/configure.html - (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))) + (list "--enable-cet=yes" + "--enable-default-ssp=yes" + "--enable-default-pie=yes" + "--enable-gprofng=no" + "--enable-host-bind-now=yes" + "--enable-initfini-array=yes" + "--enable-standard-branch-protection=yes" + "--disable-gcov" + "--disable-libgomp" + "--disable-libquadmath" + "--disable-libsanitizer" + "--disable-lto" + "--disable-nls" + "--disable-tm-clone-registry" + #$building-on))) ((#:phases phases) - `(modify-phases ,phases + #~(modify-phases #$phases ;; Given a XGCC package, return a modified package that replace each instance of ;; -rpath in the default system spec that's inserted by Guix with -rpath-link (add-after 'pre-configure 'replace-rpath-with-rpath-link @@ -215,7 +214,7 @@ chain for " target " development.")) (define-public glibc-2.31 (let ((commit "28eb5caf895ced5d895cb02757e109004a2d33e5")) (package - (inherit glibc) ;; 2.39 + (inherit glibc) ;; 2.41 (version "2.31") (source (origin (method git-fetch) @@ -262,40 +261,28 @@ chain for " target " development.")) coreutils-minimal ;; File(system) inspection grep - diffutils findutils ;; File transformation patch - gawk sed ;; Compression and archiving tar gzip - xz ;; Build tools - gcc-toolchain-14 cmake-minimal gnu-make - ninja - ;; Scripting - python-minimal ;; (3.11) ;; Git - git-minimal - ;; Tests - python-lief) + git-minimal) (let ((target (getenv "HOST"))) (cond ((string-suffix? "-mingw32" target) - (list (make-mingw-pthreads-cross-toolchain "x86_64-w64-mingw32") - nsis-x86_64 - zip)) + (list gcc-toolchain-14 + (make-mingw-pthreads-cross-toolchain target))) ((string-contains target "-linux-") - (list bison - pkg-config + (list gcc-toolchain-14 (list gcc-toolchain-14 "static") (make-bitcoin-cross-toolchain target))) ((string-contains target "darwin") (list clang-toolchain-19 - lld-19 - (make-lld-wrapper lld-19 #:lld-as-ld? #t) - zip)) + libcxx ;; 19.1.7 + lld-19)) (else '()))))) diff --git a/contrib/guix/manifest_gui.scm b/contrib/guix/manifest_gui.scm new file mode 100644 index 000000000000..1754af909e83 --- /dev/null +++ b/contrib/guix/manifest_gui.scm @@ -0,0 +1,30 @@ +(use-modules (gnu packages bison) + ((gnu packages compression) #:select (xz zip)) + (gnu packages gawk) + ((gnu packages installers) #:select (nsis-x86_64)) + (gnu packages ninja) + (gnu packages pkg-config) + ((gnu packages python) #:select (python-minimal)) + ((gnu packages python-xyz) #:select (python-lief))) + +(packages->manifest + (append + (list ;; Compression and archiving + xz + ;; Build tools + ninja + ;; Packaging scripts + python-minimal ;; (3.11) + ;; Tests + python-lief) + (let ((target (getenv "HOST"))) + (cond ((string-suffix? "-mingw32" target) + (list zip + nsis-x86_64)) + ((string-contains target "-linux-") + (list bison + gawk + pkg-config)) + ((string-contains target "darwin") + (list zip)) + (else '()))))) diff --git a/contrib/guix/security-check.py b/contrib/guix/security-check.py index 2a6e26b6b7f0..87aafcb945ae 100755 --- a/contrib/guix/security-check.py +++ b/contrib/guix/security-check.py @@ -280,8 +280,8 @@ def check_MACHO_BRANCH_PROTECTION(binary) -> bool: for filename in sys.argv[1:]: binary = lief.parse(filename) - etype = binary.format - arch = binary.abstract.header.architecture + etype = binary.format # type: ignore[union-attr] + arch = binary.abstract.header.architecture # type: ignore[union-attr] failed: list[str] = [] for (name, func) in CHECKS[etype][arch]: diff --git a/contrib/guix/symbol-check.py b/contrib/guix/symbol-check.py index 86b7965277c9..8c313e3d6bfa 100755 --- a/contrib/guix/symbol-check.py +++ b/contrib/guix/symbol-check.py @@ -306,7 +306,7 @@ def check_ELF_ABI(binary) -> bool: for filename in sys.argv[1:]: binary = lief.parse(filename) - etype = binary.format + etype = binary.format # type: ignore[union-attr] failed: list[str] = [] for (name, func) in CHECKS[etype]: diff --git a/depends/packages/native_qt.mk b/depends/packages/native_qt.mk index 2bf088c10aca..c975c1e9aba5 100644 --- a/depends/packages/native_qt.mk +++ b/depends/packages/native_qt.mk @@ -94,6 +94,7 @@ $(package)_config_env += OBJCXX="$$(build_CXX)" endif $(package)_cmake_opts := -DCMAKE_EXE_LINKER_FLAGS="$$(build_LDFLAGS)" +$(package)_cmake_opts += -DCMAKE_AR="$$(build_AR)" ifneq ($(V),) $(package)_cmake_opts += --log-level=STATUS endif diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 500a2729faa5..a88902df8c7e 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -14,7 +14,6 @@ $(package)_patches_path := $(qt_details_patches_path) $(package)_patches := cocoa_compat.patch $(package)_patches += dont_hardcode_pwd.patch $(package)_patches += qtbase_avoid_qmain.patch -$(package)_patches += qtbase_platformsupport.patch $(package)_patches += qtbase_plugins_cocoa.patch $(package)_patches += qtbase_skip_tools.patch $(package)_patches += rcc_hardcode_timestamp.patch @@ -181,7 +180,11 @@ $(package)_cmake_opts += --log-level=STATUS endif $(package)_cmake_opts += -DQT_USE_DEFAULT_CMAKE_OPTIMIZATION_FLAGS=ON -$(package)_cmake_opts += -DCMAKE_C_FLAGS="$$($(package)_cppflags) $$($$($(package)_type)_CFLAGS) -ffile-prefix-map=$$($(package)_extract_dir)=/usr" +# The bundled libpng 1.6.49 in Qt 6.8.4 introduced support for +# the RISC-V Vector Extension (RVV). However, the resulting library +# fails to link when cross-compiling for riscv64-linux-gnu. +# Disable this feature for now. +$(package)_cmake_opts += -DCMAKE_C_FLAGS="$$($(package)_cppflags) -DPNG_RISCV_RVV_OPT=0 $$($$($(package)_type)_CFLAGS) -ffile-prefix-map=$$($(package)_extract_dir)=/usr" $(package)_cmake_opts += -DCMAKE_C_FLAGS_RELEASE="$$($$($(package)_type)_release_CFLAGS)" $(package)_cmake_opts += -DCMAKE_C_FLAGS_DEBUG="$$($$($(package)_type)_debug_CFLAGS)" $(package)_cmake_opts += -DCMAKE_CXX_FLAGS="$$($(package)_cppflags) $$($$($(package)_type)_CXXFLAGS) -ffile-prefix-map=$$($(package)_extract_dir)=/usr" @@ -198,6 +201,7 @@ endif $(package)_cmake_opts += -DCMAKE_EXE_LINKER_FLAGS="$$($$($(package)_type)_LDFLAGS)" $(package)_cmake_opts += -DCMAKE_EXE_LINKER_FLAGS_RELEASE="$$($$($(package)_type)_release_LDFLAGS)" $(package)_cmake_opts += -DCMAKE_EXE_LINKER_FLAGS_DEBUG="$$($$($(package)_type)_debug_LDFLAGS)" +$(package)_cmake_opts += -DCMAKE_AR="$$($(package)_ar)" ifneq ($(host),$(build)) $(package)_cmake_opts += -DCMAKE_SYSTEM_NAME=$($(host_os)_cmake_system_name) @@ -277,7 +281,6 @@ define $(package)_preprocess_cmds patch -p1 -i $($(package)_patch_dir)/cocoa_compat.patch && \ patch -p1 -i $($(package)_patch_dir)/dont_hardcode_pwd.patch && \ patch -p1 -i $($(package)_patch_dir)/qtbase_avoid_qmain.patch && \ - patch -p1 -i $($(package)_patch_dir)/qtbase_platformsupport.patch && \ patch -p1 -i $($(package)_patch_dir)/qtbase_plugins_cocoa.patch && \ patch -p1 -i $($(package)_patch_dir)/qtbase_skip_tools.patch && \ patch -p1 -i $($(package)_patch_dir)/rcc_hardcode_timestamp.patch && \ diff --git a/depends/packages/qt_details.mk b/depends/packages/qt_details.mk index e49ac6a28776..1808f342a2b6 100644 --- a/depends/packages/qt_details.mk +++ b/depends/packages/qt_details.mk @@ -1,19 +1,19 @@ -qt_details_version := 6.8.3 +qt_details_version := 6.8.4 qt_details_download_path := https://download.qt.io/archive/qt/6.8/$(qt_details_version)/submodules -qt_details_suffix := everywhere-src-$(qt_details_version).tar.xz +qt_details_suffix := everywhere-opensource-src-$(qt_details_version).tar.xz qt_details_qtbase_file_name := qtbase-$(qt_details_suffix) -qt_details_qtbase_sha256_hash := 56001b905601bb9023d399f3ba780d7fa940f3e4861e496a7c490331f49e0b80 +qt_details_qtbase_sha256_hash := 532dfbf3fa3cbc68fa37441ea9e81c5009da044eaecda78ffaeafd8bd125532f qt_details_qttranslations_file_name := qttranslations-$(qt_details_suffix) -qt_details_qttranslations_sha256_hash := c3c61d79c3d8fe316a20b3617c64673ce5b5519b2e45535f49bee313152fa531 +qt_details_qttranslations_sha256_hash := 33b1fd1d75598cbf54da12263957f18292c9fb01e42fcc3ab9bd2f8ac79763b7 qt_details_qttools_file_name := qttools-$(qt_details_suffix) -qt_details_qttools_sha256_hash := 02a4e219248b94f1333df843d25763f35251c1074cdc4fb5bda67d340f8c8b3a +qt_details_qttools_sha256_hash := c6030ea66d7be1ca7e3b40578beb35b0f4ff4014277d8e051d3219759f6ab399 qt_details_patches_path := $(PATCHES_PATH)/qt -qt_details_top_download_path := https://raw.githubusercontent.com/qt/qt5/refs/heads/$(qt_details_version) +qt_details_top_download_path := https://raw.githubusercontent.com/qt/qt5/refs/tags/v$(qt_details_version)-lts-lgpl qt_details_top_cmakelists_file_name := CMakeLists.txt qt_details_top_cmakelists_download_file := $(qt_details_top_cmakelists_file_name) qt_details_top_cmakelists_sha256_hash := 54e9a4e554da37792446dda4f52bc308407b01a34bcc3afbad58e4e0f71fac9b diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index 8bf84b1f1cba..ab10e6c2f6ee 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -11,6 +11,7 @@ $(package)_patches += openbsd_kqueue_headers.patch $(package)_patches += cmake_minimum.patch $(package)_patches += cacheline_undefined.patch $(package)_patches += no_librt.patch +$(package)_patches += add_new_include.patch define $(package)_set_vars $(package)_config_opts := -DCMAKE_BUILD_TYPE=None -DWITH_DOCS=OFF -DWITH_LIBSODIUM=OFF @@ -28,7 +29,8 @@ define $(package)_preprocess_cmds patch -p1 < $($(package)_patch_dir)/fix_have_windows.patch && \ patch -p1 < $($(package)_patch_dir)/openbsd_kqueue_headers.patch && \ patch -p1 < $($(package)_patch_dir)/cmake_minimum.patch && \ - patch -p1 < $($(package)_patch_dir)/no_librt.patch + patch -p1 < $($(package)_patch_dir)/no_librt.patch && \ + patch -p1 < $($(package)_patch_dir)/add_new_include.patch endef define $(package)_config_cmds diff --git a/depends/patches/qt/fix-gcc16-qcompare.patch b/depends/patches/qt/fix-gcc16-qcompare.patch index e56f610af4dd..c2c1100ac12f 100644 --- a/depends/patches/qt/fix-gcc16-qcompare.patch +++ b/depends/patches/qt/fix-gcc16-qcompare.patch @@ -105,7 +105,7 @@ index d82cf5ab4a4e..7eee69db66a3 100644 namespace Qt { class weak_ordering; -@@ -157,12 +183,18 @@ public: +@@ -156,12 +182,18 @@ public: constexpr Q_IMPLICIT operator std::partial_ordering() const noexcept { static_assert(sizeof(*this) == sizeof(std::partial_ordering)); @@ -127,7 +127,7 @@ index d82cf5ab4a4e..7eee69db66a3 100644 switch (m_order) { case qToUnderlying(O::Less): return R::less; case qToUnderlying(O::Greater): return R::greater; -@@ -170,7 +202,6 @@ public: +@@ -169,7 +201,6 @@ public: case qToUnderlying(U::Unordered): return R::unordered; } Q_UNREACHABLE_RETURN(R::unordered); @@ -135,7 +135,7 @@ index d82cf5ab4a4e..7eee69db66a3 100644 } friend constexpr bool operator==(partial_ordering lhs, std::partial_ordering rhs) noexcept -@@ -349,18 +380,18 @@ public: +@@ -347,18 +378,18 @@ public: constexpr Q_IMPLICIT operator std::weak_ordering() const noexcept { static_assert(sizeof(*this) == sizeof(std::weak_ordering)); @@ -158,7 +158,7 @@ index d82cf5ab4a4e..7eee69db66a3 100644 } friend constexpr bool operator==(weak_ordering lhs, std::weak_ordering rhs) noexcept -@@ -547,18 +578,18 @@ public: +@@ -542,18 +573,18 @@ public: constexpr Q_IMPLICIT operator std::strong_ordering() const noexcept { static_assert(sizeof(*this) == sizeof(std::strong_ordering)); @@ -181,7 +181,7 @@ index d82cf5ab4a4e..7eee69db66a3 100644 } friend constexpr bool operator==(strong_ordering lhs, std::strong_ordering rhs) noexcept -@@ -625,6 +656,8 @@ inline constexpr strong_ordering strong_ordering::greater(QtPrivate::Ordering::G +@@ -620,6 +651,8 @@ inline constexpr strong_ordering strong_ordering::greater(QtPrivate::Ordering::G } // namespace Qt diff --git a/depends/patches/qt/fix-gcc16-sfinae-qanystringview.patch b/depends/patches/qt/fix-gcc16-sfinae-qanystringview.patch index 11c2794986d5..42f13ebb4f74 100644 --- a/depends/patches/qt/fix-gcc16-sfinae-qanystringview.patch +++ b/depends/patches/qt/fix-gcc16-sfinae-qanystringview.patch @@ -19,7 +19,7 @@ diff --git a/qtbase/src/corelib/text/qanystringview.cpp b/qtbase/src/corelib/tex index 7bf8a3fa1fd..3c993ff1da0 100644 --- a/qtbase/src/corelib/text/qanystringview.cpp +++ b/qtbase/src/corelib/text/qanystringview.cpp -@@ -243,6 +243,10 @@ QT_BEGIN_NAMESPACE +@@ -355,6 +355,10 @@ QT_BEGIN_NAMESPACE \sa isNull(), isEmpty() */ diff --git a/depends/patches/qt/fix-gcc16-sfinae-qchar.patch b/depends/patches/qt/fix-gcc16-sfinae-qchar.patch index 888e128c01a6..e8afea818df1 100644 --- a/depends/patches/qt/fix-gcc16-sfinae-qchar.patch +++ b/depends/patches/qt/fix-gcc16-sfinae-qchar.patch @@ -37,7 +37,7 @@ diff --git a/qtbase/src/corelib/kernel/qmetatype.cpp b/qtbase/src/corelib/kernel index e70583404a46..54a0fe671fe0 100644 --- a/qtbase/src/corelib/kernel/qmetatype.cpp +++ b/qtbase/src/corelib/kernel/qmetatype.cpp -@@ -1212,7 +1212,7 @@ QT_WARNING_DISABLE_CLANG("-Wtautological-compare") +@@ -1230,7 +1230,7 @@ QT_WARNING_DISABLE_CLANG("-Wtautological-compare") return true; ); QMETATYPE_CONVERTER(QString, Char32, diff --git a/depends/patches/qt/qtbase_platformsupport.patch b/depends/patches/qt/qtbase_platformsupport.patch deleted file mode 100644 index 45ccaea53a7d..000000000000 --- a/depends/patches/qt/qtbase_platformsupport.patch +++ /dev/null @@ -1,34 +0,0 @@ -CMake: Prevent creation of empty InputSupportPrivate module - -The combination of - -no-feature-evdev - -no-feature-tslib - -no-feature-libinput -led to the creation of the InputSupportPrivate module without source -files. - -This triggered CMake upstream issue 23464 when using CMake < 3.25. - -Fix this by adjusting the inexact condition that decides whether to -build InputSupportPrivate. - - -See: https://codereview.qt-project.org/c/qt/qtbase/+/633612 - - ---- a/qtbase/src/platformsupport/CMakeLists.txt -+++ b/qtbase/src/platformsupport/CMakeLists.txt -@@ -3,7 +3,12 @@ - - add_subdirectory(devicediscovery) - add_subdirectory(fbconvenience) --if(QT_FEATURE_evdev OR QT_FEATURE_integrityhid OR QT_FEATURE_libinput OR QT_FEATURE_tslib OR QT_FEATURE_xkbcommon) -+if(QT_FEATURE_evdev -+ OR QT_FEATURE_vxworksevdev -+ OR QT_FEATURE_integrityhid -+ OR QT_FEATURE_libinput -+ OR QT_FEATURE_tslib -+ OR (QT_FEATURE_libinput AND QT_FEATURE_xkbcommon)) - add_subdirectory(input) - endif() - if(QT_FEATURE_kms) diff --git a/depends/patches/qt/qtbase_plugins_cocoa.patch b/depends/patches/qt/qtbase_plugins_cocoa.patch index 2b0cc5097f6d..1f0553533755 100644 --- a/depends/patches/qt/qtbase_plugins_cocoa.patch +++ b/depends/patches/qt/qtbase_plugins_cocoa.patch @@ -8,7 +8,7 @@ See: https://codereview.qt-project.org/c/qt/qtbase/+/634002 --- a/qtbase/src/plugins/platforms/cocoa/CMakeLists.txt +++ b/qtbase/src/plugins/platforms/cocoa/CMakeLists.txt -@@ -107,3 +107,10 @@ qt_internal_extend_target(QCocoaIntegrationPlugin CONDITION QT_FEATURE_sessionma +@@ -108,3 +108,10 @@ qt_internal_extend_target(QCocoaIntegrationPlugin CONDITION QT_FEATURE_sessionma SOURCES qcocoasessionmanager.cpp qcocoasessionmanager.h ) diff --git a/depends/patches/qt/qtbase_skip_tools.patch b/depends/patches/qt/qtbase_skip_tools.patch index eef65425d412..77cb3e3f903d 100644 --- a/depends/patches/qt/qtbase_skip_tools.patch +++ b/depends/patches/qt/qtbase_skip_tools.patch @@ -9,7 +9,7 @@ Skip building/installing unneeded tools: --- a/qtbase/cmake/QtBaseGlobalTargets.cmake +++ b/qtbase/cmake/QtBaseGlobalTargets.cmake -@@ -118,9 +118,6 @@ qt_generate_global_module_pri_file() +@@ -128,9 +128,6 @@ qt_generate_global_module_pri_file() qt_generate_global_device_pri_file() qt_generate_qmake_and_qtpaths_wrapper_for_target() @@ -19,7 +19,7 @@ Skip building/installing unneeded tools: qt_internal_add_platform_internal_target(GlobalConfigPrivate) target_link_libraries(GlobalConfigPrivate INTERFACE GlobalConfig) -@@ -390,12 +387,3 @@ elseif(WASM) +@@ -400,12 +397,3 @@ elseif(WASM) qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/qt-wasmtestrunner.py" DESTINATION "${INSTALL_LIBEXECDIR}") endif() diff --git a/depends/patches/zeromq/add_new_include.patch b/depends/patches/zeromq/add_new_include.patch new file mode 100644 index 000000000000..0bf987f680ee --- /dev/null +++ b/depends/patches/zeromq/add_new_include.patch @@ -0,0 +1,123 @@ +commit 2e8a6ccb414ca79636392604893c79c3b0d00dc4 +Author: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> +Date: Sat Jul 4 09:11:11 2026 +0200 + + Add missing includes for std::nothrow + + Without the include, compilation may fail: + + ``` + src/polling_util.hpp:28:30: error: no member named 'nothrow' in namespace 'std' + 28 | _buf = new (std::nothrow) T[nitems_]; + | ^~~~~~~ + ``` + +diff --git a/src/norm_engine.cpp b/src/norm_engine.cpp +index 1e3ae179..02483f0b 100644 +--- a/src/norm_engine.cpp ++++ b/src/norm_engine.cpp +@@ -1,6 +1,7 @@ + + #include "precompiled.hpp" + ++#include + #include "platform.hpp" + + #if defined ZMQ_HAVE_NORM +diff --git a/src/polling_util.hpp b/src/polling_util.hpp +index 13a4911f..3536be9a 100644 +--- a/src/polling_util.hpp ++++ b/src/polling_util.hpp +@@ -4,6 +4,7 @@ + #define __ZMQ_SOCKET_POLLING_UTIL_HPP_INCLUDED__ + + #include ++#include + #include + + #if defined ZMQ_HAVE_WINDOWS +diff --git a/src/proxy.cpp b/src/proxy.cpp +index 78d6ba61..85e4db4a 100644 +--- a/src/proxy.cpp ++++ b/src/proxy.cpp +@@ -3,6 +3,7 @@ + #include "precompiled.hpp" + + #include ++#include + #include "poller.hpp" + #include "proxy.hpp" + #include "likely.hpp" +diff --git a/src/reaper.cpp b/src/reaper.cpp +index 4361a7e9..1484a926 100644 +--- a/src/reaper.cpp ++++ b/src/reaper.cpp +@@ -2,6 +2,7 @@ + + #include "precompiled.hpp" + #include "macros.hpp" ++#include + #include "reaper.hpp" + #include "socket_base.hpp" + #include "err.hpp" +diff --git a/src/session_base.cpp b/src/session_base.cpp +index 5a81b076..618443d5 100644 +--- a/src/session_base.cpp ++++ b/src/session_base.cpp +@@ -1,6 +1,7 @@ + /* SPDX-License-Identifier: MPL-2.0 */ + + #include "precompiled.hpp" ++#include + #include "macros.hpp" + #include "session_base.hpp" + #include "i_engine.hpp" +diff --git a/src/socket_poller.cpp b/src/socket_poller.cpp +index b5c330e8..3feb452e 100644 +--- a/src/socket_poller.cpp ++++ b/src/socket_poller.cpp +@@ -7,6 +7,7 @@ + #include "macros.hpp" + + #include ++#include + + static bool is_thread_safe (const zmq::socket_base_t &socket_) + { +diff --git a/src/stream_connecter_base.cpp b/src/stream_connecter_base.cpp +index 8dd9a6d6..6b733b4d 100644 +--- a/src/stream_connecter_base.cpp ++++ b/src/stream_connecter_base.cpp +@@ -15,6 +15,7 @@ + #endif + + #include ++#include + + zmq::stream_connecter_base_t::stream_connecter_base_t ( + zmq::io_thread_t *io_thread_, +diff --git a/src/stream_listener_base.cpp b/src/stream_listener_base.cpp +index 350093ad..b4e02027 100644 +--- a/src/stream_listener_base.cpp ++++ b/src/stream_listener_base.cpp +@@ -13,6 +13,8 @@ + #include + #endif + ++#include ++ + zmq::stream_listener_base_t::stream_listener_base_t ( + zmq::io_thread_t *io_thread_, + zmq::socket_base_t *socket_, +diff --git a/src/ws_engine.cpp b/src/ws_engine.cpp +index 9eec0d92..55590cdc 100644 +--- a/src/ws_engine.cpp ++++ b/src/ws_engine.cpp +@@ -26,6 +26,7 @@ + #endif + + #include ++#include + + #include "compat.hpp" + #include "tcp.hpp" diff --git a/doc/AI_POLICY.md b/doc/AI_POLICY.md index 6238c7903490..fde44c4818ac 100644 --- a/doc/AI_POLICY.md +++ b/doc/AI_POLICY.md @@ -23,6 +23,7 @@ This includes the pull request body and responses to questions. This project requires a human author in the loop who understands the work produced by AI. **Pull requests should not be opened or driven by autonomous agents**. A human author must choose the work, understand the change, and be responsible for the contribution. +Do not include agents as authors or co-authors of your commits for these reasons. Pull requests that appear in violation of this can be closed without notice. If you wish to include context from an interaction with AI in your comments, it must be disclosed as such. diff --git a/doc/build-freebsd.md b/doc/build-freebsd.md index ffb8ecfe1972..8189fe0b1ee9 100644 --- a/doc/build-freebsd.md +++ b/doc/build-freebsd.md @@ -74,7 +74,7 @@ There is an included test suite that is useful for testing code changes when dev To run the test suite (recommended), you will need to have Python 3 installed: ```bash -pkg install python3 databases/py-sqlite3 net/py-pyzmq +pkg install python3 databases/py-sqlite3 net/py-pyzmq lsof ``` --- diff --git a/doc/build-netbsd.md b/doc/build-netbsd.md index d4d031d31446..22a697d731b2 100644 --- a/doc/build-netbsd.md +++ b/doc/build-netbsd.md @@ -93,7 +93,14 @@ There is an included test suite that is useful for testing code changes when dev To run the test suite (recommended), you will need to have Python 3 installed: ```bash -pkgin install python313 py313-zmq +pkgin install python313 py313-zmq lsof +``` + +When the `lsof` binary package was built for a different point release, it might be necessary to force its installation as follows: + +```bash +echo "CHECK_OSABI=no" >> /etc/pkg_install.conf +pkgin install lsof ``` ## Building Bitcoin Core diff --git a/doc/i2p.md b/doc/i2p.md index 2877c1e570ec..6bf427ea377a 100644 --- a/doc/i2p.md +++ b/doc/i2p.md @@ -4,20 +4,20 @@ It is possible to run Bitcoin Core as an [I2P (Invisible Internet Project)](https://en.wikipedia.org/wiki/I2P) service and connect to such services. -This [glossary](https://geti2p.net/en/about/glossary) may be useful to get +This [glossary](https://i2p.net/en/docs/overview/glossary) may be useful to get started with I2P terminology. ## Run Bitcoin Core with an I2P router (proxy) -A running I2P router (proxy) is required with the [SAM](https://geti2p.net/en/docs/api/samv3) +A running I2P router (proxy) is required with the [SAM](https://i2p.net/en/docs/api/samv3) application bridge enabled. The following routers are recommended for use with Bitcoin Core: -- [i2prouter (I2P Router)](https://geti2p.net), the official implementation in +- [i2prouter (I2P Router)](https://i2p.net), the official implementation in Java. The SAM bridge is not enabled by default; it must be started manually, or configured to start automatically, in the Clients page in the router console (`http://127.0.0.1:7657/configclients`) or in the `clients.config` file. - [i2pd (I2P Daemon)](https://github.com/PurpleI2P/i2pd) - ([documentation](https://i2pd.readthedocs.io/en/latest)), a lighter + ([documentation](https://docs.i2pd.website/en/latest)), a lighter alternative in C++. It enables the SAM bridge by default. Note the IP address and port the SAM proxy is listening to; usually, it is @@ -113,7 +113,7 @@ You can use the `getnodeaddresses` RPC to fetch a number of I2P peers known to y ## Compatibility -Bitcoin Core uses the [SAM v3.1](https://geti2p.net/en/docs/api/samv3) protocol +Bitcoin Core uses the [SAM v3.1](https://i2p.net/en/docs/api/samv3) protocol to connect to the I2P network. Any I2P router that supports it can be used. ## Ports in I2P and Bitcoin Core @@ -158,13 +158,13 @@ Similar bandwidth configuration options for the Java I2P router can be found in `http://127.0.0.1:7657/config` under the "Bandwidth" tab. Before doing this, please see the "Participating Traffic Considerations" section -in [Embedding I2P in your Application](https://geti2p.net/en/docs/applications/embedding). +in [Embedding I2P in your Application](https://i2p.net/en/docs/applications/embedding). In most cases, the default router settings should work fine. ## Bundling I2P in a Bitcoin application -Please see the "General Guidance for Developers" section in https://geti2p.net/en/docs/api/samv3 +Please see the "General Guidance for Developers" section in https://i2p.net/en/docs/api/samv3 if you are developing a downstream application that may be bundling I2P with Bitcoin. ## Privacy recommendations diff --git a/doc/reduce-memory.md b/doc/reduce-memory.md index 348d98bd6b45..6729ab662d5c 100644 --- a/doc/reduce-memory.md +++ b/doc/reduce-memory.md @@ -33,7 +33,7 @@ The size of some in-memory caches can be reduced. As caches trade off memory usa ## Number of peers -- `-maxconnections=` - the maximum number of connections, which defaults to 125. Each active connection takes up some +- `-maxconnections=` - the maximum number of connections, which defaults to 200. Each active connection takes up some memory. This option applies only if inbound connections are enabled; otherwise, the number of connections will not be more than 11. Of the 11 outbound peers, there can be 8 full-relay connections, 2 block-relay-only ones, and occasionally 1 short-lived feeler or extra outbound block-relay-only connection. diff --git a/doc/reduce-traffic.md b/doc/reduce-traffic.md index 8926a8361aa3..315de2145059 100644 --- a/doc/reduce-traffic.md +++ b/doc/reduce-traffic.md @@ -3,8 +3,9 @@ Reduce Traffic Some node operators need to deal with bandwidth caps imposed by their ISPs. -By default, Bitcoin Core allows up to 125 connections to different peers, 11 of -which are outbound. You can therefore, have at most 114 inbound connections. +By default, Bitcoin Core allows up to 200 connections to different peers, 11 of +which are outbound. You can therefore, have at most 189 inbound connections, half of +which can only be taken up by low-traffic block-relay-only peers. Of the 11 outbound peers, there can be 8 full-relay connections, 2 block-relay-only ones and occasionally 1 short-lived feeler or an extra block-relay-only connection. diff --git a/doc/release-notes-32800.md b/doc/release-notes-32800.md new file mode 100644 index 000000000000..de7a427e3388 --- /dev/null +++ b/doc/release-notes-32800.md @@ -0,0 +1,9 @@ +- Mempool RPCs (`getrawmempool`, `getmempoolentry`, `testmempoolaccept`, `submitpackage`) +now include an additional field `vsize_adjusted` (which is the sigop-adjusted virtual size +used for policy) and `vsize_bip141` (which represents the raw BIP141 virtual size). +While `vsize` is marked as DEPRECATED, it was previously erroneously described as the BIP 141 +vsize, but is actually sigops-adjusted vsize. Use `vsize_bip141` to actually get that behavior +or switch to the explicit `vsize_adjusted` for retained behavior. + +- `getrawtransaction` RPC now includes an additional field `vsize_adjusted`, which is the +sigop-adjusted virtual size if the transaction is in the mempool. diff --git a/doc/release-notes-34628.md b/doc/release-notes-34628.md new file mode 100644 index 000000000000..884ac0734d22 --- /dev/null +++ b/doc/release-notes-34628.md @@ -0,0 +1,13 @@ +P2P and network changes +----------------------- + +- To reduce memory and CPU usage during periods of high transaction + volume, rate-limiting of outgoing transaction relay has been changed + to use a global backlog instead of being done on a per-peer basis. The + default rate-limit remains as 14 tx/s (boosted by 2.5x for outbound + peers), though this can be changed via the `-txsendrate` configuration + option. An additional bandwidth rate-limit has also been introduced + at 12MB of transactions per 10 minutes, with a high burst rate. The + size of the global backlog and the token bucket values for the rate + limits can be queried via the `getnetworkinfo` RPC. (#34628) + diff --git a/doc/release-notes-34672.md b/doc/release-notes-34672.md new file mode 100644 index 000000000000..060d91428f05 --- /dev/null +++ b/doc/release-notes-34672.md @@ -0,0 +1,11 @@ +IPC Interface +------------- + +- `BlockTemplate.submitSolution` now returns `reason` and `debug` rejection + details in addition to the boolean result. Clients must regenerate IPC + bindings from the updated `mining.capnp` schema to use the new method. The + previous `@7` method now returns an error directing clients to update. (#34672) + +- `BlockTemplate.submitSolution` now reports duplicate blocks as failures with + `reason="duplicate"`, matching `Mining.submitBlock`, instead of returning + success for duplicate submissions. (#34672) diff --git a/doc/release-notes-35501.md b/doc/release-notes-35501.md new file mode 100644 index 000000000000..2294d63cd701 --- /dev/null +++ b/doc/release-notes-35501.md @@ -0,0 +1,4 @@ +RPC +--- + +- `gettransaction`, `listtransactions`, and `listsinceblock` now have an `alternate_wtxids` field which lists the wtxids of all transactions that have the same txid. diff --git a/doc/release-notes-35592.md b/doc/release-notes-35592.md new file mode 100644 index 000000000000..e24eec31623c --- /dev/null +++ b/doc/release-notes-35592.md @@ -0,0 +1,6 @@ +HTTP: RPC / REST +---------------- + +Clients attempting to connect from addresses not allowed by the `-rpcallowip` +option (or its default, `localhost`) will now be immediately disconnected +instead of receiving a `403 Forbidden`. diff --git a/doc/release-notes-35610.md b/doc/release-notes-35610.md index 8e0dd2087a8b..1f80677e8ce1 100644 --- a/doc/release-notes-35610.md +++ b/doc/release-notes-35610.md @@ -1,6 +1,6 @@ Tools and Utilities ------------------- -- A new `bitcoin-util netmagic` command returns the network magic of the - selected chain. +- A new `bitcoin-util getchainparams` command returns hardcoded details + about the selected chain. diff --git a/doc/release-notes-35836.md b/doc/release-notes-35836.md new file mode 100644 index 000000000000..851e48d4531b --- /dev/null +++ b/doc/release-notes-35836.md @@ -0,0 +1,5 @@ +# RPC (wallet) + +* The `fundrawtransaction` RPC no longer accepts a boolean as the second + positional argument. This silent no-op fallback was removed and the argument + is now fully type checked. Passing a boolean will raise an error. (#35836) diff --git a/doc/release-notes-953.md b/doc/release-notes-953.md new file mode 100644 index 000000000000..a4d0397552a0 --- /dev/null +++ b/doc/release-notes-953.md @@ -0,0 +1,5 @@ +GUI Changes +--- + +The migrate wallet option now allows to disable wallet loading after migrating. +It is useful in case the node is pruned and the wallet was created before the pruned height. diff --git a/doc/release-notes-gui-872.md b/doc/release-notes-gui-872.md new file mode 100644 index 000000000000..5ea70345b738 --- /dev/null +++ b/doc/release-notes-gui-872.md @@ -0,0 +1,7 @@ +GUI +--- + +* A menu action has been added to allow creating a watchonly wallet file from + an existing descriptor wallet. This option mirrors the `exportwatchonlywallet` + RPC - the exported file can be imported to another node using the Restore + Wallet menu action. diff --git a/doc/release-process.md b/doc/release-process.md index 28bcfe83decc..c02ada5ada1c 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -59,11 +59,11 @@ Release Process - Clear the release notes and move them to the wiki (see "Write the release notes" below). - Translations on Transifex: - Pull translations from Transifex into the master branch. - - Create [a new resource](https://app.transifex.com/bitcoin/bitcoin/content/) named after the major version with the slug `qt-translation-x`, where `RRR` is the major branch number padded with zeros. Use `src/qt/locale/bitcoin_en.xlf` to create it. + - Create [a new resource](https://app.transifex.com/bitcoin/bitcoin/content/) named after the major version with the slug `qt-translation-x`, where `RRR` is the major branch number padded with zeros. Use `src/qt/locale/bitcoin_en.ts` to create it. - In the project workflow settings, ensure that [Translation Memory Fill-up](https://help.transifex.com/en/articles/6224817-setting-up-translation-memory-fill-up) is enabled and that [Translation Memory Context Matching](https://help.transifex.com/en/articles/6224753-translation-memory-with-context) is disabled. - Update the Transifex slug in [`.tx/config`](/.tx/config) to the slug of the resource created in the first step. This identifies which resource the translations will be synchronized from. - Make an announcement that translators can start translating for the new version. You can use one of the [previous announcements](https://app.transifex.com/bitcoin/communication/) as a template. - - Change the auto-update URL for the resource to `master`, e.g. `https://raw.githubusercontent.com/bitcoin/bitcoin/master/src/qt/locale/bitcoin_en.xlf`. (Do this only after the previous steps, to prevent an auto-update from interfering.) + - Change the auto-update URL for the resource to `master`, e.g. `https://raw.githubusercontent.com/bitcoin/bitcoin/master/src/qt/locale/bitcoin_en.ts`. (Do this only after the previous steps, to prevent an auto-update from interfering.) #### After branch-off (on the major release branch) @@ -72,7 +72,7 @@ Release Process - Clear the release notes: `cp doc/release-notes-empty-template.md doc/release-notes.md` - Create a pinned meta-issue for testing the release candidate (see [this issue](https://github.com/bitcoin/bitcoin/issues/27621) for an example) and provide a link to it in the release announcements where useful. - Translations on Transifex - - Change the auto-update URL for the new major version's resource away from `master` and to the branch, e.g. `https://raw.githubusercontent.com/bitcoin/bitcoin//src/qt/locale/bitcoin_en.xlf`. Do not forget this or it will keep tracking the translations on master instead, drifting away from the specific major release. + - Change the auto-update URL for the new major version's resource away from `master` and to the branch, e.g. `https://raw.githubusercontent.com/bitcoin/bitcoin//src/qt/locale/bitcoin_en.ts`. Do not forget this or it will keep tracking the translations on master instead, drifting away from the specific major release. - Prune inputs from the qa-assets repo (See [pruning inputs](https://github.com/bitcoin-core/qa-assets#pruning-inputs)). diff --git a/ruff.toml b/ruff.toml index d379dde1f501..61cf6d24db60 100644 --- a/ruff.toml +++ b/ruff.toml @@ -12,7 +12,5 @@ select = [ ] ignore = [ "E501", # line too long - "E712", # true-false comparison - "E731", # lambda assignment "E741", # ambiguous-variable-name ] diff --git a/share/qt/translate.cmake b/share/qt/translate.cmake index 2ac8c7f0571a..a8f54a9155a6 100644 --- a/share/qt/translate.cmake +++ b/share/qt/translate.cmake @@ -7,7 +7,6 @@ cmake_minimum_required(VERSION 3.22) set(input_variables PROJECT_SOURCE_DIR COPYRIGHT_HOLDERS - LCONVERT_EXECUTABLE LUPDATE_EXECUTABLE XGETTEXT_EXECUTABLE ) @@ -103,28 +102,13 @@ extract_strings("${PROJECT_SOURCE_DIR}/src/qt/bitcoinstrings.cpp" execute_process( COMMAND ${LUPDATE_EXECUTABLE} -no-obsolete + -sort-messages -I ${PROJECT_SOURCE_DIR}/src - -locations relative + -locations none + -target-language en ${ui_files} ${qt_translatable_sources} ${PROJECT_SOURCE_DIR}/src/qt/bitcoinstrings.cpp -ts ${PROJECT_SOURCE_DIR}/src/qt/locale/bitcoin_en.ts COMMAND_ERROR_IS_FATAL ANY ) - -execute_process( - COMMAND ${LCONVERT_EXECUTABLE} - -drop-translations - -o ${PROJECT_SOURCE_DIR}/src/qt/locale/bitcoin_en.xlf - -i ${PROJECT_SOURCE_DIR}/src/qt/locale/bitcoin_en.ts - COMMAND_ERROR_IS_FATAL ANY -) - -file(READ "${PROJECT_SOURCE_DIR}/src/qt/locale/bitcoin_en.xlf" bitcoin_en) -string(REPLACE "source-language=\"en\" target-language=\"en\"" - "source-language=\"en\"" bitcoin_en "${bitcoin_en}" -) -string(REGEX REPLACE " *\n" - "" bitcoin_en "${bitcoin_en}" -) -file(WRITE "${PROJECT_SOURCE_DIR}/src/qt/locale/bitcoin_en.xlf" "${bitcoin_en}") diff --git a/share/setup.nsi.in b/share/setup.nsi.in index 387d78116b8d..33baa4778410 100644 --- a/share/setup.nsi.in +++ b/share/setup.nsi.in @@ -72,19 +72,19 @@ ShowUninstDetails show Section -Main SEC0000 SetOutPath $INSTDIR SetOverwrite on - File @abs_top_builddir@/release/@BITCOIN_GUI_NAME@@EXEEXT@ - File @abs_top_builddir@/release/@BITCOIN_WRAPPER_NAME@@EXEEXT@ - File /oname=COPYING.txt @abs_top_srcdir@/COPYING - File /oname=readme.txt @abs_top_srcdir@/doc/README_windows.txt - File @abs_top_srcdir@/share/examples/bitcoin.conf + File "@BIN_DIR@/@BITCOIN_GUI_NAME@@EXEEXT@" + File "@BIN_DIR@/@BITCOIN_WRAPPER_NAME@@EXEEXT@" + File /oname=COPYING.txt "@abs_top_srcdir@/COPYING" + File /oname=readme.txt "@abs_top_srcdir@/doc/README_windows.txt" + File "@abs_top_srcdir@/share/examples/bitcoin.conf" SetOutPath $INSTDIR\share\rpcauth - File @abs_top_srcdir@/share/rpcauth/*.* + File "@abs_top_srcdir@/share/rpcauth/*.*" SetOutPath $INSTDIR\daemon - File @abs_top_builddir@/release/@BITCOIN_DAEMON_NAME@@EXEEXT@ - File @abs_top_builddir@/release/@BITCOIN_CLI_NAME@@EXEEXT@ - File @abs_top_builddir@/release/@BITCOIN_TX_NAME@@EXEEXT@ - File @abs_top_builddir@/release/@BITCOIN_WALLET_TOOL_NAME@@EXEEXT@ - File @abs_top_builddir@/release/@BITCOIN_TEST_NAME@@EXEEXT@ + File "@BIN_DIR@/@BITCOIN_DAEMON_NAME@@EXEEXT@" + File "@BIN_DIR@/@BITCOIN_CLI_NAME@@EXEEXT@" + File "@BIN_DIR@/@BITCOIN_TX_NAME@@EXEEXT@" + File "@BIN_DIR@/@BITCOIN_WALLET_TOOL_NAME@@EXEEXT@" + File "@LIBEXEC_DIR@/@BITCOIN_TEST_NAME@@EXEEXT@" SetOutPath $INSTDIR WriteRegStr HKCU "${REGKEY}\Components" Main 1 SectionEnd diff --git a/src/.clang-tidy b/src/.clang-tidy index 9bdcc03f636a..4e0af3f379b6 100644 --- a/src/.clang-tidy +++ b/src/.clang-tidy @@ -8,8 +8,10 @@ bugprone-use-after-move, bugprone-lambda-function-name, bugprone-unhandled-self-assignment, bugprone-unused-return-value, -misc-unused-using-decls, +fuchsia-header-anon-namespaces, +misc-definitions-in-headers, misc-no-recursion, +misc-unused-using-decls, modernize-avoid-bind, modernize-deprecated-headers, modernize-use-default-member-init, diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 47266dcf5cd5..2b6840bbc390 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -388,6 +388,7 @@ if(BUILD_UTIL) core_interface bitcoin_common bitcoin_util + univalue ) install_binary_component(bitcoin-util HAS_MANPAGE) endif() diff --git a/src/addrman.cpp b/src/addrman.cpp index 3050beb7968c..554e5ad05a08 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -910,7 +910,10 @@ void AddrManImpl::ResolveCollisions_() int tried_bucket_pos = info_new.GetBucketPosition(nKey, false, tried_bucket); if (!info_new.IsValid()) { // id_new may no longer map to a valid address erase_collision = true; - } else if (vvTried[tried_bucket][tried_bucket_pos] != -1) { // The position in the tried bucket is not empty + } else { + // A pending tried collision implies that the destination tried slot + // remains occupied until we resolve it. + Assume(vvTried[tried_bucket][tried_bucket_pos] != -1); // Get the to-be-evicted address that is being tested nid_type id_old = vvTried[tried_bucket][tried_bucket_pos]; @@ -939,9 +942,6 @@ void AddrManImpl::ResolveCollisions_() Good_(info_new, false, current_time); erase_collision = true; } - } else { // Collision is not actually a collision anymore - Good_(info_new, false, Now()); - erase_collision = true; } } @@ -977,6 +977,7 @@ std::pair AddrManImpl::SelectTriedCollision_() int tried_bucket = newInfo.GetTriedBucket(nKey, m_netgroupman); int tried_bucket_pos = newInfo.GetBucketPosition(nKey, false, tried_bucket); + Assume(vvTried[tried_bucket][tried_bucket_pos] != -1); const AddrInfo& info_old = mapInfo[vvTried[tried_bucket][tried_bucket_pos]]; return {info_old, info_old.m_last_try}; } diff --git a/src/addrman.h b/src/addrman.h index f714338610c1..9449c938ca12 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -73,10 +72,7 @@ struct AddressPosition { const int bucket; const int position; - bool operator==(AddressPosition other) { - return std::tie(tried, multiplicity, bucket, position) == - std::tie(other.tried, other.multiplicity, other.bucket, other.position); - } + bool operator==(const AddressPosition&) const = default; explicit AddressPosition(bool tried_in, int multiplicity_in, int bucket_in, int position_in) : tried{tried_in}, multiplicity{multiplicity_in}, bucket{bucket_in}, position{position_in} {} }; diff --git a/src/bench/coin_selection.cpp b/src/bench/coin_selection.cpp index 5c54cafc5473..396d21d46bb0 100644 --- a/src/bench/coin_selection.cpp +++ b/src/bench/coin_selection.cpp @@ -76,7 +76,7 @@ static void CoinSelection(benchmark::Bench& bench) // Create coins from the amounts assigning them various output types wallet::CoinsResult available_coins; for (const auto& wtx : wtxs) { - const auto txout = wtx->tx->vout.at(0); + const auto txout = wtx->GetTx()->vout.at(0); OutputType outtype; int input_bytes; int y{det_rand.randrange(100)}; diff --git a/src/bench/crypto_hash.cpp b/src/bench/crypto_hash.cpp index 4d0660db5806..827448974fb8 100644 --- a/src/bench/crypto_hash.cpp +++ b/src/bench/crypto_hash.cpp @@ -190,10 +190,10 @@ static void SHA512(benchmark::Bench& bench) }); } -static void SipHash_32b(benchmark::Bench& bench) +static void SipHash24_32b(benchmark::Bench& bench) { FastRandomContext rng{/*fDeterministic=*/true}; - PresaltedSipHasher presalted_sip_hasher(rng.rand64(), rng.rand64()); + PresaltedSipHasher presalted_sip_hasher{rng.rand64(), rng.rand64()}; auto val{rng.rand256()}; auto i{0U}; bench.run([&] { @@ -203,6 +203,49 @@ static void SipHash_32b(benchmark::Bench& bench) }); } +static void SipHash24_36b(benchmark::Bench& bench) +{ + FastRandomContext rng{/*fDeterministic=*/true}; + PresaltedSipHasher presalted_sip_hasher{rng.rand64(), rng.rand64()}; + auto val{rng.rand256()}; + uint32_t extra{rng.rand32()}; + auto i{0U}; + bench.run([&] { + ankerl::nanobench::doNotOptimizeAway(presalted_sip_hasher(val, extra)); + ++i; + val.data()[i % uint256::size()] ^= i & 0xFF; + extra += i; + }); +} + +static void SipHash13UJ_32b(benchmark::Bench& bench) +{ + FastRandomContext rng{/*fDeterministic=*/true}; + SipHasher13UJ sip_hasher{rng.rand64(), rng.rand64()}; + auto val{rng.rand256()}; + auto i{0U}; + bench.run([&] { + ankerl::nanobench::doNotOptimizeAway(sip_hasher.Hash(val)); + ++i; + val.data()[i % uint256::size()] ^= i & 0xFF; + }); +} + +static void SipHash13UJ_36b(benchmark::Bench& bench) +{ + FastRandomContext rng{/*fDeterministic=*/true}; + SipHasher13UJ sip_hasher{rng.rand64(), rng.rand64()}; + auto val{rng.rand256()}; + uint32_t extra{rng.rand32()}; + auto i{0U}; + bench.run([&] { + ankerl::nanobench::doNotOptimizeAway(sip_hasher.Hash(val, uint64_t{extra})); + ++i; + val.data()[i % uint256::size()] ^= i & 0xFF; + extra += i; + }); +} + static void MuHash(benchmark::Bench& bench) { MuHash3072 acc; @@ -273,7 +316,10 @@ BENCHMARK(SHA256_32b_STANDARD); BENCHMARK(SHA256_32b_SSE4); BENCHMARK(SHA256_32b_AVX2); BENCHMARK(SHA256_32b_SHANI); -BENCHMARK(SipHash_32b); +BENCHMARK(SipHash24_32b); +BENCHMARK(SipHash24_36b); +BENCHMARK(SipHash13UJ_32b); +BENCHMARK(SipHash13UJ_36b); BENCHMARK(SHA256D64_1024_STANDARD); BENCHMARK(SHA256D64_1024_SSE4); BENCHMARK(SHA256D64_1024_AVX2); diff --git a/src/bench/nanobench.h b/src/bench/nanobench.h index a66e92a4a8af..ffcc480297fa 100644 --- a/src/bench/nanobench.h +++ b/src/bench/nanobench.h @@ -1369,6 +1369,7 @@ void doNotOptimizeAway(T const& val) { } // namespace ankerl #if defined(ANKERL_NANOBENCH_IMPLEMENT) +// NOLINTBEGIN(misc-definitions-in-headers) /////////////////////////////////////////////////////////////////////////////////////////////////// // implementation part - only visible in .cpp @@ -3563,5 +3564,6 @@ std::ostream& operator<<(std::ostream& os, std::vector } // namespace nanobench } // namespace ankerl +// NOLINTEND(misc-definitions-in-headers) #endif // ANKERL_NANOBENCH_IMPLEMENT #endif // ANKERL_NANOBENCH_H_INCLUDED diff --git a/src/bitcoin-util.cpp b/src/bitcoin-util.cpp index f17c7a0dd178..7e7746855379 100644 --- a/src/bitcoin-util.cpp +++ b/src/bitcoin-util.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -36,7 +37,7 @@ static void SetupBitcoinUtilArgs(ArgsManager &argsman) argsman.AddArg("-version", "Print version and exit", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); argsman.AddCommand("grind", "Perform proof of work on hex header string"); - argsman.AddCommand("netmagic", "Get the network magic bytes of the selected chain"); + argsman.AddCommand("getchainparams", "Get hardcoded parameters for the selected chain"); SetupChainParamsBaseOptions(argsman); } @@ -151,14 +152,60 @@ static int Grind(const std::vector& args, std::string& strPrint) return EXIT_SUCCESS; } -static int NetMagic(const std::vector& args, std::string& strPrint) +static int GetChainParams(const std::vector& args, std::string& strPrint) { if (!args.empty()) { - strPrint = "netmagic does not take arguments"; + strPrint = "getchainparams does not take arguments"; return EXIT_FAILURE; } - strPrint = HexStr(Params().MessageStart()); + const auto& params = Params(); + const auto& consensus = params.GetConsensus(); + + UniValue result{UniValue::VOBJ}; + result.pushKV("chain", params.GetChainTypeString()); + result.pushKV("test_chain", params.IsTestChain()); + result.pushKV("genesis", HexStr(consensus.hashGenesisBlock)); + result.pushKV("subsidy_halving_interval", consensus.nSubsidyHalvingInterval); + + if (consensus.signet_blocks) { + UniValue signet{UniValue::VOBJ}; + signet.pushKV("challenge", HexStr(consensus.signet_challenge)); + result.pushKV("signet", signet); + } + + { + UniValue pow{UniValue::VOBJ}; + pow.pushKV("limit", consensus.powLimit.ToString()); + if (!consensus.fPowNoRetargeting) { + pow.pushKV("target_spacing", TicksSeconds(consensus.PowTargetSpacing())); + pow.pushKV("difficulty_retarget_interval", consensus.DifficultyAdjustmentInterval()); + std::string mindiff_blocks = (consensus.fPowAllowMinDifficultyBlocks ? + (consensus.enforce_BIP94 ? "bip94" : "yes") : "no"); + pow.pushKV("mindiff_blocks", mindiff_blocks); + } + result.pushKV("pow", pow); + } + + { + UniValue net{UniValue::VOBJ}; + net.pushKV("default_port", params.GetDefaultPort()); + net.pushKV("magic", HexStr(params.MessageStart())); + UniValue dns{UniValue::VARR}; + for (const auto& seed : params.DNSSeeds()) { + dns.push_back(seed); + } + net.pushKV("dns_seeds", dns); + result.pushKV("net", net); + } + + { + UniValue addr{UniValue::VOBJ}; + addr.pushKV("bech32_hrp", params.Bech32HRP()); + result.pushKV("addresses", addr); + } + + strPrint = result.write(/*prettyIndent=*/2); return EXIT_SUCCESS; } @@ -191,8 +238,8 @@ MAIN_FUNCTION try { if (cmd->command == "grind") { ret = Grind(cmd->args, strPrint); - } else if (cmd->command == "netmagic") { - ret = NetMagic(cmd->args, strPrint); + } else if (cmd->command == "getchainparams") { + ret = GetChainParams(cmd->args, strPrint); } else { assert(false); // unknown command should be caught earlier } diff --git a/src/blockencodings.cpp b/src/blockencodings.cpp index c2846539bdb0..afa9df4fa7cb 100644 --- a/src/blockencodings.cpp +++ b/src/blockencodings.cpp @@ -113,25 +113,25 @@ ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& c if (shorttxids.size() != cmpctblock.shorttxids.size()) return READ_STATUS_FAILED; // Short ID collision - std::vector have_txn(txn_available.size()); + enum class TxSource : uint8_t { NONE, MEMPOOL, EXTRA, COLLIDED }; + std::vector tx_source(txn_available.size(), TxSource::NONE); { LOCK(pool->cs); for (const auto& [wtxid, txit] : pool->txns_randomized) { uint64_t shortid = cmpctblock.GetShortID(wtxid); std::unordered_map::iterator idit = shorttxids.find(shortid); if (idit != shorttxids.end()) { - if (!have_txn[idit->second]) { + if (tx_source[idit->second] == TxSource::NONE) { txn_available[idit->second] = txit->GetSharedTx(); - have_txn[idit->second] = true; + tx_source[idit->second] = TxSource::MEMPOOL; mempool_count++; - } else { + } else if (tx_source[idit->second] != TxSource::COLLIDED) { // If we find two mempool txn that match the short id, just request it. // This should be rare enough that the extra bandwidth doesn't matter, // but eating a round-trip due to FillBlock failure would be annoying - if (txn_available[idit->second]) { - txn_available[idit->second].reset(); - mempool_count--; - } + txn_available[idit->second].reset(); + mempool_count--; + tx_source[idit->second] = TxSource::COLLIDED; } } // Though ideally we'd continue scanning for the two-txn-match-shortid case, @@ -146,24 +146,23 @@ ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& c uint64_t shortid = cmpctblock.GetShortID(extra_txn[i].first); std::unordered_map::iterator idit = shorttxids.find(shortid); if (idit != shorttxids.end()) { - if (!have_txn[idit->second]) { + if (tx_source[idit->second] == TxSource::NONE) { txn_available[idit->second] = extra_txn[i].second; - have_txn[idit->second] = true; + tx_source[idit->second] = TxSource::EXTRA; mempool_count++; extra_count++; - } else { + } else if (tx_source[idit->second] != TxSource::COLLIDED && + txn_available[idit->second]->GetWitnessHash() != extra_txn[i].second->GetWitnessHash()) { // If we find two mempool/extra txn that match the short id, just // request it. // This should be rare enough that the extra bandwidth doesn't matter, // but eating a round-trip due to FillBlock failure would be annoying // Note that we don't want duplication between extra_txn and mempool to // trigger this case, so we compare witness hashes first - if (txn_available[idit->second] && - txn_available[idit->second]->GetWitnessHash() != extra_txn[i].second->GetWitnessHash()) { - txn_available[idit->second].reset(); - mempool_count--; - extra_count--; - } + txn_available[idit->second].reset(); + mempool_count--; + extra_count -= (tx_source[idit->second] == TxSource::EXTRA); + tx_source[idit->second] = TxSource::COLLIDED; } } // Though ideally we'd continue scanning for the two-txn-match-shortid case, diff --git a/src/cluster_linearize.h b/src/cluster_linearize.h index 23cb98f45637..7b262edb46c5 100644 --- a/src/cluster_linearize.h +++ b/src/cluster_linearize.h @@ -954,11 +954,16 @@ class SpanningForestState Assume(m_chunk_idxs[bottom_idx]); auto& top_chunk_info = m_set_info[top_idx]; auto& bottom_chunk_info = m_set_info[bottom_idx]; - // Count the number of dependencies between bottom_chunk and top_chunk. + // Count the number of dependencies between bottom_chunk and top_chunk, remembering the + // per-transaction counts so the picking loop below does not need to recompute the + // intersections. unsigned num_deps{0}; + std::array counts; for (auto tx_idx : top_chunk_info.transactions) { auto& tx_data = m_tx_data[tx_idx]; - num_deps += (tx_data.children & bottom_chunk_info.transactions).Count(); + auto count = (tx_data.children & bottom_chunk_info.transactions).Count(); + counts[tx_idx] = count; + num_deps += count; } m_cost.MergeChunksMid(/*num_txns=*/top_chunk_info.transactions.Count()); Assume(num_deps > 0); @@ -967,10 +972,10 @@ class SpanningForestState unsigned num_steps = 0; for (auto tx_idx : top_chunk_info.transactions) { ++num_steps; - auto& tx_data = m_tx_data[tx_idx]; - auto intersect = tx_data.children & bottom_chunk_info.transactions; - auto count = intersect.Count(); + auto count = counts[tx_idx]; if (pick < count) { + auto& tx_data = m_tx_data[tx_idx]; + auto intersect = tx_data.children & bottom_chunk_info.transactions; for (auto child_idx : intersect) { if (pick == 0) { m_cost.MergeChunksEnd(/*num_steps=*/num_steps); @@ -1183,6 +1188,7 @@ class SpanningForestState m_tx_data.resize(depgraph.PositionRange()); m_set_info.resize(num_transactions); m_reachable.resize(num_transactions); + m_suboptimal_chunks.reserve(num_transactions); size_t num_chunks = 0; size_t num_deps = 0; for (auto tx_idx : m_transaction_idxs) { @@ -1471,16 +1477,22 @@ class SpanningForestState /** A heap with all chunks (by set index) that can currently be included, sorted by * chunk feerate (high to low), chunk size (small to large), and by least maximum element * according to the fallback order (which is the second pair element). */ - std::vector> ready_chunks; + std::array, SetType::Size()> ready_chunks; + /** The number of entries of ready_chunks in use. */ + unsigned num_ready_chunks{0}; /** For every chunk, indexed by SetIdx, the number of unmet dependencies the chunk has on * other chunks (not including dependencies within the chunk itself). */ - std::vector chunk_deps(m_set_info.size(), 0); + std::array chunk_deps; + std::fill_n(chunk_deps.begin(), m_set_info.size(), TxIdx{0}); /** For every transaction, indexed by TxIdx, the number of unmet dependencies the * transaction has. */ - std::vector tx_deps(m_tx_data.size(), 0); + std::array tx_deps; + std::fill_n(tx_deps.begin(), m_tx_data.size(), TxIdx{0}); /** A heap with all transactions within the current chunk that can be included, sorted by * tx feerate (high to low), tx size (small to large), and fallback order. */ - std::vector ready_tx; + std::array ready_tx; + /** The number of entries of ready_tx in use. */ + unsigned num_ready_tx{0}; // Populate chunk_deps and tx_deps. unsigned num_deps{0}; for (TxIdx chl_idx : m_transaction_idxs) { @@ -1549,31 +1561,31 @@ class SpanningForestState // Construct a heap with all chunks that have no out-of-chunk dependencies. for (SetIdx chunk_idx : m_chunk_idxs) { if (chunk_deps[chunk_idx] == 0) { - ready_chunks.emplace_back(chunk_idx, max_fallback_fn(chunk_idx)); + ready_chunks[num_ready_chunks++] = {chunk_idx, max_fallback_fn(chunk_idx)}; } } - std::make_heap(ready_chunks.begin(), ready_chunks.end(), chunk_cmp_fn); + std::make_heap(ready_chunks.begin(), ready_chunks.begin() + num_ready_chunks, chunk_cmp_fn); // Pop chunks off the heap. - while (!ready_chunks.empty()) { + while (num_ready_chunks > 0) { auto [chunk_idx, _rnd] = ready_chunks.front(); - std::pop_heap(ready_chunks.begin(), ready_chunks.end(), chunk_cmp_fn); - ready_chunks.pop_back(); + std::pop_heap(ready_chunks.begin(), ready_chunks.begin() + num_ready_chunks, chunk_cmp_fn); + --num_ready_chunks; Assume(chunk_deps[chunk_idx] == 0); const auto& chunk_txn = m_set_info[chunk_idx].transactions; // Build heap of all includable transactions in chunk. - Assume(ready_tx.empty()); + Assume(num_ready_tx == 0); for (TxIdx tx_idx : chunk_txn) { - if (tx_deps[tx_idx] == 0) ready_tx.push_back(tx_idx); + if (tx_deps[tx_idx] == 0) ready_tx[num_ready_tx++] = tx_idx; } - Assume(!ready_tx.empty()); - std::make_heap(ready_tx.begin(), ready_tx.end(), tx_cmp_fn); + Assume(num_ready_tx > 0); + std::make_heap(ready_tx.begin(), ready_tx.begin() + num_ready_tx, tx_cmp_fn); // Pick transactions from the ready heap, append them to linearization, and decrement // dependency counts. - while (!ready_tx.empty()) { + while (num_ready_tx > 0) { // Pop an element from the tx_ready heap. auto tx_idx = ready_tx.front(); - std::pop_heap(ready_tx.begin(), ready_tx.end(), tx_cmp_fn); - ready_tx.pop_back(); + std::pop_heap(ready_tx.begin(), ready_tx.begin() + num_ready_tx, tx_cmp_fn); + --num_ready_tx; // Append to linearization. ret.push_back(tx_idx); // Decrement dependency counts. @@ -1584,16 +1596,16 @@ class SpanningForestState Assume(tx_deps[chl_idx] > 0); if (--tx_deps[chl_idx] == 0 && chunk_txn[chl_idx]) { // Child tx has no dependencies left, and is in this chunk. Add it to the tx heap. - ready_tx.push_back(chl_idx); - std::push_heap(ready_tx.begin(), ready_tx.end(), tx_cmp_fn); + ready_tx[num_ready_tx++] = chl_idx; + std::push_heap(ready_tx.begin(), ready_tx.begin() + num_ready_tx, tx_cmp_fn); } // Decrement chunk dependency count if this is out-of-chunk dependency. if (chl_data.chunk_idx != chunk_idx) { Assume(chunk_deps[chl_data.chunk_idx] > 0); if (--chunk_deps[chl_data.chunk_idx] == 0) { // Child chunk has no dependencies left. Add it to the chunk heap. - ready_chunks.emplace_back(chl_data.chunk_idx, max_fallback_fn(chl_data.chunk_idx)); - std::push_heap(ready_chunks.begin(), ready_chunks.end(), chunk_cmp_fn); + ready_chunks[num_ready_chunks++] = {chl_data.chunk_idx, max_fallback_fn(chl_data.chunk_idx)}; + std::push_heap(ready_chunks.begin(), ready_chunks.begin() + num_ready_chunks, chunk_cmp_fn); } } } diff --git a/src/coins.cpp b/src/coins.cpp index 72cbda2dd26a..3d3e63fa4b8d 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -19,6 +19,13 @@ TRACEPOINT_SEMAPHORE(utxocache, add); TRACEPOINT_SEMAPHORE(utxocache, spent); TRACEPOINT_SEMAPHORE(utxocache, uncache); +SaltedCoinsCacheHasher::SaltedCoinsCacheHasher(bool deterministic) + : m_hasher{ + deterministic ? 0x8e819f2607a18de6 : FastRandomContext().rand64(), + deterministic ? 0xf4020d2e3983b0eb : FastRandomContext().rand64()} +{ +} + CoinsViewEmpty& CoinsViewEmpty::Get() { static CoinsViewEmpty instance; @@ -35,7 +42,7 @@ std::optional CCoinsViewCache::PeekCoin(const COutPoint& outpoint) const CCoinsViewCache::CCoinsViewCache(CCoinsView* in_base, bool deterministic) : CCoinsViewBacked(in_base), m_deterministic(deterministic), - cacheCoins(0, SaltedOutpointHasher(/*deterministic=*/deterministic), CCoinsMap::key_equal{}, &m_cache_coins_memory_resource) + cacheCoins(0, SaltedCoinsCacheHasher{/*deterministic=*/deterministic}, CCoinsMap::key_equal{}, &m_cache_coins_memory_resource) { m_sentinel.second.SelfRef(m_sentinel); } @@ -331,7 +338,7 @@ void CCoinsViewCache::ReallocateCache() cacheCoins.~CCoinsMap(); m_cache_coins_memory_resource.~CCoinsMapMemoryResource(); ::new (&m_cache_coins_memory_resource) CCoinsMapMemoryResource{}; - ::new (&cacheCoins) CCoinsMap{0, SaltedOutpointHasher{/*deterministic=*/m_deterministic}, CCoinsMap::key_equal{}, &m_cache_coins_memory_resource}; + ::new (&cacheCoins) CCoinsMap{0, SaltedCoinsCacheHasher{/*deterministic=*/m_deterministic}, CCoinsMap::key_equal{}, &m_cache_coins_memory_resource}; } void CCoinsViewCache::SanityCheck() const @@ -376,7 +383,7 @@ CCoinsViewCache::ResetGuard CoinsViewOverlay::StartFetching(const CBlock& block // Loop through the block inputs and set their prevouts in the queue. // Filter inputs that spend outputs created earlier in the same block. These outputs will be created // directly in the cache from the tx that creates them, so they will not be requested from a base view. - std::unordered_set earlier_txids; + std::unordered_set earlier_txids; earlier_txids.reserve(block.vtx.size()); for (const auto& tx : block.vtx | std::views::drop(1)) { for (const auto& input : tx->vin) { diff --git a/src/coins.h b/src/coins.h index 7fc01af37ff0..6fcf10929295 100644 --- a/src/coins.h +++ b/src/coins.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -18,7 +19,6 @@ #include #include #include -#include #include #include @@ -219,6 +219,43 @@ struct CCoinsCacheEntry } }; +/** + * SipHash-1-3-UJ based hasher for the coins cache and related coins containers. + * + * Retained entries identify real transaction outputs, so their keys contain computed txids. + * Missing-input lookups may contain arbitrary claimed prevouts, but FetchCoin() immediately + * erases their temporary entries when the backend lookup fails, so non-hash keys cannot + * accumulate. + * + * The assumeutxo loader assumes snapshot txids are valid while loading and verifies the + * complete snapshot's content hash before activation. + * + * Hash values are process-local and must not be persisted, serialized, or compared across + * processes. + * + * Having the hash noexcept lets libstdc++ recalculate it during rehash instead of storing it in + * each node. + */ +class SaltedCoinsCacheHasher +{ + const SipHasher13UJ m_hasher; + +public: + SaltedCoinsCacheHasher(bool deterministic = false); + + /** Hash a transaction ID, itself a cryptographic hash, as one jumbo block. */ + size_t operator()(const Txid& id) const noexcept + { + return m_hasher.Hash(id.ToUint256()); + } + + /** Hash an outpoint as its txid jumbo block followed by the zero-extended index as one normal block. */ + size_t operator()(const COutPoint& id) const noexcept + { + return m_hasher.Hash(id.hash.ToUint256(), uint64_t{id.n}); + } +}; + /** * PoolAllocator's MAX_BLOCK_SIZE_BYTES parameter here uses sizeof the data, and adds the size * of 4 pointers. We do not know the exact node size used in the std::unordered_node implementation @@ -229,7 +266,7 @@ struct CCoinsCacheEntry */ using CCoinsMap = std::unordered_map, PoolAllocator>; @@ -401,6 +438,19 @@ class CCoinsViewCache : public CCoinsViewBacked private: const bool m_deterministic; + //! Force a reallocation of the cache map. This is required when downsizing + //! the cache because the map's allocator may be hanging onto a lot of + //! memory despite having called .clear(). + //! + //! See: https://stackoverflow.com/questions/42114044/how-to-release-unordered-map-memory + void ReallocateCache(); + + /** + * @note this is marked const, but may actually append to `cacheCoins`, increasing + * memory usage. + */ + CCoinsMap::iterator FetchCoin(const COutPoint &outpoint) const; + protected: /** * Make mutable so that we can "fill the cache" even from Get-methods @@ -518,13 +568,6 @@ class CCoinsViewCache : public CCoinsViewBacked //! Check whether all prevouts of the transaction are present in the UTXO set represented by this view bool HaveInputs(const CTransaction& tx) const; - //! Force a reallocation of the cache map. This is required when downsizing - //! the cache because the map's allocator may be hanging onto a lot of - //! memory despite having called .clear(). - //! - //! See: https://stackoverflow.com/questions/42114044/how-to-release-unordered-map-memory - void ReallocateCache(); - //! Run an internal sanity check on the cache data structure. */ void SanityCheck() const; @@ -546,13 +589,6 @@ class CCoinsViewCache : public CCoinsViewBacked //! Create a scoped guard that will call `Reset()` on this cache when it goes out of scope. [[nodiscard]] ResetGuard CreateResetGuard() noexcept { return ResetGuard{*this}; } - -private: - /** - * @note this is marked const, but may actually append to `cacheCoins`, increasing - * memory usage. - */ - CCoinsMap::iterator FetchCoin(const COutPoint &outpoint) const; }; /** diff --git a/src/common/args.cpp b/src/common/args.cpp index cfd36e1f6a5a..97b37eb43873 100644 --- a/src/common/args.cpp +++ b/src/common/args.cpp @@ -23,8 +23,6 @@ #endif #include -#include -#include #include #include #include diff --git a/src/common/args.h b/src/common/args.h index 0a3195f89d6e..0a83e143047d 100644 --- a/src/common/args.h +++ b/src/common/args.h @@ -6,7 +6,6 @@ #define BITCOIN_COMMON_ARGS_H #include -#include #include #include #include diff --git a/src/common/bloom.cpp b/src/common/bloom.cpp index 3ee78994c14c..c15c8f78f905 100644 --- a/src/common/bloom.cpp +++ b/src/common/bloom.cpp @@ -16,8 +16,7 @@ #include #include -#include -#include +#include #include static constexpr double LN2SQUARED = 0.4804530139182014246671025263266649717305529515945455; diff --git a/src/common/bloom.h b/src/common/bloom.h index 97007e1ff517..c9ed89f85e3d 100644 --- a/src/common/bloom.h +++ b/src/common/bloom.h @@ -6,8 +6,9 @@ #define BITCOIN_COMMON_BLOOM_H #include -#include +#include +#include #include class COutPoint; diff --git a/src/common/config.cpp b/src/common/config.cpp index cc7ffd59537e..8cf324ca4832 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -2,28 +2,25 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include +#include // IWYU pragma: associated #include #include #include #include -#include +#include #include #include #include #include -#include #include -#include #include #include -#include #include #include -#include #include +#include #include #include #include diff --git a/src/common/init.cpp b/src/common/init.cpp index 5c9742bec47c..091b8d81329a 100644 --- a/src/common/init.cpp +++ b/src/common/init.cpp @@ -2,15 +2,15 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include + #include #include -#include #include #include #include #include -#include #include #include diff --git a/src/common/interfaces.cpp b/src/common/interfaces.cpp index b501493d6bf8..3873ca2e8646 100644 --- a/src/common/interfaces.cpp +++ b/src/common/interfaces.cpp @@ -2,8 +2,9 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include -#include +#include // IWYU pragma: associated +#include // IWYU pragma: associated + #include #include diff --git a/src/common/messages.cpp b/src/common/messages.cpp index 82ad310bb709..e558442f4272 100644 --- a/src/common/messages.cpp +++ b/src/common/messages.cpp @@ -4,16 +4,17 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include + #include #include #include #include +#include #include #include #include #include -#include #include #include #include diff --git a/src/common/messages.h b/src/common/messages.h index 60fdaa18625e..6dc3212f8c94 100644 --- a/src/common/messages.h +++ b/src/common/messages.h @@ -13,17 +13,19 @@ #include #include +#include struct bilingual_str; - enum class FeeEstimateMode; enum class FeeReason; + namespace node { enum class TransactionError; } // namespace node namespace common { enum class PSBTError; + bool FeeModeFromString(std::string_view mode_string, FeeEstimateMode& fee_estimate_mode); std::string StringForFeeReason(FeeReason reason); std::string FeeModes(const std::string& delimiter); diff --git a/src/common/netif.cpp b/src/common/netif.cpp index 997db7d5b930..1120ee6057ea 100644 --- a/src/common/netif.cpp +++ b/src/common/netif.cpp @@ -6,12 +6,22 @@ #include +#include #include #include #include #include +#include +#include +#include +#include +#include +#include +#include + #if defined(__linux__) +#include #include #elif defined(__FreeBSD__) #include @@ -27,8 +37,6 @@ #include #endif -#include - namespace { //! Return CNetAddr for the specified OS-level network address. diff --git a/src/common/netif.h b/src/common/netif.h index 769bcbccb32b..84df00a207d5 100644 --- a/src/common/netif.h +++ b/src/common/netif.h @@ -8,6 +8,7 @@ #include #include +#include //! Query the OS for the default gateway for `network`. This only makes sense for NET_IPV4 and NET_IPV6. //! Returns std::nullopt if it cannot be found, or there is no support for this OS. diff --git a/src/common/pcp.cpp b/src/common/pcp.cpp index 7b22e82eda82..96a858213d1d 100644 --- a/src/common/pcp.cpp +++ b/src/common/pcp.cpp @@ -4,19 +4,30 @@ #include -#include -#include +#include #include +#include #include #include -#include -#include +#include #include #include -#include #include -#include +#include #include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include namespace { diff --git a/src/common/pcp.h b/src/common/pcp.h index 121349b02a07..c48317f73016 100644 --- a/src/common/pcp.h +++ b/src/common/pcp.h @@ -6,10 +6,16 @@ #define BITCOIN_COMMON_PCP_H #include -#include +#include +#include +#include +#include +#include #include +class CThreadInterrupt; + // RFC6886 NAT-PMP and RFC6887 Port Control Protocol (PCP) implementation. // NAT-PMP and PCP use network byte order (big-endian). diff --git a/src/common/run_command.cpp b/src/common/run_command.cpp index 86f89e17f23e..8c57e53bf11d 100644 --- a/src/common/run_command.cpp +++ b/src/common/run_command.cpp @@ -14,6 +14,10 @@ #include #endif // ENABLE_EXTERNAL_SIGNER +#include +#include +#include + UniValue RunCommandParseJSON(const std::vector& cmd_args, const std::string& str_std_in) { #ifdef ENABLE_EXTERNAL_SIGNER diff --git a/src/common/settings.cpp b/src/common/settings.cpp index 7d511b574dea..eca29becdae8 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -2,15 +2,14 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include - #include // IWYU pragma: keep +#include + #include #include #include -#include #include #include #include diff --git a/src/common/settings.h b/src/common/settings.h index bc7b89a9b426..6f2579b128e5 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -12,7 +12,9 @@ #include #include -class UniValue; +// Users of this header need to explicitly #include +// IWYU pragma: no_include +class UniValue; // IWYU pragma: keep namespace common { diff --git a/src/common/signmessage.cpp b/src/common/signmessage.cpp index 0f9e1f5e30d7..b45951f61e7c 100644 --- a/src/common/signmessage.cpp +++ b/src/common/signmessage.cpp @@ -4,15 +4,18 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include + +#include #include #include #include #include #include +#include #include -#include #include +#include #include #include #include diff --git a/src/common/system.cpp b/src/common/system.cpp index ca7b857d983c..33918dd8d609 100644 --- a/src/common/system.cpp +++ b/src/common/system.cpp @@ -12,12 +12,12 @@ #include #ifdef WIN32 -#include -#include #include +#include #include #else #include +#include #include #endif @@ -25,8 +25,6 @@ #include #endif -#include -#include #include #include #include @@ -50,11 +48,7 @@ std::string ShellEscape(const std::string& arg) void runCommand(const std::string& strCommand) { if (strCommand.empty()) return; -#ifndef WIN32 int nErr = ::system(strCommand.c_str()); -#else - int nErr = ::_wsystem(std::wstring_convert,wchar_t>().from_bytes(strCommand).c_str()); -#endif if (nErr) { LogWarning("runCommand error: system(%s) returned %d", strCommand, nErr); } @@ -111,20 +105,17 @@ int GetNumCores() return std::thread::hardware_concurrency(); } -std::optional GetTotalRAM() +std::optional TryGetTotalRam() { - [[maybe_unused]] auto clamp{[](uint64_t v) { return size_t(std::min(v, uint64_t{std::numeric_limits::max()})); }}; + static const auto total_ram{[]() -> std::optional { #ifdef WIN32 - if (MEMORYSTATUSEX m{}; (m.dwLength = sizeof(m), GlobalMemoryStatusEx(&m))) return clamp(m.ullTotalPhys); -#elif defined(__APPLE__) || \ - defined(__FreeBSD__) || \ - defined(__NetBSD__) || \ - defined(__OpenBSD__) || \ - defined(__illumos__) || \ - defined(__linux__) - if (long p{sysconf(_SC_PHYS_PAGES)}, s{sysconf(_SC_PAGESIZE)}; p > 0 && s > 0) return clamp(1ULL * p * s); + if (MEMORYSTATUSEX m{}; (m.dwLength = sizeof(m), GlobalMemoryStatusEx(&m))) return m.ullTotalPhys; +#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__illumos__) || defined(__linux__) + if (long p{sysconf(_SC_PHYS_PAGES)}, s{sysconf(_SC_PAGESIZE)}; p > 0 && s > 0) return 1ULL * p * s; #endif - return std::nullopt; + return std::nullopt; + }()}; + return total_ram; } namespace { diff --git a/src/common/system.h b/src/common/system.h index a3100fecbc17..ad217e0db488 100644 --- a/src/common/system.h +++ b/src/common/system.h @@ -7,9 +7,9 @@ #define BITCOIN_COMMON_SYSTEM_H #include // IWYU pragma: keep + #include -#include #include #include #include @@ -35,6 +35,6 @@ int GetNumCores(); /** * Return the total RAM available on the current system, if detectable. */ -std::optional GetTotalRAM(); +std::optional TryGetTotalRam(); #endif // BITCOIN_COMMON_SYSTEM_H diff --git a/src/common/url.cpp b/src/common/url.cpp index 19db4e99dfa1..a186c5124fc7 100644 --- a/src/common/url.cpp +++ b/src/common/url.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include diff --git a/src/compressor.h b/src/compressor.h index 95490b7bd235..b6b738f65488 100644 --- a/src/compressor.h +++ b/src/compressor.h @@ -59,7 +59,7 @@ struct ScriptCompression * transactions, in which case this value becomes dependent on version * and nHeight of the enclosing transaction. */ - static const unsigned int nSpecialScripts = 6; + static constexpr unsigned int nSpecialScripts{6}; template void Ser(Stream &s, const CScript& script) { diff --git a/src/consensus/consensus.h b/src/consensus/consensus.h index 71b5fe2468d9..f1595f31d3f4 100644 --- a/src/consensus/consensus.h +++ b/src/consensus/consensus.h @@ -6,8 +6,8 @@ #ifndef BITCOIN_CONSENSUS_CONSENSUS_H #define BITCOIN_CONSENSUS_CONSENSUS_H +#include #include -#include /** The maximum allowed size for a serialized block, in bytes (only for buffer size limits) */ static const unsigned int MAX_BLOCK_SERIALIZED_SIZE = 4000000; diff --git a/src/consensus/merkle.cpp b/src/consensus/merkle.cpp index c6ae81c61420..dfa23cf897d2 100644 --- a/src/consensus/merkle.cpp +++ b/src/consensus/merkle.cpp @@ -3,9 +3,17 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include + +#include #include +#include +#include #include +#include +#include +#include + /* WARNING! If you're reading this because you're learning about crypto and/or designing a new system that will use merkle trees, keep in mind that the following merkle tree algorithm has a serious flaw related to diff --git a/src/consensus/merkle.h b/src/consensus/merkle.h index 03b5a1b5aac7..446b2df75ae8 100644 --- a/src/consensus/merkle.h +++ b/src/consensus/merkle.h @@ -5,10 +5,12 @@ #ifndef BITCOIN_CONSENSUS_MERKLE_H #define BITCOIN_CONSENSUS_MERKLE_H +#include + +#include #include -#include -#include +class CBlock; uint256 ComputeMerkleRoot(std::vector hashes, bool* mutated = nullptr); diff --git a/src/consensus/params.h b/src/consensus/params.h index 7f56729455a8..99096e06d9a8 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -11,6 +11,7 @@ #include #include +#include #include #include #include diff --git a/src/consensus/tx_check.cpp b/src/consensus/tx_check.cpp index 251417c87950..473538e4fe5e 100644 --- a/src/consensus/tx_check.cpp +++ b/src/consensus/tx_check.cpp @@ -5,8 +5,16 @@ #include #include -#include +#include #include +#include +#include