LCOV - code coverage report
Current view: top level - src/test/fuzz - process_message_e2e.cpp (source / functions) Hit Total Coverage
Test: fuzz_coverage.info Lines: 37 42 88.1 %
Date: 2023-11-06 23:13:05 Functions: 4 8 50.0 %
Branches: 37 66 56.1 %

           Branch data     Line data    Source code
       1                 :            : // Copyright (c) 2020-2022 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 <consensus/consensus.h>
       6                 :            : #include <net.h>
       7                 :            : #include <net_processing.h>
       8                 :            : #include <node/connection_types.h>
       9                 :            : #include <primitives/transaction.h>
      10                 :            : #include <protocol.h>
      11                 :            : #include <script/script.h>
      12                 :            : #include <test/fuzz/FuzzedDataProvider.h>
      13                 :            : #include <test/fuzz/fuzz.h>
      14                 :            : #include <test/fuzz/util.h>
      15                 :            : #include <test/util/mining.h>
      16                 :            : #include <test/util/setup_common.h>
      17         [ +  - ]:          2 : #include <test/util/validation.h>
      18         [ +  - ]:          2 : #include <util/chaintype.h>
      19                 :            : #include <util/check.h>
      20                 :            : #include <util/time.h>
      21                 :            : #include <validationinterface.h>
      22                 :            : 
      23                 :            : #include <algorithm>
      24                 :            : #include <cstdlib>
      25                 :            : #include <memory>
      26                 :            : #include <optional>
      27                 :            : #include <stdint.h>
      28                 :            : #include <string.h>
      29                 :            : #include <string>
      30                 :            : #include <string_view>
      31                 :            : #include <vector>
      32                 :            : 
      33                 :            : // There are two sets of tests:
      34                 :            : // - direct: pass the fuzzed message directly to PeerManager::ProcessMessage() (fuzz/process_message.cpp)
      35                 :            : // - e2e: send the fuzzed message to a mocked socket which is read from Connman
      36                 :            : //   and processed by PeerManager (like it is happening in the "real world") (fuzz/process_message_e2e.cpp)
      37                 :            : 
      38                 :            : namespace {
      39                 :            : NetTestingSetup* g_setup;
      40                 :            : std::string_view LIMIT_TO_MESSAGE_TYPE{};
      41                 :            : } // namespace
      42                 :            : 
      43                 :          1 : void initialize_process_message_e2e()
      44                 :            : {
      45         [ +  - ]:          1 :     if (const auto val{std::getenv("LIMIT_TO_MESSAGE_TYPE")}) {
      46                 :          0 :         LIMIT_TO_MESSAGE_TYPE = val;
      47                 :          0 :         Assert(std::count(getAllNetMessageTypes().begin(), getAllNetMessageTypes().end(), LIMIT_TO_MESSAGE_TYPE)); // Unknown message type passed
      48                 :          0 :     }
      49                 :            : 
      50 [ +  - ][ -  + ]:          2 :     static const auto testing_setup = MakeNoLogFileContext<NetTestingSetup>(
                 [ -  + ]
      51                 :            :             /*chain_type=*/ChainType::REGTEST,
      52         [ +  - ]:          1 :             /*extra_args=*/{"-txreconciliation"});
      53                 :          1 :     g_setup = testing_setup.get();
      54         [ +  + ]:        201 :     for (int i = 0; i < 2 * COINBASE_MATURITY; ++i) {
      55 [ +  - ][ +  - ]:        200 :         MineBlock(g_setup->m_node, CScript() << OP_TRUE);
      56                 :        200 :     }
      57                 :          1 :     SyncWithValidationInterfaceQueue();
      58                 :          1 : }
      59                 :            : 
      60         [ +  - ]:        148 : FUZZ_TARGET(process_message_e2e, .init = initialize_process_message_e2e)
      61                 :            : {
      62                 :        144 :     FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
      63                 :            : 
      64         [ +  - ]:        144 :     const std::string random_message_type{fuzzed_data_provider.ConsumeBytesAsString(CMessageHeader::COMMAND_SIZE).c_str()};
      65 [ -  + ][ #  # ]:        144 :     if (!LIMIT_TO_MESSAGE_TYPE.empty() && random_message_type != LIMIT_TO_MESSAGE_TYPE) {
      66                 :          0 :         return;
      67                 :            :     }
      68                 :            : 
      69                 :            :     // Enter IBD. Since the chain tip is from 2011, set the mock time so that the chain tip
      70                 :            :     // is 24h or older. 1610000000 is from 2021.
      71         [ +  - ]:        144 :     SetMockTime(1610000000);
      72         [ +  - ]:        144 :     static_cast<TestChainstateManager&>(*g_setup->m_node.chainman).ResetIbd();
      73                 :            : 
      74 [ +  - ][ +  - ]:        144 :     g_setup->m_node.connman->OpenNetworkConnection(/*addrConnect=*/CAddress{},
      75                 :            :                                                    /*fCountFailure=*/false,
      76                 :        144 :                                                    /*grant_outbound=*/CSemaphoreGrant{},
      77                 :            :                                                    /*strDest=*/"1.2.3.4:8333",
      78                 :            :                                                    /*conn_type=*/ConnectionType::OUTBOUND_FULL_RELAY,
      79                 :            :                                                    /*use_v2transport=*/false);
      80                 :            : 
      81         [ +  - ]:        144 :     const auto pipes{g_setup->m_sockets_pipes.PopFront()};
      82                 :            : 
      83         [ +  - ]:          2 :     uint8_t buf[1024];
      84                 :            : 
      85 [ +  - ][ +  + ]:       5533 :     LIMITED_WHILE(fuzzed_data_provider.remaining_bytes() > 0, 100) {
                 [ +  + ]
      86                 :            : 
      87         [ +  - ]:       5391 :         pipes->recv.PushNetMsg(random_message_type, ConsumeRandomLengthByteVector(fuzzed_data_provider));
      88                 :            : 
      89 [ +  - ][ +  + ]:       5391 :         if (pipes->send.GetBytes(buf, sizeof(buf)) == 0) { // EOF, the socket has been closed.
      90                 :          2 :             return;
      91                 :            :         }
      92                 :            : 
      93                 :            :         // Will jump out of IBD if it happens to be before the chain tip (2011).
      94                 :       5389 :         const auto mock_time = ConsumeTime(fuzzed_data_provider);
      95         [ +  - ]:       5389 :         SetMockTime(mock_time);
      96                 :       5389 :     }
      97                 :            : 
      98                 :            :     // Force a disconnect and wait for it.
      99         [ +  - ]:        143 :     g_setup->m_node.connman->ForEachNode([&](CNode* node) {
     100                 :          1 :         g_setup->m_node.peerman->UnitTestMisbehaving(node->GetId(), DISCOURAGEMENT_THRESHOLD);
     101                 :          1 :     });
     102                 :        142 :     memset(buf, 0x0, sizeof(buf));
     103         [ +  - ]:        142 :     pipes->recv.PushBytes(buf, sizeof(buf));
     104 [ +  - ][ +  + ]:        206 :     while (pipes->send.GetNetMsg().has_value()) {
     105                 :            :         ;
     106                 :            :     }
     107                 :            : 
     108         [ +  - ]:        142 :     SyncWithValidationInterfaceQueue();
     109         [ -  + ]:        144 : }

Generated by: LCOV version 1.14