LCOV - code coverage report
Current view: top level - src/test/fuzz - p2p_transport_serialization.cpp (source / functions) Coverage Total Hit
Test: fuzz_coverage.info Lines: 97.9 % 234 229
Test Date: 2024-09-01 05:20:30 Functions: 95.8 % 24 23
Branches: 64.2 % 293 188

             Branch data     Line data    Source code
       1                 :             : // Copyright (c) 2019-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 <chainparams.h>
       6                 :             : #include <hash.h>
       7                 :             : #include <net.h>
       8                 :             : #include <netmessagemaker.h>
       9                 :             : #include <protocol.h>
      10                 :             : #include <test/fuzz/FuzzedDataProvider.h>
      11                 :             : #include <test/fuzz/fuzz.h>
      12                 :             : #include <test/fuzz/util.h>
      13                 :             : #include <util/chaintype.h>
      14                 :             : 
      15                 :             : #include <algorithm>
      16                 :             : #include <cassert>
      17                 :             : #include <cstdint>
      18                 :             : #include <limits>
      19                 :             : #include <optional>
      20                 :             : #include <vector>
      21                 :             : 
      22                 :             : namespace {
      23                 :             : 
      24                 :           1 : auto g_all_messages = ALL_NET_MESSAGE_TYPES;
      25                 :             : 
      26                 :           0 : void initialize_p2p_transport_serialization()
      27                 :             : {
      28   [ #  #  #  #  :           0 :     static ECC_Context ecc_context{};
                   #  # ]
      29                 :           0 :     SelectParams(ChainType::REGTEST);
      30                 :           0 :     std::sort(g_all_messages.begin(), g_all_messages.end());
      31                 :           0 : }
      32                 :             : 
      33                 :             : } // namespace
      34                 :             : 
      35         [ +  - ]:         449 : FUZZ_TARGET(p2p_transport_serialization, .init = initialize_p2p_transport_serialization)
      36                 :             : {
      37                 :             :     // Construct transports for both sides, with dummy NodeIds.
      38                 :         447 :     V1Transport recv_transport{NodeId{0}};
      39                 :         447 :     V1Transport send_transport{NodeId{1}};
      40                 :             : 
      41         [ +  - ]:         447 :     FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
      42                 :             : 
      43         [ +  - ]:         447 :     auto checksum_assist = fuzzed_data_provider.ConsumeBool();
      44         [ +  - ]:         447 :     auto magic_bytes_assist = fuzzed_data_provider.ConsumeBool();
      45                 :         447 :     std::vector<uint8_t> mutable_msg_bytes;
      46                 :             : 
      47                 :         447 :     auto header_bytes_remaining = CMessageHeader::HEADER_SIZE;
      48         [ +  + ]:         447 :     if (magic_bytes_assist) {
      49   [ +  -  +  - ]:         363 :         auto msg_start = Params().MessageStart();
      50         [ +  + ]:        1815 :         for (size_t i = 0; i < CMessageHeader::MESSAGE_SIZE_SIZE; ++i) {
      51         [ +  - ]:        1452 :             mutable_msg_bytes.push_back(msg_start[i]);
      52                 :        1452 :         }
      53                 :         363 :         header_bytes_remaining -= CMessageHeader::MESSAGE_SIZE_SIZE;
      54                 :         363 :     }
      55                 :             : 
      56         [ +  + ]:         447 :     if (checksum_assist) {
      57                 :         218 :         header_bytes_remaining -= CMessageHeader::CHECKSUM_SIZE;
      58                 :         218 :     }
      59                 :             : 
      60         [ +  - ]:         447 :     auto header_random_bytes = fuzzed_data_provider.ConsumeBytes<uint8_t>(header_bytes_remaining);
      61         [ +  - ]:         447 :     mutable_msg_bytes.insert(mutable_msg_bytes.end(), header_random_bytes.begin(), header_random_bytes.end());
      62         [ +  - ]:         447 :     auto payload_bytes = fuzzed_data_provider.ConsumeRemainingBytes<uint8_t>();
      63                 :             : 
      64   [ +  +  +  + ]:         447 :     if (checksum_assist && mutable_msg_bytes.size() == CMessageHeader::CHECKSUM_OFFSET) {
      65         [ +  - ]:         216 :         CHash256 hasher;
      66                 :         216 :         unsigned char hsh[32];
      67   [ +  -  +  - ]:         216 :         hasher.Write(payload_bytes);
      68         [ +  - ]:         216 :         hasher.Finalize(hsh);
      69         [ +  + ]:        1080 :         for (size_t i = 0; i < CMessageHeader::CHECKSUM_SIZE; ++i) {
      70         [ +  - ]:         864 :            mutable_msg_bytes.push_back(hsh[i]);
      71                 :         864 :         }
      72                 :         216 :     }
      73                 :             : 
      74         [ +  - ]:         447 :     mutable_msg_bytes.insert(mutable_msg_bytes.end(), payload_bytes.begin(), payload_bytes.end());
      75         [ +  - ]:         447 :     Span<const uint8_t> msg_bytes{mutable_msg_bytes};
      76         [ +  + ]:      136501 :     while (msg_bytes.size() > 0) {
      77   [ +  -  +  + ]:      136172 :         if (!recv_transport.ReceivedBytes(msg_bytes)) {
      78                 :         118 :             break;
      79                 :             :         }
      80   [ +  -  +  + ]:      136054 :         if (recv_transport.ReceivedMessageComplete()) {
      81                 :       79562 :             const std::chrono::microseconds m_time{std::numeric_limits<int64_t>::max()};
      82                 :       79562 :             bool reject_message{false};
      83         [ -  + ]:       79562 :             CNetMessage msg = recv_transport.GetReceivedMessage(m_time, reject_message);
      84         [ -  + ]:       79562 :             assert(msg.m_type.size() <= CMessageHeader::COMMAND_SIZE);
      85         [ -  + ]:       79562 :             assert(msg.m_raw_message_size <= mutable_msg_bytes.size());
      86         [ -  + ]:       79562 :             assert(msg.m_raw_message_size == CMessageHeader::HEADER_SIZE + msg.m_message_size);
      87   [ -  +  -  + ]:       79562 :             assert(msg.m_time == m_time);
      88                 :             : 
      89                 :       79562 :             std::vector<unsigned char> header;
      90   [ -  +  +  -  :       79562 :             auto msg2 = NetMsg::Make(msg.m_type, Span{msg.m_recv});
                   +  - ]
      91                 :       79562 :             bool queued = send_transport.SetMessageToSend(msg2);
      92         [ -  + ]:       79562 :             assert(queued);
      93                 :       79562 :             std::optional<bool> known_more;
      94                 :      215316 :             while (true) {
      95                 :      351070 :                 const auto& [to_send, more, _msg_type] = send_transport.GetBytesToSend(false);
      96   [ +  +  +  - ]:      215316 :                 if (known_more) assert(!to_send.empty() == *known_more);
      97         [ +  + ]:      215316 :                 if (to_send.empty()) break;
      98                 :      135754 :                 send_transport.MarkBytesSent(to_send.size());
      99                 :      271508 :                 known_more = more;
     100      [ +  -  + ]:      215316 :             }
     101                 :       79562 :         }
     102                 :             :     }
     103                 :         447 : }
     104                 :             : 
     105                 :             : namespace {
     106                 :             : 
     107                 :             : template<RandomNumberGenerator R>
     108                 :        2266 : void SimulationTest(Transport& initiator, Transport& responder, R& rng, FuzzedDataProvider& provider)
     109                 :             : {
     110                 :             :     // Simulation test with two Transport objects, which send messages to each other, with
     111                 :             :     // sending and receiving fragmented into multiple pieces that may be interleaved. It primarily
     112                 :             :     // verifies that the sending and receiving side are compatible with each other, plus a few
     113                 :             :     // sanity checks. It does not attempt to introduce errors in the communicated data.
     114                 :             : 
     115                 :             :     // Put the transports in an array for by-index access.
     116                 :        2266 :     const std::array<Transport*, 2> transports = {&initiator, &responder};
     117                 :             : 
     118                 :             :     // Two vectors representing in-flight bytes. inflight[i] is from transport[i] to transport[!i].
     119                 :        2266 :     std::array<std::vector<uint8_t>, 2> in_flight;
     120                 :             : 
     121                 :             :     // Two queues with expected messages. expected[i] is expected to arrive in transport[!i].
     122         [ +  - ]:        2266 :     std::array<std::deque<CSerializedNetMsg>, 2> expected;
     123                 :             : 
     124                 :             :     // Vectors with bytes last returned by GetBytesToSend() on transport[i].
     125                 :        2266 :     std::array<std::vector<uint8_t>, 2> to_send;
     126                 :             : 
     127                 :             :     // Last returned 'more' values (if still relevant) by transport[i]->GetBytesToSend(), for
     128                 :             :     // both have_next_message false and true.
     129                 :        2266 :     std::array<std::optional<bool>, 2> last_more, last_more_next;
     130                 :             : 
     131                 :             :     // Whether more bytes to be sent are expected on transport[i], before and after
     132                 :             :     // SetMessageToSend().
     133                 :        2266 :     std::array<std::optional<bool>, 2> expect_more, expect_more_next;
     134                 :             : 
     135                 :             :     // Function to consume a message type.
     136                 :       69827 :     auto msg_type_fn = [&]() {
     137                 :       67561 :         uint8_t v = provider.ConsumeIntegral<uint8_t>();
     138         [ +  + ]:       67561 :         if (v == 0xFF) {
     139                 :             :             // If v is 0xFF, construct a valid (but possibly unknown) message type from the fuzz
     140                 :             :             // data.
     141                 :       10088 :             std::string ret;
     142         [ +  + ]:       45393 :             while (ret.size() < CMessageHeader::COMMAND_SIZE) {
     143         [ +  - ]:       43866 :                 char c = provider.ConsumeIntegral<char>();
     144                 :             :                 // Match the allowed characters in CMessageHeader::IsCommandValid(). Any other
     145                 :             :                 // character is interpreted as end.
     146   [ +  +  +  + ]:       43866 :                 if (c < ' ' || c > 0x7E) break;
     147         [ +  - ]:       35305 :                 ret += c;
     148      [ -  +  + ]:       43866 :             }
     149                 :       10088 :             return ret;
     150                 :       10088 :         } else {
     151                 :             :             // Otherwise, use it as index into the list of known messages.
     152                 :       57473 :             return g_all_messages[v % g_all_messages.size()];
     153                 :             :         }
     154                 :       67561 :     };
     155                 :             : 
     156                 :             :     // Function to construct a CSerializedNetMsg to send.
     157                 :       74359 :     auto make_msg_fn = [&](bool first) {
     158                 :       72093 :         CSerializedNetMsg msg;
     159         [ +  + ]:       72093 :         if (first) {
     160                 :             :             // Always send a "version" message as first one.
     161         [ +  - ]:        4532 :             msg.m_type = "version";
     162                 :        4532 :         } else {
     163         [ +  - ]:       67561 :             msg.m_type = msg_type_fn();
     164                 :             :         }
     165                 :             :         // Determine size of message to send (limited to 75 kB for performance reasons).
     166         [ +  - ]:       72093 :         size_t size = provider.ConsumeIntegralInRange<uint32_t>(0, 75000);
     167                 :             :         // Get payload of message from RNG.
     168                 :       72093 :         msg.data = rng.randbytes(size);
     169                 :             :         // Return.
     170                 :       72093 :         return msg;
     171                 :       72093 :     };
     172                 :             : 
     173                 :             :     // The next message to be sent (initially version messages, but will be replaced once sent).
     174                 :        2266 :     std::array<CSerializedNetMsg, 2> next_msg = {
     175         [ +  - ]:        2266 :         make_msg_fn(/*first=*/true),
     176         [ +  - ]:        2266 :         make_msg_fn(/*first=*/true)
     177                 :             :     };
     178                 :             : 
     179                 :             :     // Wrapper around transport[i]->GetBytesToSend() that performs sanity checks.
     180                 :     1195094 :     auto bytes_to_send_fn = [&](int side) -> Transport::BytesToSend {
     181                 :             :         // Invoke GetBytesToSend twice (for have_next_message = {false, true}). This function does
     182                 :             :         // not modify state (it's const), and only the "more" return value should differ between
     183                 :             :         // the calls.
     184                 :    11344774 :         const auto& [bytes, more_nonext, msg_type] = transports[side]->GetBytesToSend(false);
     185                 :     4187806 :         const auto& [bytes_next, more_next, msg_type_next] = transports[side]->GetBytesToSend(true);
     186                 :             :         // Compare with expected more.
     187   [ +  +  +  - ]:     1192828 :         if (expect_more[side].has_value()) assert(!bytes.empty() == *expect_more[side]);
     188                 :             :         // Verify consistency between the two results.
     189         [ +  - ]:     1192828 :         assert(std::ranges::equal(bytes, bytes_next));
     190         [ +  - ]:     1192828 :         assert(msg_type == msg_type_next);
     191   [ +  +  +  - ]:     1192828 :         if (more_nonext) assert(more_next);
     192                 :             :         // Compare with previously reported output.
     193   [ +  -  +  - ]:     2385656 :         assert(to_send[side].size() <= bytes.size());
     194   [ +  -  +  - ]:     2385656 :         assert(std::ranges::equal(to_send[side], Span{bytes}.first(to_send[side].size())));
     195                 :     2385656 :         to_send[side].resize(bytes.size());
     196                 :     2385656 :         std::copy(bytes.begin(), bytes.end(), to_send[side].begin());
     197                 :             :         // Remember 'more' results.
     198                 :     2385656 :         last_more[side] = {more_nonext};
     199                 :     2385656 :         last_more_next[side] = {more_next};
     200                 :             :         // Return.
     201                 :     1192828 :         return {bytes, more_nonext, msg_type};
     202                 :     1192828 :     };
     203                 :             : 
     204                 :             :     // Function to make side send a new message.
     205                 :      354468 :     auto new_msg_fn = [&](int side) {
     206                 :             :         // Don't do anything if there are too many unreceived messages already.
     207         [ +  + ]:      352202 :         if (expected[side].size() >= 16) return;
     208                 :             :         // Try to send (a copy of) the message in next_msg[side].
     209                 :      348398 :         CSerializedNetMsg msg = next_msg[side].Copy();
     210                 :      348398 :         bool queued = transports[side]->SetMessageToSend(msg);
     211                 :             :         // Update expected more data.
     212                 :      348398 :         expect_more[side] = expect_more_next[side];
     213                 :      348398 :         expect_more_next[side] = std::nullopt;
     214                 :             :         // Verify consistency of GetBytesToSend after SetMessageToSend
     215         [ +  - ]:      348398 :         bytes_to_send_fn(/*side=*/side);
     216         [ +  + ]:      348398 :         if (queued) {
     217                 :             :             // Remember that this message is now expected by the receiver.
     218         [ +  - ]:       67561 :             expected[side].emplace_back(std::move(next_msg[side]));
     219                 :             :             // Construct a new next message to send.
     220         [ +  - ]:       67561 :             next_msg[side] = make_msg_fn(/*first=*/false);
     221                 :       67561 :         }
     222                 :      352202 :     };
     223                 :             : 
     224                 :             :     // Function to make side send out bytes (if any).
     225                 :      423995 :     auto send_fn = [&](int side, bool everything = false) {
     226                 :     1502843 :         const auto& [bytes, more, msg_type] = bytes_to_send_fn(/*side=*/side);
     227                 :             :         // Don't do anything if no bytes to send.
     228         [ +  + ]:      421729 :         if (bytes.empty()) return false;
     229         [ +  + ]:      308677 :         size_t send_now = everything ? bytes.size() : provider.ConsumeIntegralInRange<size_t>(0, bytes.size());
     230         [ +  + ]:      308677 :         if (send_now == 0) return false;
     231                 :             :         // Add bytes to the in-flight queue, and mark those bytes as consumed.
     232                 :      772437 :         in_flight[side].insert(in_flight[side].end(), bytes.begin(), bytes.begin() + send_now);
     233                 :      257479 :         transports[side]->MarkBytesSent(send_now);
     234                 :             :         // If all to-be-sent bytes were sent, move last_more data to expect_more data.
     235   [ +  +  +  + ]:      514958 :         if (send_now == bytes.size()) {
     236                 :       82814 :             expect_more[side] = last_more[side];
     237                 :       82814 :             expect_more_next[side] = last_more_next[side];
     238                 :       82814 :         }
     239                 :             :         // Remove the bytes from the last reported to-be-sent vector.
     240         [ +  - ]:      257479 :         assert(to_send[side].size() >= send_now);
     241                 :      257479 :         to_send[side].erase(to_send[side].begin(), to_send[side].begin() + send_now);
     242                 :             :         // Verify that GetBytesToSend gives a result consistent with earlier.
     243                 :      257479 :         bytes_to_send_fn(/*side=*/side);
     244                 :             :         // Return whether anything was sent.
     245                 :      257479 :         return send_now > 0;
     246                 :      421729 :     };
     247                 :             : 
     248                 :             :     // Function to make !side receive bytes (if any).
     249                 :      140972 :     auto recv_fn = [&](int side, bool everything = false) {
     250                 :             :         // Don't do anything if no bytes in flight.
     251         [ +  + ]:      138706 :         if (in_flight[side].empty()) return false;
     252                 :             :         // Decide span to receive
     253                 :      108404 :         size_t to_recv_len = in_flight[side].size();
     254         [ +  + ]:      108404 :         if (!everything) to_recv_len = provider.ConsumeIntegralInRange<size_t>(0, to_recv_len);
     255                 :      108404 :         Span<const uint8_t> to_recv = Span{in_flight[side]}.first(to_recv_len);
     256                 :             :         // Process those bytes
     257         [ +  + ]:      273626 :         while (!to_recv.empty()) {
     258                 :      165222 :             size_t old_len = to_recv.size();
     259                 :      165222 :             bool ret = transports[!side]->ReceivedBytes(to_recv);
     260                 :             :             // Bytes must always be accepted, as this test does not introduce any errors in
     261                 :             :             // communication.
     262         [ +  - ]:      165222 :             assert(ret);
     263                 :             :             // Clear cached expected 'more' information: if certainly no more data was to be sent
     264                 :             :             // before, receiving bytes makes this uncertain.
     265         [ +  + ]:      165222 :             if (expect_more[!side] == false) expect_more[!side] = std::nullopt;
     266         [ +  + ]:      165222 :             if (expect_more_next[!side] == false) expect_more_next[!side] = std::nullopt;
     267                 :             :             // Verify consistency of GetBytesToSend after ReceivedBytes
     268                 :      165222 :             bytes_to_send_fn(/*side=*/!side);
     269                 :      165222 :             bool progress = to_recv.size() < old_len;
     270         [ +  + ]:      165222 :             if (transports[!side]->ReceivedMessageComplete()) {
     271                 :       67561 :                 bool reject{false};
     272                 :       67561 :                 auto received = transports[!side]->GetReceivedMessage({}, reject);
     273                 :             :                 // Receiving must succeed.
     274         [ -  + ]:       67561 :                 assert(!reject);
     275                 :             :                 // There must be a corresponding expected message.
     276         [ -  + ]:       67561 :                 assert(!expected[side].empty());
     277                 :             :                 // The m_message_size field must be correct.
     278         [ -  + ]:       67561 :                 assert(received.m_message_size == received.m_recv.size());
     279                 :             :                 // The m_type must match what is expected.
     280         [ -  + ]:       67561 :                 assert(received.m_type == expected[side].front().m_type);
     281                 :             :                 // The data must match what is expected.
     282   [ -  +  +  - ]:       67561 :                 assert(std::ranges::equal(received.m_recv, MakeByteSpan(expected[side].front().data)));
     283                 :       67561 :                 expected[side].pop_front();
     284                 :       67561 :                 progress = true;
     285                 :       67561 :             }
     286                 :             :             // Progress must be made (by processing incoming bytes and/or returning complete
     287                 :             :             // messages) until all received bytes are processed.
     288         [ +  - ]:      165222 :             assert(progress);
     289                 :      165222 :         }
     290                 :             :         // Remove the processed bytes from the in_flight buffer.
     291                 :      108404 :         in_flight[side].erase(in_flight[side].begin(), in_flight[side].begin() + to_recv_len);
     292                 :             :         // Return whether anything was received.
     293                 :      108404 :         return to_recv_len > 0;
     294                 :      138706 :     };
     295                 :             : 
     296                 :             :     // Main loop, interleaving new messages, sends, and receives.
     297   [ +  -  +  +  :      892935 :     LIMITED_WHILE(provider.remaining_bytes(), 1000) {
                   +  + ]
     298   [ +  -  +  - ]:     1781338 :         CallOneOf(provider,
     299                 :             :             // (Try to) give the next message to the transport.
     300                 :     1142997 :             [&] { new_msg_fn(/*side=*/0); },
     301                 :      990543 :             [&] { new_msg_fn(/*side=*/1); },
     302                 :             :             // (Try to) send some bytes from the transport to the network.
     303                 :     1027882 :             [&] { send_fn(/*side=*/0); },
     304                 :     1164201 :             [&] { send_fn(/*side=*/1); },
     305                 :             :             // (Try to) receive bytes from the network, converting to messages.
     306                 :      963951 :             [&] { recv_fn(/*side=*/0); },
     307                 :      945109 :             [&] { recv_fn(/*side=*/1); }
     308                 :             :         );
     309                 :      890669 :     }
     310                 :             : 
     311                 :             :     // When we're done, perform sends and receives of existing messages to flush anything already
     312                 :             :     // in flight.
     313                 :        5492 :     while (true) {
     314                 :        5492 :         bool any = false;
     315   [ +  -  +  + ]:        5492 :         if (send_fn(/*side=*/0, /*everything=*/true)) any = true;
     316   [ +  -  +  + ]:        5492 :         if (send_fn(/*side=*/1, /*everything=*/true)) any = true;
     317   [ +  -  +  + ]:        5492 :         if (recv_fn(/*side=*/0, /*everything=*/true)) any = true;
     318   [ +  -  +  + ]:        5492 :         if (recv_fn(/*side=*/1, /*everything=*/true)) any = true;
     319         [ +  + ]:        5492 :         if (!any) break;
     320      [ -  +  + ]:        5492 :     }
     321                 :             : 
     322                 :             :     // Make sure nothing is left in flight.
     323         [ +  - ]:        2266 :     assert(in_flight[0].empty());
     324         [ +  - ]:        2266 :     assert(in_flight[1].empty());
     325                 :             : 
     326                 :             :     // Make sure all expected messages were received.
     327         [ +  - ]:        2266 :     assert(expected[0].empty());
     328         [ +  - ]:        2266 :     assert(expected[1].empty());
     329                 :             : 
     330                 :             :     // Compare session IDs.
     331   [ +  -  +  - ]:        2266 :     assert(transports[0]->GetInfo().session_id == transports[1]->GetInfo().session_id);
     332                 :        2266 : }
     333                 :             : 
     334                 :        1755 : std::unique_ptr<Transport> MakeV1Transport(NodeId nodeid) noexcept
     335                 :             : {
     336         [ +  - ]:        1755 :     return std::make_unique<V1Transport>(nodeid);
     337                 :             : }
     338                 :             : 
     339                 :             : template<RandomNumberGenerator RNG>
     340                 :        3003 : std::unique_ptr<Transport> MakeV2Transport(NodeId nodeid, bool initiator, RNG& rng, FuzzedDataProvider& provider)
     341                 :             : {
     342                 :             :     // Retrieve key
     343                 :        3003 :     auto key = ConsumePrivateKey(provider);
     344   [ +  -  +  + ]:        3003 :     if (!key.IsValid()) return {};
     345                 :             :     // Construct garbage
     346                 :        2877 :     size_t garb_len = provider.ConsumeIntegralInRange<size_t>(0, V2Transport::MAX_GARBAGE_LEN);
     347                 :        2877 :     std::vector<uint8_t> garb;
     348         [ +  + ]:        2877 :     if (garb_len <= 64) {
     349                 :             :         // When the garbage length is up to 64 bytes, read it directly from the fuzzer input.
     350         [ +  - ]:        1086 :         garb = provider.ConsumeBytes<uint8_t>(garb_len);
     351         [ +  - ]:        1086 :         garb.resize(garb_len);
     352                 :        1086 :     } else {
     353                 :             :         // If it's longer, generate it from the RNG. This avoids having large amounts of
     354                 :             :         // (hopefully) irrelevant data needing to be stored in the fuzzer data.
     355                 :        1791 :         garb = rng.randbytes(garb_len);
     356                 :             :     }
     357                 :             :     // Retrieve entropy
     358         [ +  - ]:        2877 :     auto ent = provider.ConsumeBytes<std::byte>(32);
     359         [ +  - ]:        2877 :     ent.resize(32);
     360                 :             :     // Use as entropy SHA256(ent || garbage). This prevents a situation where the fuzzer manages to
     361                 :             :     // include the garbage terminator (which is a function of both ellswift keys) in the garbage.
     362                 :             :     // This is extremely unlikely (~2^-116) with random keys/garbage, but the fuzzer can choose
     363                 :             :     // both non-randomly and dependently. Since the entropy is hashed anyway inside the ellswift
     364                 :             :     // computation, no coverage should be lost by using a hash as entropy, and it removes the
     365                 :             :     // possibility of garbage that happens to contain what is effectively a hash of the keys.
     366   [ +  -  +  - ]:        5754 :     CSHA256().Write(UCharCast(ent.data()), ent.size())
     367         [ +  - ]:        2877 :              .Write(garb.data(), garb.size())
     368         [ +  - ]:        2877 :              .Finalize(UCharCast(ent.data()));
     369                 :             : 
     370         [ +  - ]:        2877 :     return std::make_unique<V2Transport>(nodeid, initiator, key, ent, std::move(garb));
     371                 :        3003 : }
     372                 :             : 
     373                 :             : } // namespace
     374                 :             : 
     375         [ +  - ]:         543 : FUZZ_TARGET(p2p_transport_bidirectional, .init = initialize_p2p_transport_serialization)
     376                 :             : {
     377                 :             :     // Test with two V1 transports talking to each other.
     378                 :         541 :     FuzzedDataProvider provider{buffer.data(), buffer.size()};
     379                 :         541 :     InsecureRandomContext rng(provider.ConsumeIntegral<uint64_t>());
     380                 :         541 :     auto t1 = MakeV1Transport(NodeId{0});
     381                 :         541 :     auto t2 = MakeV1Transport(NodeId{1});
     382   [ +  -  -  + ]:         541 :     if (!t1 || !t2) return;
     383         [ +  - ]:         541 :     SimulationTest(*t1, *t2, rng, provider);
     384         [ -  + ]:         541 : }
     385                 :             : 
     386         [ +  - ]:        1167 : FUZZ_TARGET(p2p_transport_bidirectional_v2, .init = initialize_p2p_transport_serialization)
     387                 :             : {
     388                 :             :     // Test with two V2 transports talking to each other.
     389                 :        1165 :     FuzzedDataProvider provider{buffer.data(), buffer.size()};
     390                 :        1165 :     InsecureRandomContext rng(provider.ConsumeIntegral<uint64_t>());
     391                 :        1165 :     auto t1 = MakeV2Transport(NodeId{0}, true, rng, provider);
     392         [ +  - ]:        1165 :     auto t2 = MakeV2Transport(NodeId{1}, false, rng, provider);
     393   [ +  +  +  + ]:        1165 :     if (!t1 || !t2) return;
     394         [ +  - ]:        1066 :     SimulationTest(*t1, *t2, rng, provider);
     395         [ -  + ]:        1165 : }
     396                 :             : 
     397         [ +  - ]:         675 : FUZZ_TARGET(p2p_transport_bidirectional_v1v2, .init = initialize_p2p_transport_serialization)
     398                 :             : {
     399                 :             :     // Test with a V1 initiator talking to a V2 responder.
     400                 :         673 :     FuzzedDataProvider provider{buffer.data(), buffer.size()};
     401                 :         673 :     InsecureRandomContext rng(provider.ConsumeIntegral<uint64_t>());
     402                 :         673 :     auto t1 = MakeV1Transport(NodeId{0});
     403         [ +  - ]:         673 :     auto t2 = MakeV2Transport(NodeId{1}, false, rng, provider);
     404   [ +  -  +  + ]:         673 :     if (!t1 || !t2) return;
     405         [ +  - ]:         659 :     SimulationTest(*t1, *t2, rng, provider);
     406         [ -  + ]:         673 : }
        

Generated by: LCOV version 2.0-1