From 7444a2bb2ab98195880e9f876359d9f75e3209cf Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Wed, 29 Jul 2026 01:32:51 +0700 Subject: [PATCH 01/14] fix: make sanitizer reports symbolizable Mainstream it has been done in #14673 but not properly backported so far as we hadn't use travis Sanitizers that cannot find it print raw addresses instead of source locations, and a suppression file cannot match a stack of raw addresses. Current CI image registers update-alternatives slaves for llvm-ar, llvm-cov, llvm-nm, llvm-objdump, llvm-ranlib and llvm-strip, but not llvm-symbolizer, so /usr/bin/llvm-symbolizer does not exist. That fixes issue discovered in #5379: ********* Finished testing of TrafficGraphDataTests ********* ~BitcoinApplication : Stopping thread ~BitcoinApplication : Stopped thread ==28475==WARNING: invalid path to external symbolizer! ==28475==WARNING: Failed to use and restart external symbolizer! ================================================================= ==28475==ERROR: LeakSanitizer: detected memory leaks Direct leak of 520 byte(s) in 13 object(s) allocated from: #0 0x55fc08e2353d (/builds/dashpay/dash/build-ci/dashcore-linux64_asan/src/qt/test/test_dash-qt+0x779153d) #1 0x7f7a7724bd85 () --- contrib/containers/ci/ci.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/containers/ci/ci.Dockerfile b/contrib/containers/ci/ci.Dockerfile index 42df9b08018c..d353decbc592 100644 --- a/contrib/containers/ci/ci.Dockerfile +++ b/contrib/containers/ci/ci.Dockerfile @@ -48,7 +48,7 @@ RUN set -ex; \ rm -rf /var/lib/apt/lists/*; \ echo "Setting defaults..."; \ llvmUpdAltArgs="update-alternatives --install /usr/bin/llvm-config llvm-config /usr/bin/llvm-config-${LLVM_VERSION} 100"; \ - for binName in clang clang++ clang-apply-replacements clang-format clang-tidy clangd dsymutil lld lldb lldb-server llvm-ar llvm-cov llvm-nm llvm-objdump llvm-ranlib llvm-strip run-clang-tidy; do \ + for binName in clang clang++ clang-apply-replacements clang-format clang-tidy clangd dsymutil lld lldb lldb-server llvm-ar llvm-cov llvm-nm llvm-objdump llvm-ranlib llvm-strip llvm-symbolizer run-clang-tidy; do \ llvmUpdAltArgs="${llvmUpdAltArgs} --slave /usr/bin/${binName} ${binName} /usr/bin/${binName}-${LLVM_VERSION}"; \ done; \ for binName in ld64.lld ld.lld lld-link wasm-ld; do \ From 75b5a222cfaa29cea0de63a2af232254cb8b7f36 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Wed, 29 Jul 2026 01:33:40 +0700 Subject: [PATCH 02/14] fix: grant SYS_PTRACE to build and test containers Mainstream it has been done in bitcoin#15022 and later in bitcoin#16582 but hasn't been properly backported. LeakSanitizer suspends every thread through ptrace to walk the heap. In a container without CAP_SYS_PTRACE that call fails and the process dies before any leak is reported, so the job fails without saying why. ci/test/04_install.sh already encodes this for the legacy local path, but GitHub Actions builds and runs the unit tests inside the container declared by these two reusable workflows, which never granted the capability. --- .github/workflows/build-src.yml | 4 +++- .github/workflows/test-src.yml | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-src.yml b/.github/workflows/build-src.yml index 8ea9ba443378..47a757d3941e 100644 --- a/.github/workflows/build-src.yml +++ b/.github/workflows/build-src.yml @@ -51,7 +51,9 @@ jobs: key: ${{ steps.bundle.outputs.key }} container: image: ${{ inputs.container-path }} - options: --user root + # SYS_PTRACE is required by LeakSanitizer's stop-the-world + # (https://github.com/google/sanitizers/issues/764) + options: --user root --cap-add SYS_PTRACE steps: - name: Checkout code uses: actions/checkout@v6 diff --git a/.github/workflows/test-src.yml b/.github/workflows/test-src.yml index f27751be60a2..795a665f03e4 100644 --- a/.github/workflows/test-src.yml +++ b/.github/workflows/test-src.yml @@ -30,7 +30,9 @@ jobs: runs-on: ${{ inputs.runs-on }} container: image: ${{ inputs.container-path }} - options: --user root + # SYS_PTRACE is required by LeakSanitizer's stop-the-world + # (https://github.com/google/sanitizers/issues/764) + options: --user root --cap-add SYS_PTRACE steps: - name: Checkout code uses: actions/checkout@v6 From 6fea7b97be5e5814b2c896a6a5c841d445b03109 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Fri, 26 Jan 2024 11:26:52 +0000 Subject: [PATCH 03/14] Merge bitcoin/bitcoin#28875: build: Pass sanitize flags to instrument `libsecp256k1` code cbea49c0d32badb975fbf22d44f8e25cc7972af7 build: Pass sanitize flags to instrument `libsecp256k1` code (Hennadii Stepanov) Pull request description: This PR is a revived https://github.com/bitcoin/bitcoin/pull/27991 with an addressed [comment](https://github.com/bitcoin/bitcoin/pull/27991#discussion_r1252148488). Fixes https://github.com/bitcoin/bitcoin/issues/27990. Might be tested as follows: ``` $ ./autogen.sh && ./configure --enable-fuzz --with-sanitizers=fuzzer CC=clang-13 CXX=clang++-13 $ make clean > /dev/null && make $ objdump --disassemble=secp256k1_xonly_pubkey_serialize src/test/fuzz/fuzz | grep __sanitizer_cov 1953bd0:e8 bb c6 05 ff call 9b0290 <__sanitizer_cov_trace_const_cmp8> 1953d32:e8 69 c4 05 ff call 9b01a0 <__sanitizer_cov_trace_pc_indir> 1953d58:e8 43 c4 05 ff call 9b01a0 <__sanitizer_cov_trace_pc_indir> 1953d82:e8 19 c4 05 ff call 9b01a0 <__sanitizer_cov_trace_pc_indir> ``` ACKs for top commit: fanquake: ACK cbea49c0d32badb975fbf22d44f8e25cc7972af7 dergoegge: reACK cbea49c0d32badb975fbf22d44f8e25cc7972af7 Tree-SHA512: 801994e75b711d20eaf0d675f378da07d693f4a7de026efd93860f5f1deabed855a83eca3561725263e4fe605fcc5f91eb73c021ec91c831864e6deb575e3885 (cherry picked from commit e3b68b3b833984973401ceff43930f7c56a83f29) Co-authored-by: fanquake --- configure.ac | 8 ++++++-- test/sanitizer_suppressions/ubsan | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 1fcbafbd99fd..d36f8046cfa2 100644 --- a/configure.ac +++ b/configure.ac @@ -393,7 +393,8 @@ if test "$use_sanitizers" != ""; then dnl fail if a bad argument is passed, e.g. -fsanitize=undfeined AX_CHECK_COMPILE_FLAG( [-fsanitize=$use_sanitizers], - [SANITIZER_CXXFLAGS="-fsanitize=$use_sanitizers"], + [SANITIZER_CXXFLAGS="-fsanitize=$use_sanitizers" + SANITIZER_CFLAGS="-fsanitize=$use_sanitizers"], [AC_MSG_ERROR([compiler did not accept requested flags])]) dnl Some compilers (e.g. GCC) require additional libraries like libasan, @@ -2073,6 +2074,9 @@ CPPFLAGS_TEMP="$CPPFLAGS" unset CPPFLAGS CPPFLAGS="$CPPFLAGS_TEMP" +if test -n "$use_sanitizers"; then + export SECP_CFLAGS="$SECP_CFLAGS $SANITIZER_CFLAGS" +fi ac_configure_args="${ac_configure_args} --disable-shared --with-pic --enable-benchmark=no --enable-module-recovery --disable-module-ecdh --disable-openssl-tests" AC_CONFIG_SUBDIRS([src/dashbls src/secp256k1]) @@ -2133,7 +2137,7 @@ echo " target os = $host_os" echo " build os = $build_os" echo echo " CC = $CC" -echo " CFLAGS = $BACKTRACE_FLAGS $DEBUG_CFLAGS $PTHREAD_CFLAGS $CFLAGS" +echo " CFLAGS = $SANITIZER_CFLAGS $BACKTRACE_FLAGS $DEBUG_CFLAGS $PTHREAD_CFLAGS $CFLAGS" echo " CPPFLAGS = $DEBUG_CPPFLAGS $HARDENED_CPPFLAGS $CORE_CPPFLAGS $CPPFLAGS" echo " CXX = $CXX" echo " CXXFLAGS = $BACKTRACE_FLAGS $DEBUG_CXXFLAGS $HARDENED_CXXFLAGS $WARN_CXXFLAGS $NOWARN_CXXFLAGS $ERROR_CXXFLAGS $CORE_CXXFLAGS $CXXFLAGS" diff --git a/test/sanitizer_suppressions/ubsan b/test/sanitizer_suppressions/ubsan index b486e22bea12..0ac2d92ace08 100644 --- a/test/sanitizer_suppressions/ubsan +++ b/test/sanitizer_suppressions/ubsan @@ -23,6 +23,7 @@ implicit-integer-sign-change:secp256k1/ implicit-signed-integer-truncation:*/include/c++/ implicit-signed-integer-truncation:leveldb/ implicit-signed-integer-truncation:secp256k1/ +implicit-signed-integer-truncation,implicit-integer-sign-change:secp256k1_modinv64_posdivsteps_62_var implicit-unsigned-integer-truncation:*/include/c++/ implicit-unsigned-integer-truncation:leveldb/ implicit-unsigned-integer-truncation:secp256k1/ From 1a202b35bce2daa29927fb4aa0af14e88750ab1f Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Tue, 24 Jun 2025 14:07:59 +0100 Subject: [PATCH 04/14] Merge bitcoin/bitcoin#32780: lsan: add more Qt suppressions 5be31b20e54eb9d3c5e9dc389597bcff5e066305 lsan: add more Qt suppressions (fanquake) Pull request description: Using Clang clang version 20.1.6 (Fedora 20.1.6-9.fc43) and: ```bash export CC=clang export CXX=clang++ cmake -B build -DBUILD_GUI=ON -DSANITIZERS=address cmake --build build export LSAN_OPTIONS="suppressions=/root/bitcoin/test/sanitizer_suppressions/lsan" ctest --test-dir build ``` ```bash Totals: 3 passed, 0 failed, 0 skipped, 0 blacklisted, 1589ms ********* Finished testing of AddressBookTests ********* ================================================================= ==21869==ERROR: LeakSanitizer: detected memory leaks Direct leak of 88 byte(s) in 1 object(s) allocated from: #0 0xaaaab5d5af40 in operator new(unsigned long) (/root/bitcoin/build/bin/test_bitcoin-qt+0x39af40) (BuildId: c0e038f1c507ea6860d1cfd499ac54ad83359872) #1 0xffff8c8f56cc in QLayoutPrivate::createWidgetItem(QLayout const*, QWidget*) (/lib64/libQt6Widgets.so.6+0x1a56cc) (BuildId: 8b7b9e470f4d4cd920282a4f963abb01225814fa) #2 0xffff8c8d2f90 in QBoxLayout::insertWidget(int, QWidget*, int, QFlags) (/lib64/libQt6Widgets.so.6+0x182f90) (BuildId: 8b7b9e470f4d4cd920282a4f963abb01225814fa) #3 0xaaaab5fc7188 in SendCoinsDialog::addEntry() /root/bitcoin/build/src/qt/./qt/sendcoinsdialog.cpp:596:18 #4 0xaaaab5fc4eec in SendCoinsDialog::SendCoinsDialog(PlatformStyle const*, QWidget*) /root/bitcoin/build/src/qt/./qt/sendcoinsdialog.cpp:84:5 #5 0xaaaab5da67ac in (anonymous namespace)::MiniGUI::MiniGUI(interfaces::Node&, PlatformStyle const*) /root/bitcoin/build/src/qt/test/./qt/test/wallettests.cpp:235:75 #6 0xaaaab5da2000 in (anonymous namespace)::TestGUI(interfaces::Node&, std::shared_ptr const&) /root/bitcoin/build/src/qt/test/./qt/test/wallettests.cpp:270:13 #7 0xaaaab5d9ebc8 in (anonymous namespace)::TestGUI(interfaces::Node&) /root/bitcoin/build/src/qt/test/./qt/test/wallettests.cpp:453:5 #8 0xaaaab5d9ebc8 in WalletTests::walletTests() /root/bitcoin/build/src/qt/test/./qt/test/wallettests.cpp:475:5 #9 0xffff8b1c5314 in QMetaMethodInvoker::invokeImpl(QMetaMethod, void*, Qt::ConnectionType, long long, void const* const*, char const* const*, QtPrivate::QMetaTypeInterface const* const*) (/lib64/libQt6Core.so.6+0x195314) (BuildId: eacb2d1228362560e5df1a1ce496c99ad61960e7) #10 0xffff8b1c5dc8 in QMetaMethod::invokeImpl(QMetaMethod, void*, Qt::ConnectionType, long long, void const* const*, char const* const*, QtPrivate::QMetaTypeInterface const* const*) (/lib64/libQt6Core.so.6+0x195dc8) (BuildId: eacb2d1228362560e5df1a1ce496c99ad61960e7) #11 0xffff8cf57c54 (/lib64/libQt6Test.so.6+0x27c54) (BuildId: 96bb1cdeead53af0ced36d7970cf9cd79c4c4ccd) #12 0xffff8cf5fa18 (/lib64/libQt6Test.so.6+0x2fa18) (BuildId: 96bb1cdeead53af0ced36d7970cf9cd79c4c4ccd) #13 0xffff8cf6067c (/lib64/libQt6Test.so.6+0x3067c) (BuildId: 96bb1cdeead53af0ced36d7970cf9cd79c4c4ccd) #14 0xffff8cf610a4 (/lib64/libQt6Test.so.6+0x310a4) (BuildId: 96bb1cdeead53af0ced36d7970cf9cd79c4c4ccd) #15 0xffff8cf61aa4 in QTest::qRun() (/lib64/libQt6Test.so.6+0x31aa4) (BuildId: 96bb1cdeead53af0ced36d7970cf9cd79c4c4ccd) #16 0xffff8cf61eb4 in QTest::qExec(QObject*, int, char**) (/lib64/libQt6Test.so.6+0x31eb4) (BuildId: 96bb1cdeead53af0ced36d7970cf9cd79c4c4ccd) #17 0xaaaab5d7d77c in main /root/bitcoin/build/src/qt/test/./qt/test/test_main.cpp:95:30 #18 0xffff8aad6398 in __libc_start_call_main (/lib64/libc.so.6+0x26398) (BuildId: 627f878dd454ee3cc1dfdbd347bb565f1ffb53e7) #19 0xffff8aad6478 in __libc_start_main@GLIBC_2.17 (/lib64/libc.so.6+0x26478) (BuildId: 627f878dd454ee3cc1dfdbd347bb565f1ffb53e7) #20 0xaaaab5c74cac in _start (/root/bitcoin/build/bin/test_bitcoin-qt+0x2b4cac) (BuildId: c0e038f1c507ea6860d1cfd499ac54ad83359872) ``` This happens when building using depends: ```bash Indirect leak of 24 byte(s) in 1 object(s) allocated from: #0 0xaaaabdbe86f8 in malloc (/root/bitcoin/build/bin/test_bitcoin-qt+0x4386f8) (BuildId: dd54811dc11325890f7bac3e3a49d38f5a7ffef5) #1 0xfbff97f8c164 () #2 0xaaaabf0cfaa4 in QDBusConnectionPrivate::QDBusConnectionPrivate() (/root/bitcoin/build/bin/test_bitcoin-qt+0x191faa4) (BuildId: dd54811dc11325890f7bac3e3a49d38f5a7ffef5) #3 0xaaaabf0c9e30 in QDBusConnectionManager::doConnectToStandardBus(QDBusConnection::BusType, QString const&, bool) (/root/bitcoin/build/bin/test_bitcoin-qt+0x1919e30) (BuildId: dd54811dc11325890f7bac3e3a49d38f5a7ffef5) #4 0xaaaabf0cb0e4 in QtPrivate::QCallableObject, QDBusConnectionPrivate*>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (/root/bitcoin/build/bin/test_bitcoin-qt+0x191b0e4) (BuildId: dd54811dc11325890f7bac3e3a49d38f5a7ffef5) #5 0xaaaabf5cbaf0 in QObject::event(QEvent*) (/root/bitcoin/build/bin/test_bitcoin-qt+0x1e1baf0) (BuildId: dd54811dc11325890f7bac3e3a49d38f5a7ffef5) #6 0xaaaabf5a4ce0 in QCoreApplicationPrivate::notify_helper(QObject*, QEvent*) (/root/bitcoin/build/bin/test_bitcoin-qt+0x1df4ce0) (BuildId: dd54811dc11325890f7bac3e3a49d38f5a7ffef5) #7 0xaaaabf5a486c in QCoreApplication::notifyInternal2(QObject*, QEvent*) (/root/bitcoin/build/bin/test_bitcoin-qt+0x1df486c) (BuildId: dd54811dc11325890f7bac3e3a49d38f5a7ffef5) #8 0xaaaabf5a575c in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (/root/bitcoin/build/bin/test_bitcoin-qt+0x1df575c) (BuildId: dd54811dc11325890f7bac3e3a49d38f5a7ffef5) #9 0xaaaabf66b858 in QEventDispatcherUNIX::processEvents(QFlags) (/root/bitcoin/build/bin/test_bitcoin-qt+0x1ebb858) (BuildId: dd54811dc11325890f7bac3e3a49d38f5a7ffef5) #10 0xaaaabf5a9e3c in QEventLoop::exec(QFlags) (/root/bitcoin/build/bin/test_bitcoin-qt+0x1df9e3c) (BuildId: dd54811dc11325890f7bac3e3a49d38f5a7ffef5) #11 0xaaaabf632a44 in QThread::exec() (/root/bitcoin/build/bin/test_bitcoin-qt+0x1e82a44) (BuildId: dd54811dc11325890f7bac3e3a49d38f5a7ffef5) #12 0xaaaabf0c9bd0 in QDBusConnectionManager::run() (/root/bitcoin/build/bin/test_bitcoin-qt+0x1919bd0) (BuildId: dd54811dc11325890f7bac3e3a49d38f5a7ffef5) #13 0xaaaabf669c30 in QThreadPrivate::start(void*) (/root/bitcoin/build/bin/test_bitcoin-qt+0x1eb9c30) (BuildId: dd54811dc11325890f7bac3e3a49d38f5a7ffef5) #14 0xaaaabdbe5f2c in asan_thread_start(void*) asan_interceptors.cpp.o #15 0xffff99538608 in thread_start (/lib64/libc.so.6+0xf8608) (BuildId: 627f878dd454ee3cc1dfdbd347bb565f1ffb53e7) SUMMARY: AddressSanitizer: 3592 byte(s) leaked in 37 allocation(s). ``` ACKs for top commit: maflcko: lgtm ACK 5be31b20e54eb9d3c5e9dc389597bcff5e066305 Tree-SHA512: 0c33661c7ec83ea9b874c1ee4ee2de513131690287363e216a88560dfb31a59ef563a50af756c86a991583aa64a600a74e20fd5d6a104cf4c0a27532de8d2211 (cherry picked from commit 67e6746dc87a674102ce2f2ed93e5eb563181cc9) Co-authored-by: merge-script --- test/sanitizer_suppressions/lsan | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/sanitizer_suppressions/lsan b/test/sanitizer_suppressions/lsan index 7ccb22515f91..fc1d82f45976 100644 --- a/test/sanitizer_suppressions/lsan +++ b/test/sanitizer_suppressions/lsan @@ -1,2 +1,4 @@ # Suppress warnings triggered in dependencies leak:libQt5Widgets +leak:QDBusConnectionPrivate +leak:QLayoutPrivate From 208e425c5ee5f49930de5815df2c17ea7e73ba7c Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Wed, 6 Nov 2024 15:04:06 +0000 Subject: [PATCH 05/14] Merge bitcoin/bitcoin#31232: ci: `add second_deadlock_stack=1` to TSAN options 5161c2618cd36cd2d64c64d42d6f6d3b1929cb28 ci: add second_deadlock_stack=1 to TSAN options (fanquake) Pull request description: This is mentioned in the developer notes, but isn't present in `TSAN_OPTIONS`, resulting in: ```bash WARNING: ThreadSanitizer: lock-order-inversion (potential deadlock) (pid=60508) Cycle in lock order graph: M0 (0xffff98e02208) => M1 (0xffff98e0cbe8) => M2 (0xffff98e0cd98) => M0 Hint: use TSAN_OPTIONS=second_deadlock_stack=1 to get more informative warning message ``` Add it, for (potentially) more informative output, when failures occur. Checked that adding does output more information. ACKs for top commit: maflcko: lgtm ACK 5161c2618cd36cd2d64c64d42d6f6d3b1929cb28 hebasto: ACK 5161c2618cd36cd2d64c64d42d6f6d3b1929cb28. Tree-SHA512: 57bfa24d248ed76ba0db537edff425453a0765c4768fc1b6f59a87876d4acf63ed38bb3c20f369a008ae256472d9d24e58d76729d423f662dfdb2952afc46cb0 Co-authored-by: merge-script --- ci/dash/matrix.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/dash/matrix.sh b/ci/dash/matrix.sh index de01eaf6d6c7..1afb5a6527c4 100755 --- a/ci/dash/matrix.sh +++ b/ci/dash/matrix.sh @@ -13,7 +13,7 @@ source ./ci/test/00_setup_env.sh # Configure sanitizers options export ASAN_OPTIONS="" export LSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/lsan" -export TSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/tsan:halt_on_error=1" +export TSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/tsan:halt_on_error=1:second_deadlock_stack=1" export UBSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/ubsan:print_stacktrace=1:halt_on_error=1:report_error_type=1" if [ "$BUILD_TARGET" = "aarch64-linux" ]; then From 406c549c84be162dc5c8a33a6215a4daedbf4af0 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Wed, 29 Jul 2026 01:33:14 +0700 Subject: [PATCH 06/14] ci: populate ASAN_OPTIONS to matrix.sh Original changes has been added to ci/test/04_install.sh and hasn't been propogated to matrix.sh where it's actually used --- ci/dash/matrix.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/dash/matrix.sh b/ci/dash/matrix.sh index 1afb5a6527c4..53e9195cc596 100755 --- a/ci/dash/matrix.sh +++ b/ci/dash/matrix.sh @@ -11,7 +11,7 @@ export LC_ALL=C.UTF-8 source ./ci/test/00_setup_env.sh # Configure sanitizers options -export ASAN_OPTIONS="" +export ASAN_OPTIONS="detect_leaks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1" export LSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/lsan" export TSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/tsan:halt_on_error=1:second_deadlock_stack=1" export UBSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/ubsan:print_stacktrace=1:halt_on_error=1:report_error_type=1" From f7b15d4394f2314ce95d0fa5f41ae544790ecb44 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Fri, 31 Jul 2026 20:34:52 +0700 Subject: [PATCH 07/14] ci: support ASAN in legacy PR workflow as a workaround to test ASAN on CI before PR is merged --- ci/dash/matrix.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ci/dash/matrix.sh b/ci/dash/matrix.sh index 53e9195cc596..224408b8e752 100755 --- a/ci/dash/matrix.sh +++ b/ci/dash/matrix.sh @@ -33,7 +33,11 @@ elif [ "$BUILD_TARGET" = "linux64_sqlite" ]; then elif [ "$BUILD_TARGET" = "linux64_tsan" ]; then source ./ci/test/00_setup_env_native_tsan.sh elif [ "$BUILD_TARGET" = "linux64_ubsan" ]; then - source ./ci/test/00_setup_env_native_ubsan.sh + # TODO: remove it when #7503 will get merged. That's a temporary workaround to check asan on CI + # Compatibility for pull_request_target workflows that still request the legacy target. + # Their default-branch container setup does not grant SYS_PTRACE. + export ASAN_OPTIONS="detect_leaks=0:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1" + source ./ci/test/00_setup_env_native_asan.sh elif [ "$BUILD_TARGET" = "linux64_valgrind" ]; then source ./ci/test/00_setup_env_native_valgrind.sh elif [ "$BUILD_TARGET" = "mac" ]; then From 3906c287ea92392db18024f436e71c703f1a04ba Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Wed, 29 Jul 2026 01:37:14 +0700 Subject: [PATCH 08/14] ci: replace linux64_ubsan job by linux64_asan Reworked the env file for the GitHub Actions flow: - NO_DEPENDS=1 is gone. ci/dash/build_src.sh always configures against depends and ignores it, so leaving it in only misleads. - DEP_OPTS is empty to match the linux64 depends this job reuses. build-src.yml takes DEP_OPTS from the depends build rather than from the build target, so a different value here would never take effect. - Pinned clang-19 to match LLVM_VERSION in the CI image instead of unversioned clang. - Picked up -ftrivial-auto-var-init=pattern and -DARENA_DEBUG from upstream v28.0, the last release before the CMake migration and so the last one directly comparable to our autotools build. - Dropped RUN_BENCH and FUNCTIONAL_TESTS_CONFIG, which nothing reads. The job reuses the linux64 depends artifact, so it costs a source build and a test run, not a dependency build. --- .github/workflows/build.yml | 52 ++++++++++++++-------------- ci/test/00_setup_env_native_asan.sh | 16 +++++---- ci/test/00_setup_env_native_ubsan.sh | 15 -------- 3 files changed, 35 insertions(+), 48 deletions(-) delete mode 100755 ci/test/00_setup_env_native_ubsan.sh diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e8c993c6eeec..ce8191dc99ea 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -132,9 +132,9 @@ jobs: needs: [check-skip, container, cache-sources] if: | vars.SKIP_LINUX64 == '' || + vars.SKIP_LINUX64_ASAN == '' || vars.SKIP_LINUX64_FUZZ == '' || - vars.SKIP_LINUX64_SQLITE == '' || - vars.SKIP_LINUX64_UBSAN == '' + vars.SKIP_LINUX64_SQLITE == '' with: build-target: linux64 container-path: ${{ needs.container.outputs.path }} @@ -222,6 +222,20 @@ jobs: depends-artifact: ${{ needs.depends-linux64.outputs.built-artifact }} runs-on: ${{ needs.check-skip.outputs['runner-amd64'] }} + src-linux64_asan: + name: linux64_asan-build + uses: ./.github/workflows/build-src.yml + needs: [check-skip, container, depends-linux64] + if: ${{ vars.SKIP_LINUX64_ASAN == '' }} + with: + build-target: linux64_asan + container-path: ${{ needs.container.outputs.path }} + depends-key: ${{ needs.depends-linux64.outputs.key }} + depends-host: ${{ needs.depends-linux64.outputs.host }} + depends-dep-opts: ${{ needs.depends-linux64.outputs.dep-opts }} + depends-artifact: ${{ needs.depends-linux64.outputs.built-artifact }} + runs-on: ${{ needs.check-skip.outputs['runner-amd64'] }} + src-linux64_fuzz: name: linux64_fuzz-build uses: ./.github/workflows/build-src.yml @@ -291,20 +305,6 @@ jobs: depends-artifact: ${{ needs.depends-linux64_multiprocess.outputs.built-artifact }} runs-on: ${{ needs.check-skip.outputs['runner-arm64'] }} - src-linux64_ubsan: - name: linux64_ubsan-build - uses: ./.github/workflows/build-src.yml - needs: [check-skip, container, depends-linux64] - if: ${{ vars.SKIP_LINUX64_UBSAN == '' }} - with: - build-target: linux64_ubsan - container-path: ${{ needs.container.outputs.path }} - depends-key: ${{ needs.depends-linux64.outputs.key }} - depends-host: ${{ needs.depends-linux64.outputs.host }} - depends-dep-opts: ${{ needs.depends-linux64.outputs.dep-opts }} - depends-artifact: ${{ needs.depends-linux64.outputs.built-artifact }} - runs-on: ${{ needs.check-skip.outputs['runner-amd64'] }} - src-mac: name: mac-build uses: ./.github/workflows/build-src.yml @@ -342,6 +342,16 @@ jobs: container-path: ${{ needs.container-slim.outputs.path }} runs-on: ${{ needs.check-skip.outputs['runner-amd64'] }} + test-linux64_asan: + name: linux64_asan-test + uses: ./.github/workflows/test-src.yml + needs: [check-skip, container-slim, src-linux64_asan, lint] + with: + bundle-key: ${{ needs.src-linux64_asan.outputs.key }} + build-target: linux64_asan + container-path: ${{ needs.container-slim.outputs.path }} + runs-on: ${{ needs.check-skip.outputs['runner-amd64'] }} + test-linux64_multiprocess: name: linux64_multiprocess-test uses: ./.github/workflows/test-src.yml @@ -381,13 +391,3 @@ jobs: build-target: linux64_tsan container-path: ${{ needs.container-slim.outputs.path }} runs-on: ${{ needs.check-skip.outputs['runner-arm64'] }} - - test-linux64_ubsan: - name: linux64_ubsan-test - uses: ./.github/workflows/test-src.yml - needs: [check-skip, container-slim, src-linux64_ubsan, lint] - with: - bundle-key: ${{ needs.src-linux64_ubsan.outputs.key }} - build-target: linux64_ubsan - container-path: ${{ needs.container-slim.outputs.path }} - runs-on: ${{ needs.check-skip.outputs['runner-amd64'] }} diff --git a/ci/test/00_setup_env_native_asan.sh b/ci/test/00_setup_env_native_asan.sh index 94e01cf906d4..f65f90170aa7 100755 --- a/ci/test/00_setup_env_native_asan.sh +++ b/ci/test/00_setup_env_native_asan.sh @@ -6,12 +6,14 @@ export LC_ALL=C.UTF-8 -export PACKAGES="clang llvm python3-zmq qtbase5-dev qttools5-dev qttools5-dev-tools libevent-dev bsdmainutils libboost-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev libqrencode-dev" -export NO_DEPENDS=1 +export CONTAINER_NAME=ci_native_asan +export PACKAGES="clang-19 llvm-19 libclang-rt-19-dev python3-zmq qtbase5-dev qttools5-dev-tools libevent-dev bsdmainutils libboost-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev libqrencode-dev" +# Reuses the depends built for the linux64 target, which uses the defaults. +export DEP_OPTS="" export TEST_RUNNER_EXTRA="--timeout-factor=4" # Increase timeout because sanitizers slow down -export FUNCTIONAL_TESTS_CONFIG="--exclude wallet_multiwallet.py" # Temporarily suppress ASan heap-use-after-free (see issue #14163) -export RUN_BENCH=true export GOAL="install" -export BITCOIN_CONFIG="--enable-zmq --with-incompatible-bdb --with-gui=qt5 \ -CPPFLAGS=-DDEBUG_LOCKORDER \ ---with-sanitizers=address,float-divide-by-zero,integer,undefined CC=clang CXX=clang++" +export BITCOIN_CONFIG="--enable-zmq --enable-crash-hooks --with-gui=qt5 \ +--with-sanitizers=address,float-divide-by-zero,integer,undefined \ +CPPFLAGS='-DARENA_DEBUG -DDEBUG_LOCKORDER' \ +CC='clang-19 -ftrivial-auto-var-init=pattern' CXX='clang++-19 -ftrivial-auto-var-init=pattern'" +export PYZMQ=true diff --git a/ci/test/00_setup_env_native_ubsan.sh b/ci/test/00_setup_env_native_ubsan.sh deleted file mode 100755 index f562bce0edbf..000000000000 --- a/ci/test/00_setup_env_native_ubsan.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (c) 2019 The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -# TODO: use config `asan` instead `ubsan` for `undefined` sanitizer to unify with bitcoin -export LC_ALL=C.UTF-8 - -export CONTAINER_NAME=ci_native_ubsan -export PACKAGES="clang-19 llvm-19 python3-zmq qtbase5-dev qttools5-dev-tools libevent-dev bsdmainutils libboost-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev libqrencode-dev" -export DEP_OPTS="NO_UPNP=1 DEBUG=1" -export GOAL="install" -export BITCOIN_CONFIG="--enable-zmq --enable-reduce-exports --enable-crash-hooks --with-sanitizers=undefined CC=clang-19 CXX=clang++-19" -export PYZMQ=true From b8a66644bb810839bbc206317895c62e6c8414b4 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Sat, 1 Aug 2026 01:31:05 +0700 Subject: [PATCH 09/14] ci: register llvm-symbolizer in the slim image, not the full one The lint job and every test-* job, functional tests included, run in ci-slim; only depends and the src-* builds use the full image. Registering the alternative only in ci.Dockerfile therefore left the sanitizer reports that matter most, the ones from functional tests, coming back as raw addresses. That is the failure mode that caused 844ede2eb2 to disable the job in the first place. Registering it in both is not an option: ci.Dockerfile is built FROM ci-slim.Dockerfile, so the slim image installs /usr/bin/llvm-symbolizer as a master alternative and the full image would then try to attach the same link as a slave of llvm-config, which update-alternatives refuses with alternative llvm-symbolizer can't be slave of llvm-config: it is a master alternative Registering it once in the slim image covers both, since the full image inherits from it. --- contrib/containers/ci/ci-slim.Dockerfile | 4 +++- contrib/containers/ci/ci.Dockerfile | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/contrib/containers/ci/ci-slim.Dockerfile b/contrib/containers/ci/ci-slim.Dockerfile index 8436fd14dfa3..10ece13d60ca 100644 --- a/contrib/containers/ci/ci-slim.Dockerfile +++ b/contrib/containers/ci/ci-slim.Dockerfile @@ -129,7 +129,9 @@ RUN set -ex; \ echo "deb [signed-by=/etc/apt/trusted.gpg.d/apt.llvm.org.asc] http://apt.llvm.org/${UBUNTU_CODENAME}/ llvm-toolchain-${UBUNTU_CODENAME}-${LLVM_VERSION} main" > /etc/apt/sources.list.d/llvm.list; \ apt-get update && apt-get install ${APT_ARGS} \ "llvm-${LLVM_VERSION}-dev"; \ - rm -rf /var/lib/apt/lists/*; + rm -rf /var/lib/apt/lists/*; \ + update-alternatives --install /usr/bin/llvm-symbolizer llvm-symbolizer \ + "/usr/bin/llvm-symbolizer-${LLVM_VERSION}" 100; # Setup unprivileged user and configuration files ARG USER_ID=1000 \ diff --git a/contrib/containers/ci/ci.Dockerfile b/contrib/containers/ci/ci.Dockerfile index d353decbc592..42df9b08018c 100644 --- a/contrib/containers/ci/ci.Dockerfile +++ b/contrib/containers/ci/ci.Dockerfile @@ -48,7 +48,7 @@ RUN set -ex; \ rm -rf /var/lib/apt/lists/*; \ echo "Setting defaults..."; \ llvmUpdAltArgs="update-alternatives --install /usr/bin/llvm-config llvm-config /usr/bin/llvm-config-${LLVM_VERSION} 100"; \ - for binName in clang clang++ clang-apply-replacements clang-format clang-tidy clangd dsymutil lld lldb lldb-server llvm-ar llvm-cov llvm-nm llvm-objdump llvm-ranlib llvm-strip llvm-symbolizer run-clang-tidy; do \ + for binName in clang clang++ clang-apply-replacements clang-format clang-tidy clangd dsymutil lld lldb lldb-server llvm-ar llvm-cov llvm-nm llvm-objdump llvm-ranlib llvm-strip run-clang-tidy; do \ llvmUpdAltArgs="${llvmUpdAltArgs} --slave /usr/bin/${binName} ${binName} /usr/bin/${binName}-${LLVM_VERSION}"; \ done; \ for binName in ld64.lld ld.lld lld-link wasm-ld; do \ From d1755bbe6a62eff4f97cc600d75e3923bee5b0fb Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Sat, 1 Aug 2026 02:32:38 +0700 Subject: [PATCH 10/14] test: make secp256k1 more wide matching sanitizer suppressions by symbol There are already suppressions for this, but they never match. The subtree is configured from inside the build directory, so its reports name files relative to the subtree, src/util.h, with no secp256k1/ path component for entries like implicit-unsigned-integer-truncation:secp256k1/ to catch. An in-tree build records the full path and does match, which is why this only shows up in CI. Match by symbol as well, which holds however the build is laid out; upstream added a per-symbol entry for secp256k1_modinv64_posdivsteps_62_var for the same reason. Instrumenting the secp256k1 subtree (bitcoin#28875) makes its selftest report on every process start: src/util.h:350:12: runtime error: implicit conversion from type 'uint32_t' of value 504 to type 'unsigned char' changed the value to 248 secp256k1_write_be32 secp256k1_sha256_finalize secp256k1_selftest secp256k1_write_be32 is "p[3] = x;" writing a uint32 out as four bytes, so the truncation is the point of the function and there is nothing to fix. --- test/sanitizer_suppressions/ubsan | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/test/sanitizer_suppressions/ubsan b/test/sanitizer_suppressions/ubsan index 0ac2d92ace08..d5ee6aa15dfb 100644 --- a/test/sanitizer_suppressions/ubsan +++ b/test/sanitizer_suppressions/ubsan @@ -12,26 +12,27 @@ unsigned-integer-overflow:*/include/c++/ unsigned-integer-overflow:FuzzedDataProvider::ConsumeIntegralInRange unsigned-integer-overflow:leveldb/ unsigned-integer-overflow:minisketch/ -unsigned-integer-overflow:secp256k1/ +unsigned-integer-overflow:secp256k1* unsigned-integer-overflow:test/fuzz/crypto_diff_fuzz_chacha20.cpp implicit-integer-sign-change:*/include/boost/ implicit-integer-sign-change:*/include/c++/ implicit-integer-sign-change:*/new_allocator.h implicit-integer-sign-change:crc32c/ implicit-integer-sign-change:minisketch/ -implicit-integer-sign-change:secp256k1/ +implicit-integer-sign-change:secp256k1* implicit-signed-integer-truncation:*/include/c++/ implicit-signed-integer-truncation:leveldb/ -implicit-signed-integer-truncation:secp256k1/ +implicit-signed-integer-truncation:secp256k1* implicit-signed-integer-truncation,implicit-integer-sign-change:secp256k1_modinv64_posdivsteps_62_var implicit-unsigned-integer-truncation:*/include/c++/ implicit-unsigned-integer-truncation:leveldb/ -implicit-unsigned-integer-truncation:secp256k1/ +implicit-unsigned-integer-truncation:secp256k1* +implicit-signed-integer-truncation,implicit-integer-sign-change:secp256k1* implicit-unsigned-integer-truncation:test/fuzz/crypto_diff_fuzz_chacha20.cpp shift-base:*/include/c++/ shift-base:leveldb/ shift-base:minisketch/ -shift-base:secp256k1/ +shift-base:secp256k1* shift-base:test/fuzz/crypto_diff_fuzz_chacha20.cpp # Unsigned integer overflow occurs when the result of an unsigned integer # computation cannot be represented in its type. Unlike signed integer overflow, From eacd9e05fb73a8c37d2fa39ca5c97f4f6388e9a3 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Mon, 3 Aug 2026 02:45:56 +0700 Subject: [PATCH 11/14] test: suppress intentional wraparound in quorum snapshot skip lists `BuildNewQuorumQuarterMembers` walks `sortedCombinedMnsList` circularly: `idx` wraps back to 0 at the end of the list (src/llmq/utils.cpp:441). The skip list records the first skipped position absolutely and every later one as an offset from it, `idx - firstSkippedIndex`, so once `idx` has wrapped past `firstSkippedIndex` that subtraction underflows `size_t` and is then narrowed into `std::vector`. `GetQuorumQuarterMembersBySnapshot` undoes it with `first_entry_index + s`, where the negative `int` converts back to `size_t` and the addition wraps in the opposite direction, recovering the absolute index exactly. The two wraparounds are each other's inverse, and the encoding is consensus-critical: it is what peers serialize in `CQuorumSnapshot::mnSkipList`. Changing the types would change the wire format. `-fsanitize=integer` (new in the linux64_asan job) reports the underflow, the narrowing and the sign change. Suppress all three per symbol rather than per file, so the rest of llmq/utils.cpp stays covered. --- test/sanitizer_suppressions/ubsan | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/sanitizer_suppressions/ubsan b/test/sanitizer_suppressions/ubsan index d5ee6aa15dfb..5560aada773a 100644 --- a/test/sanitizer_suppressions/ubsan +++ b/test/sanitizer_suppressions/ubsan @@ -48,6 +48,13 @@ unsigned-integer-overflow:compressor.cpp unsigned-integer-overflow:crypto/ unsigned-integer-overflow:hash.cpp unsigned-integer-overflow:lcg.h +# The quorum snapshot skip list stores offsets relative to the first skipped +# index, and the index wraps around the sorted MN list, so an offset can be +# negative. Encoding wraps size_t and narrows into vector, decoding wraps +# it back; the two cancel and the absolute index is recovered exactly. Per +# symbol rather than per file so the rest of llmq/utils.cpp stays covered. +unsigned-integer-overflow:BuildNewQuorumQuarterMembers +unsigned-integer-overflow:GetQuorumQuarterMembersBySnapshot unsigned-integer-overflow:policy/fees.cpp unsigned-integer-overflow:prevector.h unsigned-integer-overflow:EvalScript @@ -56,6 +63,7 @@ unsigned-integer-overflow:xoroshiro128plusplus.h implicit-integer-sign-change:addrman.h implicit-integer-sign-change:compat/stdin.cpp implicit-integer-sign-change:CBlockPolicyEstimator::processBlockTx +implicit-integer-sign-change:GetQuorumQuarterMembersBySnapshot implicit-integer-sign-change:compressor.h implicit-integer-sign-change:crypto/ implicit-integer-sign-change:policy/fees.cpp @@ -68,6 +76,7 @@ implicit-integer-sign-change:util/strencodings.cpp implicit-integer-sign-change:util/strencodings.h implicit-integer-sign-change:validation.cpp implicit-signed-integer-truncation,implicit-integer-sign-change:test/skiplist_tests.cpp +implicit-signed-integer-truncation,implicit-integer-sign-change:BuildNewQuorumQuarterMembers implicit-signed-integer-truncation:addrman.h implicit-signed-integer-truncation:crypto/ implicit-unsigned-integer-truncation:crypto/ From 0f7da3afe2a5ee9b98c6f0610a5bd4b719558944 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Tue, 4 Aug 2026 03:04:50 +0700 Subject: [PATCH 12/14] fix: use only 2 parallel workers for asan job --- ci/test/00_setup_env_native_asan.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/test/00_setup_env_native_asan.sh b/ci/test/00_setup_env_native_asan.sh index f65f90170aa7..c3029cfe68b4 100755 --- a/ci/test/00_setup_env_native_asan.sh +++ b/ci/test/00_setup_env_native_asan.sh @@ -10,7 +10,7 @@ export CONTAINER_NAME=ci_native_asan export PACKAGES="clang-19 llvm-19 libclang-rt-19-dev python3-zmq qtbase5-dev qttools5-dev-tools libevent-dev bsdmainutils libboost-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev libqrencode-dev" # Reuses the depends built for the linux64 target, which uses the defaults. export DEP_OPTS="" -export TEST_RUNNER_EXTRA="--timeout-factor=4" # Increase timeout because sanitizers slow down +export TEST_RUNNER_EXTRA="--timeout-factor=4 -j2" # Increase timeout because sanitizers slow down export GOAL="install" export BITCOIN_CONFIG="--enable-zmq --enable-crash-hooks --with-gui=qt5 \ --with-sanitizers=address,float-divide-by-zero,integer,undefined \ From 6c460f624b6419ec9d71c33d27120165761ab0d2 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Fri, 7 Aug 2026 16:47:17 +0700 Subject: [PATCH 13/14] fix: account index should not be negative for hd chains --- src/wallet/hdchain.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/wallet/hdchain.cpp b/src/wallet/hdchain.cpp index 94b5e598d605..f781aaac075d 100644 --- a/src/wallet/hdchain.cpp +++ b/src/wallet/hdchain.cpp @@ -187,7 +187,8 @@ void CHDChain::AddAccount() bool CHDChain::GetAccount(uint32_t nAccountIndex, CHDAccount& hdAccountRet) { LOCK(cs); - if (nAccountIndex > mapAccounts.size() - 1) + // A chain stored without accounts creates one on first use, with zeroed counters. + if (!mapAccounts.empty() && nAccountIndex >= mapAccounts.size()) return false; hdAccountRet = mapAccounts[nAccountIndex]; return true; @@ -197,7 +198,7 @@ bool CHDChain::SetAccount(uint32_t nAccountIndex, const CHDAccount& hdAccount) { LOCK(cs); // can only replace existing accounts - if (nAccountIndex > mapAccounts.size() - 1) + if (!mapAccounts.empty() && nAccountIndex >= mapAccounts.size()) return false; mapAccounts[nAccountIndex] = hdAccount; return true; From 3aaf867e4061e86076603d5bcac2ca419bf0c67b Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Fri, 7 Aug 2026 22:47:02 +0700 Subject: [PATCH 14/14] fix: follow-up missing changes for dash specific code from bitcoin#24218 It fix implicit-integer-sign-change asan message --- src/zmq/zmqpublishnotifier.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp index 6a1bd06f5b99..2b88b69cea33 100644 --- a/src/zmq/zmqpublishnotifier.cpp +++ b/src/zmq/zmqpublishnotifier.cpp @@ -255,7 +255,7 @@ bool CZMQPublishHashChainLockNotifier::NotifyChainLock(const CBlockIndex *pindex { uint256 hash = pindex->GetBlockHash(); LogPrint(BCLog::ZMQ, "Publish hashchainlock %s to %s\n", hash.GetHex(), this->address); - char data[32]; + uint8_t data[32]; for (unsigned int i = 0; i < 32; i++) data[31 - i] = hash.begin()[i]; return SendZmqMessage(MSG_HASHCHAINLOCK, data, 32); @@ -276,7 +276,7 @@ bool CZMQPublishHashTransactionLockNotifier::NotifyTransactionLock(const CTransa { uint256 hash = transaction->GetHash(); LogPrint(BCLog::ZMQ, "Publish hashtxlock %s to %s\n", hash.GetHex(), this->address); - char data[32]; + uint8_t data[32]; for (unsigned int i = 0; i < 32; i++) data[31 - i] = hash.begin()[i]; return SendZmqMessage(MSG_HASHTXLOCK, data, 32); @@ -286,7 +286,7 @@ bool CZMQPublishHashGovernanceVoteNotifier::NotifyGovernanceVote(const std::shar { uint256 hash = vote->GetHash(); LogPrint(BCLog::ZMQ, "Publish hashgovernancevote %s to %s\n", hash.GetHex(), this->address); - char data[32]; + uint8_t data[32]; for (unsigned int i = 0; i < 32; i++) data[31 - i] = hash.begin()[i]; return SendZmqMessage(MSG_HASHGVOTE, data, 32); @@ -296,7 +296,7 @@ bool CZMQPublishHashGovernanceObjectNotifier::NotifyGovernanceObject(const std:: { uint256 hash = object->GetHash(); LogPrint(BCLog::ZMQ, "Publish hashgovernanceobject %s to %s\n", hash.GetHex(), this->address); - char data[32]; + uint8_t data[32]; for (unsigned int i = 0; i < 32; i++) data[31 - i] = hash.begin()[i]; return SendZmqMessage(MSG_HASHGOBJ, data, 32); @@ -306,7 +306,7 @@ bool CZMQPublishHashInstantSendDoubleSpendNotifier::NotifyInstantSendDoubleSpend { uint256 currentHash = currentTx->GetHash(), previousHash = previousTx->GetHash(); LogPrint(BCLog::ZMQ, "Publish hashinstantsenddoublespend %s conflicts against %s to %s\n", currentHash.ToString(), previousHash.ToString(), this->address); - char dataCurrentHash[32], dataPreviousHash[32]; + uint8_t dataCurrentHash[32], dataPreviousHash[32]; for (unsigned int i = 0; i < 32; i++) { dataCurrentHash[31 - i] = currentHash.begin()[i]; dataPreviousHash[31 - i] = previousHash.begin()[i]; @@ -318,7 +318,7 @@ bool CZMQPublishHashInstantSendDoubleSpendNotifier::NotifyInstantSendDoubleSpend bool CZMQPublishHashRecoveredSigNotifier::NotifyRecoveredSig(const std::shared_ptr &sig) { LogPrint(BCLog::ZMQ, "Publish hashrecoveredsig %s to %s\n", sig->getMsgHash().ToString(), this->address); - char data[32]; + uint8_t data[32]; for (unsigned int i = 0; i < 32; i++) data[31 - i] = sig->getMsgHash().begin()[i]; return SendZmqMessage(MSG_HASHRECSIG, data, 32);