Merge bitcoin/bitcoin#31841: fuzz: Use immediate task runner to increase fuzz stability

fa4fb6a8f1 fuzz: Use serial task runner to increase fuzz stability (MarcoFalke)

Pull request description:

  Leaking a scheduler with a non-empty queue from the fuzz initialization phase into the fuzz target execution phase is problematic, because it messes with coverage data. This in turn is problematic, because it leads to:

  * Decrease in fuzz target execution stability (non-determinism when running the fuzz target).
  * Decrease in fuzz input merge stability (non-determinism when selecting a minimum set of fuzz input to reach maximum coverage), which leads to qa-assets bloat.

  Fix one such issue. Tracking issue: https://github.com/bitcoin/bitcoin/issues/29018

  Can be tested via: `RUST_BACKTRACE=1 cargo run --manifest-path ./contrib/devtools/deterministic-fuzz-coverage/Cargo.toml -- $PWD/bld-cmake $PWD/../b-c-qa-assets/fuzz_corpora/ partially_downloaded_block`.

  The failure is non-deterministic (obviously) and will show coverage in validation signals such as `UpdatedBlockTip` before this change and will have this one fixed after this change.

ACKs for top commit:
  marcofleon:
    ACK fa4fb6a8f1
  dergoegge:
    Code review ACK fa4fb6a8f1

Tree-SHA512: fd1f66562c1d3c21553c7dd324399cdc16faa2fedfdb8e7544ea6a68b8b356e7c81d81815ecf70e0d334307dab6b275c1889b3b889b6f15eec514beee22c95f4
This commit is contained in:
merge-script 2025-03-21 08:25:41 +08:00
commit b858b72903
No known key found for this signature in database
GPG key ID: 2EEB9F5CC09526C1

View file

@ -49,6 +49,7 @@
#include <util/rbf.h>
#include <util/strencodings.h>
#include <util/string.h>
#include <util/task_runner.h>
#include <util/thread.h>
#include <util/threadnames.h>
#include <util/time.h>
@ -220,12 +221,15 @@ ChainTestingSetup::ChainTestingSetup(const ChainType chainType, TestOpts opts)
{
const CChainParams& chainparams = Params();
// We have to run a scheduler thread to prevent ActivateBestChain
// A task runner is required to prevent ActivateBestChain
// from blocking due to queue overrun.
if (opts.setup_validation_interface) {
m_node.scheduler = std::make_unique<CScheduler>();
m_node.scheduler->m_service_thread = std::thread(util::TraceThread, "scheduler", [&] { m_node.scheduler->serviceQueue(); });
m_node.validation_signals = std::make_unique<ValidationSignals>(std::make_unique<SerialTaskRunner>(*m_node.scheduler));
m_node.validation_signals =
// Use synchronous task runner while fuzzing to avoid non-determinism
G_FUZZING ? std::make_unique<ValidationSignals>(std::make_unique<util::ImmediateTaskRunner>()) :
std::make_unique<ValidationSignals>(std::make_unique<SerialTaskRunner>(*m_node.scheduler));
}
bilingual_str error{};