diff --git a/.github/ci-windows.py b/.github/ci-windows.py index 236c6301d017..e21a7da94a30 100755 --- a/.github/ci-windows.py +++ b/.github/ci-windows.py @@ -8,6 +8,7 @@ import shlex import subprocess import sys +import time from pathlib import Path sys.path.append(str(Path(__file__).resolve().parent.parent / "test")) @@ -73,7 +74,12 @@ def generate(ci_type): "--preset", "vs2026", ] + GENERATE_OPTIONS[ci_type] - run(command) + if run(command, check=False).returncode != 0: + print("=== ⚠️ ===") + print("Generate failure! Network issue? Retry once ...") + time.sleep(12) + print("=== ⚠️ ===") + run(command) def build(_ci_type): diff --git a/CMakeLists.txt b/CMakeLists.txt index 26e5fede0eb9..eda934cc8205 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -453,6 +453,7 @@ else() try_append_cxx_flags("-Wall" TARGET warn_interface SKIP_LINK) try_append_cxx_flags("-Wextra" TARGET warn_interface SKIP_LINK) try_append_cxx_flags("-Wgnu" TARGET warn_interface SKIP_LINK) + try_append_cxx_flags("-Wcovered-switch-default" TARGET warn_interface SKIP_LINK) # Some compilers will ignore -Wformat-security without -Wformat, so just combine the two here. try_append_cxx_flags("-Wformat -Wformat-security" TARGET warn_interface SKIP_LINK) try_append_cxx_flags("-Wvla" TARGET warn_interface SKIP_LINK) diff --git a/ci/lint/01_install.sh b/ci/lint/01_install.sh index a6963a902e73..573dbca5fe56 100755 --- a/ci/lint/01_install.sh +++ b/ci/lint/01_install.sh @@ -41,7 +41,7 @@ command -v python3 python3 --version ${CI_RETRY_EXE} pip3 install \ - lief==0.16.6 \ + lief==0.17.5 \ mypy==1.19.1 \ pyzmq==27.1.0 \ ruff==0.15.5 diff --git a/cmake/leveldb.cmake b/cmake/leveldb.cmake index e21190420ec8..cff8c61f96ca 100644 --- a/cmake/leveldb.cmake +++ b/cmake/leveldb.cmake @@ -87,6 +87,9 @@ else() try_append_cxx_flags("-Wconditional-uninitialized" TARGET nowarn_leveldb_interface SKIP_LINK IF_CHECK_PASSED "-Wno-conditional-uninitialized" ) + try_append_cxx_flags("-Wcovered-switch-default" TARGET nowarn_leveldb_interface SKIP_LINK + IF_CHECK_PASSED "-Wno-covered-switch-default" + ) endif() target_link_libraries(leveldb PRIVATE diff --git a/contrib/guix/INSTALL.md b/contrib/guix/INSTALL.md index a157acb4b75c..f6f286c03cbf 100644 --- a/contrib/guix/INSTALL.md +++ b/contrib/guix/INSTALL.md @@ -761,6 +761,21 @@ Please see the following links for more details: - A commit to skip this test is included since Guix 1.4.0: [codeberg/guix@6ba1058](https://codeberg.org/guix/guix/commit/6ba1058df0c4ce5611c2367531ae5c3cdc729ab4) +## zdiff3 + +[Currently](https://issues.guix.gnu.org/72942) `guix` builds may fail if the +global git config has `merge.conflictstyle` set to `zdiff3` as follows: + +``` +Updating channel 'guix' from Git repository at 'https://codeberg.org/guix/guix.git'... +guix time-machine: error: Git error: unknown style 'zdiff3' given for 'merge.conflictstyle' +``` + +This can be fixed by setting `merge.conflictstyle` to `diff3`: + +```bash +git config --global merge.conflictstyle diff3 +``` [install-script]: #options-1-and-2-using-the-official-shell-installer-script-or-binary-tarball [install-bin-tarball]: #options-1-and-2-using-the-official-shell-installer-script-or-binary-tarball @@ -782,7 +797,9 @@ an irreversible way, you may want to completely purge Guix from your system and start over. 1. Uninstall Guix itself according to the way you installed it (e.g. `sudo apt - purge guix` for Ubuntu packaging, `sudo make uninstall` for a build from source). + purge guix` for Ubuntu packaging, `sudo make uninstall` for a build from + source, or running the GUIX [install script][install-script] with the + `--uninstall` [flag](https://guix.gnu.org/manual/devel/en/guix.html#index-uninstalling-Guix)). 2. Remove all build users and groups You may check for relevant users and groups using: diff --git a/contrib/guix/guix-build b/contrib/guix/guix-build index ee285bf322cf..bef1c8412a7b 100755 --- a/contrib/guix/guix-build +++ b/contrib/guix/guix-build @@ -383,6 +383,8 @@ EOF # Running in an isolated container minimizes build-time differences # between machines and improves reproducibility # + # --writable-root make the root filesystem writable + # # --pure unset existing environment variables # # Same rationale as --container @@ -441,6 +443,7 @@ EOF # shellcheck disable=SC2086,SC2031 time-machine shell --manifest="${PWD}/contrib/guix/manifest.scm" \ --container \ + --writable-root \ --pure \ --no-cwd \ --share="$PWD"=/bitcoin \ diff --git a/contrib/guix/guix-codesign b/contrib/guix/guix-codesign index 791b75c540bc..39291dfe9ceb 100755 --- a/contrib/guix/guix-codesign +++ b/contrib/guix/guix-codesign @@ -299,6 +299,8 @@ EOF # Running in an isolated container minimizes build-time differences # between machines and improves reproducibility # + # --writable-root make the root filesystem writable + # # --pure unset existing environment variables # # Same rationale as --container @@ -341,6 +343,7 @@ EOF # shellcheck disable=SC2086,SC2031 time-machine shell --manifest="${PWD}/contrib/guix/manifest.scm" \ --container \ + --writable-root \ --pure \ --no-cwd \ --share="$PWD"=/bitcoin \ diff --git a/contrib/guix/libexec/build.sh b/contrib/guix/libexec/build.sh index 38f3958eb24f..51354273efae 100755 --- a/contrib/guix/libexec/build.sh +++ b/contrib/guix/libexec/build.sh @@ -6,7 +6,7 @@ export LC_ALL=C set -e -o pipefail # Environment variables for determinism -export TAR_OPTIONS="--owner=0 --group=0 --numeric-owner --mtime='@${SOURCE_DATE_EPOCH}' --sort=name" +export TAR_OPTIONS="--no-same-owner --owner=0 --group=0 --numeric-owner --mtime='@${SOURCE_DATE_EPOCH}' --sort=name" export TZ=UTC # Although Guix _does_ set umask when building its own packages (in our case, @@ -272,10 +272,6 @@ mkdir -p "$DISTSRC" # Install built Bitcoin Core to $INSTALLPATH case "$HOST" in *darwin*) - # This workaround can be dropped for CMake >= 3.27. - # See the upstream commit 689616785f76acd844fd448c51c5b2a0711aafa2. - find build -name 'cmake_install.cmake' -exec sed -i 's| -u -r | |g' {} + - cmake --install build --strip --prefix "${INSTALLPATH}" ${V:+--verbose} ;; *) diff --git a/contrib/guix/libexec/prelude.bash b/contrib/guix/libexec/prelude.bash index b7c13cc91d8c..166675e8bf09 100644 --- a/contrib/guix/libexec/prelude.bash +++ b/contrib/guix/libexec/prelude.bash @@ -71,7 +71,7 @@ fi time-machine() { # shellcheck disable=SC2086 guix time-machine --url=https://codeberg.org/guix/guix.git \ - --commit=5cb84f2013c5b1e48a7d0e617032266f1e6059e2 \ + --commit=c5eee3336cc1d10a3cc1c97fde2809c3451624d3 \ --cores="$JOBS" \ --keep-failed \ --fallback \ diff --git a/contrib/guix/manifest.scm b/contrib/guix/manifest.scm index 9cadd410537c..710178ddf444 100644 --- a/contrib/guix/manifest.scm +++ b/contrib/guix/manifest.scm @@ -1,12 +1,11 @@ (use-modules (gnu packages) ((gnu packages bash) #:select (bash-minimal)) (gnu packages bison) - ((gnu packages certs) #:select (nss-certs)) - ((gnu packages check) #:select (libfaketime)) ((gnu packages cmake) #:select (cmake-minimal)) (gnu packages commencement) (gnu packages compression) (gnu packages cross-base) + ((gnu packages crypto) #:select (osslsigncode)) (gnu packages gawk) (gnu packages gcc) ((gnu packages installers) #:select (nsis-x86_64)) @@ -17,9 +16,8 @@ (gnu packages pkg-config) ((gnu packages python) #:select (python-minimal)) ((gnu packages python-build) #:select (python-poetry-core)) - ((gnu packages python-crypto) #:select (python-asn1crypto)) - ((gnu packages python-science) #:select (python-scikit-build-core)) - ((gnu packages python-xyz) #:select (python-pydantic-2)) + ((gnu packages python-crypto) #:select (python-asn1crypto python-oscrypto)) + ((gnu packages python-xyz) #:select (python-lief)) ((gnu packages tls) #:select (openssl)) ((gnu packages version-control) #:select (git-minimal)) (guix build-system cmake) @@ -95,25 +93,17 @@ chain for " target " development.")) (license (package-license xgcc))))) (define base-gcc - (package - (inherit gcc-14) ;; 14.2.0 - (version "14.3.0") - (source (origin - (method url-fetch) - (uri (string-append "mirror://gnu/gcc/gcc-" - version "/gcc-" version ".tar.xz")) - (sha256 - (base32 - "0fna78ly417g69fdm4i5f3ms96g8xzzjza8gwp41lqr5fqlpgp70")))))) + (package-with-extra-patches gcc-14 + (search-our-patches "gcc-remap-guix-store.patch" "gcc-ssa-generation.patch"))) (define base-linux-kernel-headers linux-libre-headers-6.1) (define* (make-bitcoin-cross-toolchain target #:key - (base-gcc-for-libc (gcc-libgcc-patches linux-base-gcc)) + (base-gcc-for-libc linux-base-gcc) (base-kernel-headers base-linux-kernel-headers) (base-libc glibc-2.31) - (base-gcc (gcc-libgcc-patches linux-base-gcc))) + (base-gcc linux-base-gcc)) "Convenience wrapper around MAKE-CROSS-TOOLCHAIN with default values desirable for building Bitcoin Core release binaries." (make-cross-toolchain target @@ -122,10 +112,6 @@ desirable for building Bitcoin Core release binaries." base-libc base-gcc)) -(define (gcc-libgcc-patches gcc) - (package-with-extra-patches gcc - (search-our-patches "gcc-remap-guix-store.patch" "gcc-ssa-generation.patch"))) - (define (binutils-mingw-patches binutils) (package-with-extra-patches binutils (search-our-patches "binutils-unaligned-default.patch"))) @@ -139,10 +125,10 @@ desirable for building Bitcoin Core release binaries." (let* ((xbinutils (binutils-mingw-patches (cross-binutils target))) (machine (substring target 0 (string-index target #\-))) (pthreads-xlibc (winpthreads-patches (make-mingw-w64 machine - #:xgcc (cross-gcc target #:xgcc (gcc-libgcc-patches base-gcc)) + #:xgcc (cross-gcc target #:xgcc base-gcc) #:with-winpthreads? #t))) (pthreads-xgcc (cross-gcc target - #:xgcc (gcc-libgcc-patches mingw-w64-base-gcc) + #:xgcc mingw-w64-base-gcc #:xbinutils xbinutils #:libc pthreads-xlibc))) ;; Define a meta-package that propagates the resulting XBINUTILS, XLIBC, and @@ -164,80 +150,6 @@ chain for " target " development.")) (home-page (package-home-page pthreads-xgcc)) (license (package-license pthreads-xgcc))))) -;; While LIEF is packaged in Guix, we maintain our own package, -;; to simplify building, and more easily apply updates. -;; Moreover, the Guix's package uses cmake, which caused build -;; failure; see https://github.com/bitcoin/bitcoin/pull/27296. -(define-public python-lief - (package - (name "python-lief") - (version "0.16.6") - (source (origin - (method git-fetch) - (uri (git-reference - (url "https://github.com/lief-project/LIEF") - (commit version))) - (file-name (git-file-name name version)) - (sha256 - (base32 - "1pq9nagrnkl1x943bqnpiyxmkd9vk99znfxiwqp6vf012b50bz2a")) - (patches (search-our-patches "lief-scikit-0-9.patch")))) - (build-system pyproject-build-system) - (native-inputs (list cmake-minimal - ninja - python-scikit-build-core - python-pydantic-2)) - (arguments - (list - #:tests? #f ;needs network - #:phases #~(modify-phases %standard-phases - (add-before 'build 'set-pythonpath - (lambda _ - (setenv "PYTHONPATH" - (string-append (string-append (getcwd) "/api/python/backend") - ":" (or (getenv "PYTHONPATH") ""))))) - (add-after 'set-pythonpath 'change-directory - (lambda _ - (chdir "api/python")))))) - (home-page "https://github.com/lief-project/LIEF") - (synopsis "Library to instrument executable formats") - (description - "@code{python-lief} is a cross platform library which can parse, modify -and abstract ELF, PE and MachO formats.") - (license license:asl2.0))) - -(define osslsigncode - (package - (name "osslsigncode") - (version "2.5") - (source (origin - (method git-fetch) - (uri (git-reference - (url "https://github.com/mtrojnar/osslsigncode") - (commit version))) - (sha256 - (base32 - "1j47vwq4caxfv0xw68kw5yh00qcpbd56d7rq6c483ma3y7s96yyz")))) - (build-system cmake-build-system) - (arguments - (list - #:phases - #~(modify-phases %standard-phases - (replace 'check - (lambda* (#:key tests? #:allow-other-keys) - (if tests? - (invoke "faketime" "-f" "@2025-01-01 00:00:00" ;; Tests fail after 2025. - "ctest" "--output-on-failure" "--no-tests=error") - (format #t "test suite not run~%"))))))) - (inputs (list libfaketime openssl)) - (home-page "https://github.com/mtrojnar/osslsigncode") - (synopsis "Authenticode signing and timestamping tool") - (description "osslsigncode is a small tool that implements part of the -functionality of the Microsoft tool signtool.exe - more exactly the Authenticode -signing and timestamping. But osslsigncode is based on OpenSSL and cURL, and -thus should be able to compile on most platforms where these exist.") - (license license:gpl3+))) ; license is with openssl exception - (define-public python-elfesteem (let ((commit "2eb1e5384ff7a220fd1afacd4a0170acff54fe56")) (package @@ -262,64 +174,6 @@ thus should be able to compile on most platforms where these exist.") (description "elfesteem parses ELF, PE and Mach-O files.") (license license:lgpl2.1)))) -(define-public python-oscrypto - (package - (name "python-oscrypto") - (version "1.3.0") - (source - (origin - (method git-fetch) - (uri (git-reference - (url "https://github.com/wbond/oscrypto") - (commit version))) - (file-name (git-file-name name version)) - (sha256 - (base32 - "1v5wkmzcyiqy39db8j2dvkdrv2nlsc48556h73x4dzjwd6kg4q0a")) - (patches (search-our-patches "oscrypto-hard-code-openssl.patch")))) - (build-system python-build-system) - (native-search-paths - (list (search-path-specification - (variable "SSL_CERT_FILE") - (file-type 'regular) - (separator #f) ;single entry - (files '("etc/ssl/certs/ca-certificates.crt"))))) - - (propagated-inputs - (list python-asn1crypto openssl)) - (arguments - `(#:phases - (modify-phases %standard-phases - (add-after 'unpack 'hard-code-path-to-libscrypt - (lambda* (#:key inputs #:allow-other-keys) - (let ((openssl (assoc-ref inputs "openssl"))) - (substitute* "oscrypto/__init__.py" - (("@GUIX_OSCRYPTO_USE_OPENSSL@") - (string-append openssl "/lib/libcrypto.so" "," openssl "/lib/libssl.so"))) - #t))) - (add-after 'unpack 'disable-broken-tests - (lambda _ - ;; This test is broken as there is no keyboard interrupt. - (substitute* "tests/test_trust_list.py" - (("^(.*)class TrustListTests" line indent) - (string-append indent - "@unittest.skip(\"Disabled by Guix\")\n" - line))) - (substitute* "tests/test_tls.py" - (("^(.*)class TLSTests" line indent) - (string-append indent - "@unittest.skip(\"Disabled by Guix\")\n" - line))) - #t)) - (replace 'check - (lambda _ - (invoke "python" "run.py" "tests") - #t))))) - (home-page "https://github.com/wbond/oscrypto") - (synopsis "Compiler-free Python crypto library backed by the OS") - (description "oscrypto is a compilation-free, always up-to-date encryption library for Python.") - (license license:expat))) - (define-public python-oscryptotests (package (inherit python-oscrypto) (name "python-oscryptotests") @@ -351,7 +205,8 @@ thus should be able to compile on most platforms where these exist.") "1qw2k7xis53179lpqdqyylbcmp76lj7sagp883wmxg5i7chhc96k")))) (build-system python-build-system) (propagated-inputs - (list python-asn1crypto + (list openssl + python-asn1crypto python-oscrypto python-oscryptotests)) ;; certvalidator tests import oscryptotests (arguments @@ -480,7 +335,7 @@ inspecting signatures in Mach-O binaries.") #t)))))))) (define-public glibc-2.31 - (let ((commit "7b27c450c34563a28e634cccb399cd415e71ebfe")) + (let ((commit "28eb5caf895ced5d895cb02757e109004a2d33e5")) (package (inherit glibc) ;; 2.39 (version "2.31") @@ -492,7 +347,7 @@ inspecting signatures in Mach-O binaries.") (file-name (git-file-name "glibc" commit)) (sha256 (base32 - "017qdpr5id7ddb4lpkzj2li1abvw916m3fc6n7nw28z4h5qbv2n0")) + "07arjrc1smqy8wrhg38apr1s9ji7xv1rpzdapk4k2ps2n07irp58")) (patches (search-our-patches "glibc-guix-prefix.patch" "glibc-riscv-jumptarget.patch")))) (arguments @@ -545,7 +400,7 @@ inspecting signatures in Mach-O binaries.") gnu-make ninja ;; Scripting - python-minimal ;; (3.10) + python-minimal ;; (3.11) ;; Git git-minimal ;; Tests @@ -555,7 +410,6 @@ inspecting signatures in Mach-O binaries.") (list zip (make-mingw-pthreads-cross-toolchain "x86_64-w64-mingw32") nsis-x86_64 - nss-certs osslsigncode)) ((string-contains target "-linux-") (list bison diff --git a/contrib/guix/patches/gcc-ssa-generation.patch b/contrib/guix/patches/gcc-ssa-generation.patch index 2e5a600230ec..7054fbf3d0b4 100644 --- a/contrib/guix/patches/gcc-ssa-generation.patch +++ b/contrib/guix/patches/gcc-ssa-generation.patch @@ -1,3 +1,8 @@ +This patch can be removed when using GCC 14.4, 15.3 or 16.x. +14.x: https://github.com/gcc-mirror/gcc/commit/2d7099faa5c59b871e3027268d70a8a46d892824 +15.x: https://github.com/gcc-mirror/gcc/commit/7debee2cb6503b2af0f1d43b0e56b759474396d5 +16.x: https://github.com/gcc-mirror/gcc/commit/c6085ca0ed4cef3bcf4eb382cb71e44219c10f6e + commit b46614ebfc57ccca8a050668ad0e8ba5968c5943 Author: Jakub Jelinek Date: Tue Jan 6 08:36:20 2026 +0100 diff --git a/contrib/guix/patches/lief-scikit-0-9.patch b/contrib/guix/patches/lief-scikit-0-9.patch deleted file mode 100644 index 71e617834f07..000000000000 --- a/contrib/guix/patches/lief-scikit-0-9.patch +++ /dev/null @@ -1,21 +0,0 @@ -Partially revert f23ced2f4ffc170d0a6f40ff4a1bee575e3447cf - -Restore compat with python-scikit-build-core 0.9.x -Can be dropped when using python-scikit-build-core >= 0.10.x - ---- a/api/python/backend/setup.py -+++ b/api/python/backend/setup.py -@@ -101,12 +101,12 @@ def _get_hooked_config(is_editable: bool) -> Optional[dict[str, Union[str, List[ - config_settings = { - "logging.level": "DEBUG", - "build-dir": config.build_dir, -- "build.targets": config.build.targets, - "install.strip": config.strip, - "backport.find-python": "0", - "wheel.py-api": config.build.py_api, - "cmake.source-dir": SRC_DIR.as_posix(), - "cmake.build-type": config.build.build_type, -+ "cmake.targets": config.build.targets, - "cmake.args": [ - *config.cmake_generator, - *config.get_cmake_args(is_editable), diff --git a/contrib/guix/patches/oscrypto-hard-code-openssl.patch b/contrib/guix/patches/oscrypto-hard-code-openssl.patch deleted file mode 100644 index 32027f2d09af..000000000000 --- a/contrib/guix/patches/oscrypto-hard-code-openssl.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/oscrypto/__init__.py b/oscrypto/__init__.py -index eb27313..371ab24 100644 ---- a/oscrypto/__init__.py -+++ b/oscrypto/__init__.py -@@ -302,3 +302,8 @@ def load_order(): - 'oscrypto._win.tls', - 'oscrypto.tls', - ] -+ -+ -+paths = '@GUIX_OSCRYPTO_USE_OPENSSL@'.split(',') -+assert len(paths) == 2, 'Value for OSCRYPTO_USE_OPENSSL env var must be two paths separated by a comma' -+use_openssl(*paths) diff --git a/contrib/guix/patches/winpthreads-remap-guix-store.patch b/contrib/guix/patches/winpthreads-remap-guix-store.patch index e1f1a6eba531..4530e5f3eea0 100644 --- a/contrib/guix/patches/winpthreads-remap-guix-store.patch +++ b/contrib/guix/patches/winpthreads-remap-guix-store.patch @@ -6,12 +6,12 @@ the package, map all guix store prefixes to something fixed, e.g. /usr. --- a/mingw-w64-libraries/winpthreads/Makefile.in +++ b/mingw-w64-libraries/winpthreads/Makefile.in -@@ -478,7 +478,7 @@ top_build_prefix = @top_build_prefix@ +@@ -465,7 +465,7 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = . tests --AM_CFLAGS = -Wall -DWIN32_LEAN_AND_MEAN $(am__append_1) -+AM_CFLAGS = -Wall -DWIN32_LEAN_AND_MEAN $(am__append_1) $(shell find /gnu/store -maxdepth 1 -mindepth 1 -type d -exec echo -n " -ffile-prefix-map={}=/usr" \;) +-AM_CFLAGS = $(am__append_1) $(am__append_3) ++AM_CFLAGS = $(am__append_1) $(am__append_3) $(shell find /gnu/store -maxdepth 1 -mindepth 1 -type d -exec echo -n " -ffile-prefix-map={}=/usr" \;) ACLOCAL_AMFLAGS = -I m4 lib_LTLIBRARIES = libwinpthread.la - include_HEADERS = include/pthread.h include/sched.h include/semaphore.h include/pthread_unistd.h include/pthread_time.h include/pthread_compat.h include/pthread_signal.h + include_HEADERS = \ diff --git a/contrib/guix/symbol-check.py b/contrib/guix/symbol-check.py index 93002ddce798..d31d5aa83bcf 100755 --- a/contrib/guix/symbol-check.py +++ b/contrib/guix/symbol-check.py @@ -241,7 +241,7 @@ def check_MACHO_sdk(binary) -> bool: return False def check_MACHO_lld(binary) -> bool: - if binary.build_version.tools[0].version == [19, 1, 4]: + if binary.build_version.tools[0].version == [19, 1, 7]: return True return False diff --git a/doc/developer-notes.md b/doc/developer-notes.md index d8ce01c8118b..496fa8ef0bf3 100644 --- a/doc/developer-notes.md +++ b/doc/developer-notes.md @@ -854,19 +854,19 @@ Foo(vec); enum class Tabs { info, console, - network_graph, - peers }; int GetInt(Tabs tab) { - switch (tab) { - case Tabs::info: return 0; - case Tabs::console: return 1; - case Tabs::network_graph: return 2; - case Tabs::peers: return 3; - } // no default case, so the compiler can warn about missing cases - assert(false); + int ret = [&]() { + switch (tab) { + case Tabs::info: return 0; + case Tabs::console: return 1; + } // no default case, so the compiler can warn about missing cases + assert(false); + }(); + LogInfo("Tab %s", ret); + return ret; } ``` diff --git a/doc/release-notes-29060.md b/doc/release-notes-29060.md new file mode 100644 index 000000000000..bb11dc91365f --- /dev/null +++ b/doc/release-notes-29060.md @@ -0,0 +1,10 @@ +- Logging and RPC + + - Bitcoin Core now reports a debug message explaining why transaction inputs are non-standard. + + - This information is now returned in the responses of the transaction-sending RPCs `submitpackage`, + `sendrawtransaction`, and `testmempoolaccept`, and is also logged to `debug.log` (if `mempoolrej` ++ debug category is enabled) when such transactions are received over the P2P network. + + - This does not change the existing error code `bad-txns-nonstandard-inputs`, but instead adds additional debug information to it. + diff --git a/src/bench/ccoins_caching.cpp b/src/bench/ccoins_caching.cpp index 2b7315f4c169..82735b3286ed 100644 --- a/src/bench/ccoins_caching.cpp +++ b/src/bench/ccoins_caching.cpp @@ -49,8 +49,7 @@ static void CCoinsCaching(benchmark::Bench& bench) // Benchmark. const CTransaction tx_1(t1); bench.run([&] { - bool success{AreInputsStandard(tx_1, coins)}; - assert(success); + assert(ValidateInputsStandardness(tx_1, coins).IsValid()); }); } diff --git a/src/bench/sign_transaction.cpp b/src/bench/sign_transaction.cpp index 96af48c57248..5405265b230e 100644 --- a/src/bench/sign_transaction.cpp +++ b/src/bench/sign_transaction.cpp @@ -42,12 +42,15 @@ static void SignTransactionSingleInput(benchmark::Bench& bench, InputType input_ keystore.pubkeys.emplace(key_id, pubkey); // Create specified locking script type - CScript prev_spk; - switch (input_type) { - case InputType::P2WPKH: prev_spk = GetScriptForDestination(WitnessV0KeyHash(pubkey)); break; - case InputType::P2TR: prev_spk = GetScriptForDestination(WitnessV1Taproot(XOnlyPubKey{pubkey})); break; - default: assert(false); - } + CScript prev_spk = [&]() { + switch (input_type) { + case InputType::P2WPKH: + return GetScriptForDestination(WitnessV0KeyHash(pubkey)); + case InputType::P2TR: + return GetScriptForDestination(WitnessV1Taproot(XOnlyPubKey{pubkey})); + } // no default case, so the compiler can warn about missing cases + assert(false); + }(); prev_spks.push_back(prev_spk); } diff --git a/src/bench/verify_script.cpp b/src/bench/verify_script.cpp index 1ef6a3613f49..b0ef4988ce11 100644 --- a/src/bench/verify_script.cpp +++ b/src/bench/verify_script.cpp @@ -41,12 +41,13 @@ static void VerifyScriptBench(benchmark::Bench& bench, ScriptType script_type) keystore.pubkeys.emplace(key_id, pubkey); // Create crediting and spending transactions with provided input type - CTxDestination dest; - switch (script_type) { - case ScriptType::P2WPKH: dest = WitnessV0KeyHash(pubkey); break; - case ScriptType::P2TR: dest = WitnessV1Taproot(XOnlyPubKey{pubkey}); break; - default: assert(false); - } + const auto dest{[&]() -> CTxDestination { + switch (script_type) { + case ScriptType::P2WPKH: return WitnessV0KeyHash(pubkey); + case ScriptType::P2TR: return WitnessV1Taproot(XOnlyPubKey{pubkey}); + } // no default case, so the compiler can warn about missing cases + assert(false); + }()}; const CMutableTransaction& txCredit = BuildCreditingTransaction(GetScriptForDestination(dest), 1); CMutableTransaction txSpend = BuildSpendingTransaction(/*scriptSig=*/{}, /*scriptWitness=*/{}, CTransaction(txCredit)); diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index 323e7577a4db..32db3e7282e4 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -224,7 +224,7 @@ static bool AppInit(NodeContext& node) if (token) { // Success exit(EXIT_SUCCESS); } else { // fRet = false or token read error (premature exit). - tfm::format(std::cerr, "Error during initialization - check debug.log for details\n"); + tfm::format(std::cerr, "Error during initialization - check %s for details\n", fs::PathToString(LogInstance().m_file_path.filename())); exit(EXIT_FAILURE); } } diff --git a/src/common/args.cpp b/src/common/args.cpp index 2a9a3c19fa54..12e0f26ed214 100644 --- a/src/common/args.cpp +++ b/src/common/args.cpp @@ -717,9 +717,9 @@ std::string ArgsManager::GetHelpMessage() const case OptionsCategory::CLI_COMMANDS: usage += HelpMessageGroup("CLI Commands:"); break; - default: + case OptionsCategory::HIDDEN: break; - } + } // no default case, so the compiler can warn about missing cases // When we get to the hidden options, stop if (arg_map.first == OptionsCategory::HIDDEN) break; diff --git a/src/common/messages.cpp b/src/common/messages.cpp index 637ec62af895..12e32cae806e 100644 --- a/src/common/messages.cpp +++ b/src/common/messages.cpp @@ -66,9 +66,8 @@ std::string FeeModeInfo(const std::pair& mode, std return strprintf("%s estimates use a longer time horizon, making them\n" "less responsive to short-term drops in the prevailing fee market. This mode\n" "potentially returns a higher fee rate estimate.\n", mode.first); - default: - assert(false); - } + } // no default case, so the compiler can warn about missing cases + assert(false); } std::string FeeModesDetail(std::string default_info) @@ -119,8 +118,7 @@ bilingual_str PSBTErrorString(PSBTError err) return Untranslated("Input needs additional signatures or other data"); case PSBTError::OK: return Untranslated("No errors"); - // no default case, so the compiler can warn about missing cases - } + } // no default case, so the compiler can warn about missing cases assert(false); } @@ -143,8 +141,7 @@ bilingual_str TransactionErrorString(const TransactionError err) return Untranslated("Unspendable output exceeds maximum configured by user (maxburnamount)"); case TransactionError::INVALID_PACKAGE: return Untranslated("Transaction rejected due to invalid package"); - // no default case, so the compiler can warn about missing cases - } + } // no default case, so the compiler can warn about missing cases assert(false); } diff --git a/src/common/signmessage.cpp b/src/common/signmessage.cpp index a86310e1d49f..0f9e1f5e30d7 100644 --- a/src/common/signmessage.cpp +++ b/src/common/signmessage.cpp @@ -87,7 +87,6 @@ std::string SigningResultString(const SigningResult res) return "Private key not available"; case SigningResult::SIGNING_FAILED: return "Sign failed"; - // no default case, so the compiler can warn about missing cases - } + } // no default case, so the compiler can warn about missing cases assert(false); } diff --git a/src/init/common.cpp b/src/init/common.cpp index cb35c1b4f62a..f65e3c92d133 100644 --- a/src/init/common.cpp +++ b/src/init/common.cpp @@ -40,7 +40,7 @@ void AddLoggingArgs(ArgsManager& argsman) argsman.AddArg("-loglevelalways", strprintf("Always prepend a category and level (default: %u)", DEFAULT_LOGLEVELALWAYS), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); argsman.AddArg("-logratelimit", strprintf("Apply rate limiting to unconditional logging to mitigate disk-filling attacks (default: %u)", BCLog::DEFAULT_LOGRATELIMIT), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST); argsman.AddArg("-printtoconsole", "Send trace/debug info to console (default: 1 when no -daemon. To disable logging to file, set -nodebuglogfile)", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); - argsman.AddArg("-shrinkdebugfile", "Shrink debug.log file on client startup (default: 1 when no -debug)", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); + argsman.AddArg("-shrinkdebugfile", "Shrink debug log file on client startup (default: 1 when no -debug)", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); } void SetLoggingOptions(const ArgsManager& args) diff --git a/src/node/abort.cpp b/src/node/abort.cpp index a7c815363b2d..9483e56ae9a9 100644 --- a/src/node/abort.cpp +++ b/src/node/abort.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -18,7 +19,7 @@ namespace node { void AbortNode(const std::function& shutdown_request, std::atomic& exit_status, const bilingual_str& message, node::Warnings* warnings) { if (warnings) warnings->Set(Warning::FATAL_INTERNAL_ERROR, message); - InitError(_("A fatal internal error occurred, see debug.log for details: ") + message); + InitError(strprintf(_("A fatal internal error occurred, see %s for details: %s"), fs::PathToString(LogInstance().m_file_path.filename()), message)); exit_status.store(EXIT_FAILURE); if (shutdown_request && !shutdown_request()) { LogError("Failed to send shutdown signal\n"); diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 46ec238c3b18..83ceb63cbcd7 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -18,6 +18,7 @@ #include