Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
251targets = transform_rpc_target(targets, Path(src_dir))253def job(command, t, t_env):254logging.debug(f"Running '{command}'")255logging.debug("Command '{}' output:\n'{}'\n".format(256command,257subprocess.run(258command,259env={260**t_env,261**get_fuzz_env(target=t, source_dir=src_dir),262},263check=True,264stderr=subprocess.PIPE,265text=True,266).stderr,267))269futures = []270for target, t_env in targets:271target_corpus_dir = corpus_dir / target272os.makedirs(target_corpus_dir, exist_ok=True)273use_value_profile = int(random.random() < .3)274command = [275fuzz_bin,276"-rss_limit_mb=8000",277"-max_total_time=6000",278"-reload=0",279f"-use_value_profile={use_value_profile}",280target_corpus_dir,281]282futures.append(fuzz_pool.submit(job, command, target, t_env))284for future in as_completed(futures):285future.result()288def merge_inputs(*, fuzz_pool, corpus, test_list, src_dir, fuzz_bin, merge_dirs):289logging.info(f"Merge the inputs from the passed dir into the corpus_dir. Passed dirs {merge_dirs}")290jobs = []291for t in test_list:292args = [293fuzz_bin,294'-rss_limit_mb=8000',295'-set_cover_merge=1',296# set_cover_merge is used instead of -merge=1 to reduce the overall297# size of the qa-assets git repository a bit, but more importantly,298# to cut the runtime to iterate over all fuzz inputs [0].299# [0] https://github.com/bitcoin-core/qa-assets/issues/130#issuecomment-1761760866300'-shuffle=0',301'-prefer_small=1',302'-use_value_profile=0',303# use_value_profile is enabled by oss-fuzz [0], but disabled for304# now to avoid bloating the qa-assets git repository [1].305# [0] https://github.com/google/oss-fuzz/issues/1406#issuecomment-387790487306# [1] https://github.com/bitcoin-core/qa-assets/issues/130#issuecomment-1749075891307os.path.join(corpus, t),308] + [str(m_dir / t) for m_dir in merge_dirs]309os.makedirs(os.path.join(corpus, t), exist_ok=True)310for m_dir in merge_dirs:311(m_dir / t).mkdir(exist_ok=True)313def job(t, args):314output = 'Run {} with args {}\n'.format(t, " ".join(args))315output += subprocess.run(316args,317env=get_fuzz_env(target=t, source_dir=src_dir),318check=True,319stderr=subprocess.PIPE,320text=True,321).stderr322logging.debug(output)324jobs.append(fuzz_pool.submit(job, t, args))326for future in as_completed(jobs):327future.result()330def run_once(*, fuzz_pool, corpus, test_list, src_dir, fuzz_bin, using_libfuzzer, use_valgrind, empty_min_time):331jobs = []332for t in test_list:333corpus_path = corpus / t334os.makedirs(corpus_path, exist_ok=True)335args = [336fuzz_bin,337]338empty_dir = not any(corpus_path.iterdir())339if using_libfuzzer:340if empty_min_time and empty_dir:341args += [f"-max_total_time={empty_min_time}"]342else:343args += [344"-runs=1",345corpus_path,346]347else:348args += [corpus_path]349if use_valgrind:350args = ['valgrind', '--quiet', '--error-exitcode=1'] + args352def job(t, args):353output = 'Run {} with args {}'.format(t, args)354result = subprocess.run(355args,356env=get_fuzz_env(target=t, source_dir=src_dir),357stderr=subprocess.PIPE,358text=True,359)360output += result.stderr361return output, result, t363jobs.append(fuzz_pool.submit(job, t, args))365stats = []366for future in as_completed(jobs):367output, result, target = future.result()368logging.debug(output)369try:370result.check_returncode()371except subprocess.CalledProcessError as e:372if e.stdout:373logging.info(e.stdout)374if e.stderr:375logging.info(e.stderr)376logging.info(f"⚠️ Failure generated from target with exit code {e.returncode}: {result.args}")377sys.exit(1)378if using_libfuzzer:379done_stat = [l for l in output.splitlines() if "DONE" in l]380assert len(done_stat) == 1381stats.append((target, done_stat[0]))383if using_libfuzzer:384print("Summary:")385max_len = max(len(t[0]) for t in stats)386for t, s in sorted(stats):387t = t.ljust(max_len + 1)388print(f"{t}{s}")391def parse_test_list(*, fuzz_bin, source_dir):392test_list_all = subprocess.run(393fuzz_bin,394env={395'PRINT_ALL_FUZZ_TARGETS_AND_ABORT': '',396**get_fuzz_env(target="", source_dir=source_dir)397},398stdout=subprocess.PIPE,399text=True,400check=True,401).stdout.splitlines()402return test_list_all405if __name__ == '__main__':406main()
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.