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.
1// Copyright (c) 2020-present The Bitcoin Core developers2// Distributed under the MIT software license, see the accompanying3// file COPYING or http://www.opensource.org/licenses/mit-license.php.5#include <addrman.h>6#include <banman.h>7#include <kernel/chainparams.h>8#include <net.h>9#include <net_processing.h>10#include <primitives/block.h>11#include <primitives/transaction.h>12#include <protocol.h>13#include <sync.h>14#include <test/fuzz/FuzzedDataProvider.h>15#include <test/fuzz/fuzz.h>16#include <test/fuzz/util.h>17#include <test/fuzz/util/net.h>18#include <test/util/net.h>19#include <test/util/random.h>20#include <test/util/setup_common.h>21#include <test/util/time.h>22#include <test/util/validation.h>23#include <uint256.h>24#include <util/check.h>25#include <util/time.h>26#include <validation.h>27#include <validationinterface.h>29#include <functional>30#include <ios>31#include <memory>32#include <optional>33#include <string>34#include <utility>35#include <vector>37namespace {38TestingSetup* g_setup;40} // namespace42extern void MakeRandDeterministicDANGEROUS(const uint256& seed) noexcept;44void initialize_process_messages()45{46FakeNodeClock init_clock{}; // Uses the existing mock time47static const auto testing_setup{48MakeNoLogFileContext<TestingSetup>(49/*chain_type=*/ChainType::REGTEST,50{}),51};52g_setup = testing_setup.get();53// Replace validation_signals before creating chainman and mempool so they use it.54g_setup->m_node.validation_signals = std::make_unique<ValidationSignals>(std::make_unique<ImmediateBackgroundTaskRunner>());55ResetChainmanAndMempool(*g_setup, init_clock);56}58FUZZ_TARGET(process_messages, .init = initialize_process_messages)59{60SeedRandomStateForTest(SeedRand::ZEROS);61FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());63auto& node{g_setup->m_node};64auto& connman{static_cast<ConnmanTestMsg&>(*node.connman)};65connman.Reset();66auto& chainman{static_cast<TestChainstateManager&>(*node.chainman)};67const auto block_index_size{WITH_LOCK(chainman.GetMutex(), return chainman.BlockIndex().size())};68const auto initial_sequence{WITH_LOCK(node.mempool->cs, return node.mempool->GetSequence())};69FakeNodeClock node_clock{1610000000s}; // 2021-01-07, arbitrary70FakeSteadyClock steady_clock;71chainman.ResetIbd();72chainman.DisableNextWrite();74// Reset, so that dangling pointers can be detected by sanitizers.75node.banman.reset();76node.addrman.reset();77node.peerman.reset();78node.addrman = std::make_unique<AddrMan>(*node.netgroupman, /*deterministic=*/true, /*consistency_check_ratio=*/0);79node.peerman = PeerManager::make(connman, *node.addrman,80/*banman=*/nullptr, chainman,81*node.mempool, *node.warnings,82PeerManager::Options{83.reconcile_txs = true,84.deterministic_rng = true,85});86connman.SetMsgProc(node.peerman.get());87connman.SetAddrman(*node.addrman);89node.validation_signals->RegisterValidationInterface(node.peerman.get());91LOCK(NetEventsInterface::g_msgproc_mutex);93std::vector<CNode*> peers;94const auto num_peers_to_add = fuzzed_data_provider.ConsumeIntegralInRange(1, 3);95for (int i = 0; i < num_peers_to_add; ++i) {96peers.push_back(ConsumeNodeAsUniquePtr(fuzzed_data_provider, steady_clock, i).release());97CNode& p2p_node = *peers.back();99FillNode(fuzzed_data_provider, connman, p2p_node);101connman.AddTestNode(p2p_node);102}104// Toggle IBD from within the loop, so that some messages may be processed105// under IBD and the rest after leaving it. JumpOutOfIbd() latches, so guard106// it to call at most once.107bool jump_out_of_ibd{false};108LIMITED_WHILE (fuzzed_data_provider.ConsumeBool(), 30) {109if (!jump_out_of_ibd) jump_out_of_ibd = fuzzed_data_provider.ConsumeBool();110if (jump_out_of_ibd && chainman.IsInitialBlockDownload()) chainman.JumpOutOfIbd();111const std::string random_message_type{fuzzed_data_provider.ConsumeBytesAsString(CMessageHeader::MESSAGE_TYPE_SIZE).c_str()};113node_clock.set(ConsumeTime(fuzzed_data_provider));115CSerializedNetMsg net_msg;116net_msg.m_type = random_message_type;117net_msg.data = ConsumeRandomLengthByteVector(fuzzed_data_provider, MAX_PROTOCOL_MESSAGE_LENGTH);119CNode& random_node = *PickValue(fuzzed_data_provider, peers);121connman.FlushSendBuffer(random_node);122(void)connman.ReceiveMsgFrom(random_node, std::move(net_msg));124bool more_work{true};125while (more_work) { // Ensure that every message is eventually processed in some way or another126random_node.fPauseSend = false;128try {129more_work = connman.ProcessMessagesOnce(random_node);130} catch (const std::ios_base::failure&) {131}132node.peerman->SendMessages(random_node);133}134}135node.validation_signals->SyncWithValidationInterfaceQueue();136node.validation_signals->UnregisterValidationInterface(node.peerman.get());137node.connman->StopNodes();138const auto end_sequence{WITH_LOCK(node.mempool->cs, return node.mempool->GetSequence())};139if (block_index_size != WITH_LOCK(chainman.GetMutex(), return chainman.BlockIndex().size()) || initial_sequence != end_sequence) {140// Reuse the global chainman and mempool, but reset them when dirty.141MakeRandDeterministicDANGEROUS(uint256::ZERO);142ResetChainmanAndMempool(*g_setup, node_clock);143}144}
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.