fuzz: use ImmediateBackgroundTaskRunner to silence DEBUG_LOCKORDER
What changed, and why it matters
This change only affects an internal fuzzing test harness (a tool used to automatically find bugs in Bitcoin Core). It swaps the task runner used during fuzz testing so that lock-order debugging warnings no longer report a false alarm. There is no change to production code, no real deadlock is being fixed, and no user funds or network behavior are affected.
No action required. This is a test-infrastructure-only change. Reviewers may verify that ImmediateBackgroundTaskRunner is only used in the fuzz harness and that the thread join prevents any lifetime issues.
Security signals we found
Change is confined to a fuzz test harness (src/test/fuzz/cmpctblock.cpp)
No production consensus, networking, wallet, or validation logic is modified
The lock-order report being silenced is explicitly described by the author as a false positive
New code launches and immediately joins a thread; no concurrency bugs introduced
No cryptographic, memory-safety, or permission changes
Evidence from the diff
The commit modifies src/test/fuzz/cmpctblock.cpp to introduce ImmediateBackgroundTaskRunner, which executes callbacks in a temporary std::thread that is immediately joined. In the existing ImmediateTaskRunner, callbacks run synchronously in the same thread. Under DEBUG_LOCKORDER this caused a false-positive lock-order cycle: BlockConnected (holding mempool.cs then acquiring m_tx_download_mutex) followed by a TX send (acquiring m_tx_download_mutex then mempool.cs). By running the callback in a separate thread, the lock-order tracker sees the locks in different threads and stops reporting the spurious deadlock. The production ValidationSignals task runner is unchanged.
Changed components
src/test/fuzz/cmpctblock.cppcmpctblock fuzz harness onlyInspect captured patch +13 / −0
diff --git a/src/test/fuzz/cmpctblock.cpp b/src/test/fuzz/cmpctblock.cpp
index 3e4268cb..6af9883a 100644
--- a/src/test/fuzz/cmpctblock.cpp
+++ b/src/test/fuzz/cmpctblock.cpp
@@ -36,6 +36,7 @@
#include <txmempool.h>
#include <uint256.h>
#include <util/check.h>
+#include <util/task_runner.h>
#include <util/time.h>
#include <util/translation.h>
#include <validation.h>
@@ -52,6 +53,7 @@
#include <optional>
#include <string>
#include <string_view>
+#include <thread>
#include <utility>
#include <vector>
@@ -135,6 +137,15 @@ void ResetChainmanAndMempool(TestingSetup& setup)
}
}
+//! Used to run tasks in a std::thread to avoid DEBUG_LOCKORDER false positives.
+class ImmediateBackgroundTaskRunner : public util::TaskRunnerInterface
+{
+public:
+ void insert(std::function<void()> func) override { std::thread(std::move(func)).join(); }
+ void flush() override {}
+ size_t size() override { return 0; }
+};
+
} // namespace
extern void MakeRandDeterministicDANGEROUS(const uint256& seed) noexcept;
@@ -144,6 +155,8 @@ void initialize_cmpctblock()
static const auto testing_setup = MakeNoLogFileContext<TestingSetup>();
g_setup = testing_setup.get();
g_nBits = Params().GenesisBlock().nBits;
+ // Replace validation_signals before creating chainman and mempool so they use it.
+ testing_setup->m_node.validation_signals = std::make_unique<ValidationSignals>(std::make_unique<ImmediateBackgroundTaskRunner>());
ResetChainmanAndMempool(*g_setup);
}
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.