p2p_handshake.cpp
1 // Copyright (c) 2020-present The Bitcoin Core developers 2 // Distributed under the MIT software license, see the accompanying 3 // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 5 #include <addrman.h> 6 #include <consensus/consensus.h> 7 #include <net.h> 8 #include <net_processing.h> 9 #include <node/warnings.h> 10 #include <protocol.h> 11 #include <script/script.h> 12 #include <sync.h> 13 #include <test/fuzz/FuzzedDataProvider.h> 14 #include <test/fuzz/fuzz.h> 15 #include <test/fuzz/util.h> 16 #include <test/fuzz/util/net.h> 17 #include <test/util/mining.h> 18 #include <test/util/net.h> 19 #include <test/util/setup_common.h> 20 #include <test/util/validation.h> 21 #include <util/time.h> 22 #include <validationinterface.h> 23 24 #include <ios> 25 #include <string> 26 #include <utility> 27 #include <vector> 28 29 namespace { 30 const TestingSetup* g_setup; 31 32 void initialize() 33 { 34 static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>( 35 /*chain_type=*/ChainType::REGTEST); 36 g_setup = testing_setup.get(); 37 } 38 } // namespace 39 40 FUZZ_TARGET(p2p_handshake, .init = ::initialize) 41 { 42 SeedRandomStateForTest(SeedRand::ZEROS); 43 FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); 44 45 auto& connman = static_cast<ConnmanTestMsg&>(*g_setup->m_node.connman); 46 auto& chainman = static_cast<TestChainstateManager&>(*g_setup->m_node.chainman); 47 SetMockTime(1610000000); // any time to successfully reset ibd 48 chainman.ResetIbd(); 49 50 node::Warnings warnings{}; 51 auto netgroupman{NetGroupManager::NoAsmap()}; 52 AddrMan addrman{netgroupman, /*deterministic=*/true, /*consistency_check_ratio=*/0}; 53 auto peerman = PeerManager::make(connman, addrman, 54 /*banman=*/nullptr, chainman, 55 *g_setup->m_node.mempool, warnings, 56 PeerManager::Options{ 57 .reconcile_txs = true, 58 .deterministic_rng = true, 59 }); 60 connman.SetMsgProc(peerman.get()); 61 62 LOCK(NetEventsInterface::g_msgproc_mutex); 63 64 std::vector<CNode*> peers; 65 const auto num_peers_to_add = fuzzed_data_provider.ConsumeIntegralInRange(1, 3); 66 for (int i = 0; i < num_peers_to_add; ++i) { 67 peers.push_back(ConsumeNodeAsUniquePtr(fuzzed_data_provider, i).release()); 68 connman.AddTestNode(*peers.back()); 69 peerman->InitializeNode( 70 *peers.back(), 71 static_cast<ServiceFlags>(fuzzed_data_provider.ConsumeIntegral<uint64_t>())); 72 } 73 74 LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 100) 75 { 76 CNode& connection = *PickValue(fuzzed_data_provider, peers); 77 if (connection.fDisconnect || connection.fSuccessfullyConnected) { 78 // Skip if the connection was disconnected or if the version 79 // handshake was already completed. 80 continue; 81 } 82 83 SetMockTime(GetTime() + 84 fuzzed_data_provider.ConsumeIntegralInRange<int64_t>( 85 -std::chrono::seconds{10min}.count(), // Allow mocktime to go backwards slightly 86 std::chrono::seconds{TIMEOUT_INTERVAL}.count())); 87 88 CSerializedNetMsg net_msg; 89 net_msg.m_type = PickValue(fuzzed_data_provider, ALL_NET_MESSAGE_TYPES); 90 net_msg.data = ConsumeRandomLengthByteVector(fuzzed_data_provider, MAX_PROTOCOL_MESSAGE_LENGTH); 91 92 connman.FlushSendBuffer(connection); 93 (void)connman.ReceiveMsgFrom(connection, std::move(net_msg)); 94 95 bool more_work{true}; 96 while (more_work) { 97 connection.fPauseSend = false; 98 99 try { 100 more_work = connman.ProcessMessagesOnce(connection); 101 } catch (const std::ios_base::failure&) { 102 } 103 peerman->SendMessages(connection); 104 } 105 } 106 107 g_setup->m_node.connman->StopNodes(); 108 }