p2p_handshake.cpp raw

   1  // Copyright (c) 2020-present The Limenka 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      ConnmanTestMsg& 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      NetGroupManager netgroupman{{}};
  52      AddrMan addrman{netgroupman, /*deterministic=*/true, 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  }
 109