Bitcoin Core  22.99.0
P2P Digital Currency
p2p_transport_serialization.cpp
Go to the documentation of this file.
1 // Copyright (c) 2019-2020 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>
11 #include <test/fuzz/fuzz.h>
12 
13 #include <cassert>
14 #include <cstdint>
15 #include <limits>
16 #include <optional>
17 #include <vector>
18 
20 {
22 }
23 
25 {
26  // Construct deserializer, with a dummy NodeId
28  V1TransportSerializer serializer{};
29  FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
30 
31  auto checksum_assist = fuzzed_data_provider.ConsumeBool();
32  auto magic_bytes_assist = fuzzed_data_provider.ConsumeBool();
33  std::vector<uint8_t> mutable_msg_bytes;
34 
35  auto header_bytes_remaining = CMessageHeader::HEADER_SIZE;
36  if (magic_bytes_assist) {
37  auto msg_start = Params().MessageStart();
38  for (size_t i = 0; i < CMessageHeader::MESSAGE_SIZE_SIZE; ++i) {
39  mutable_msg_bytes.push_back(msg_start[i]);
40  }
41  header_bytes_remaining -= CMessageHeader::MESSAGE_SIZE_SIZE;
42  }
43 
44  if (checksum_assist) {
45  header_bytes_remaining -= CMessageHeader::CHECKSUM_SIZE;
46  }
47 
48  auto header_random_bytes = fuzzed_data_provider.ConsumeBytes<uint8_t>(header_bytes_remaining);
49  mutable_msg_bytes.insert(mutable_msg_bytes.end(), header_random_bytes.begin(), header_random_bytes.end());
50  auto payload_bytes = fuzzed_data_provider.ConsumeRemainingBytes<uint8_t>();
51 
52  if (checksum_assist && mutable_msg_bytes.size() == CMessageHeader::CHECKSUM_OFFSET) {
53  CHash256 hasher;
54  unsigned char hsh[32];
55  hasher.Write(payload_bytes);
56  hasher.Finalize(hsh);
57  for (size_t i = 0; i < CMessageHeader::CHECKSUM_SIZE; ++i) {
58  mutable_msg_bytes.push_back(hsh[i]);
59  }
60  }
61 
62  mutable_msg_bytes.insert(mutable_msg_bytes.end(), payload_bytes.begin(), payload_bytes.end());
63  Span<const uint8_t> msg_bytes{mutable_msg_bytes};
64  while (msg_bytes.size() > 0) {
65  const int handled = deserializer.Read(msg_bytes);
66  if (handled < 0) {
67  break;
68  }
69  if (deserializer.Complete()) {
70  const std::chrono::microseconds m_time{std::numeric_limits<int64_t>::max()};
71  uint32_t out_err_raw_size{0};
72  std::optional<CNetMessage> result{deserializer.GetMessage(m_time, out_err_raw_size)};
73  if (result) {
74  assert(result->m_command.size() <= CMessageHeader::COMMAND_SIZE);
75  assert(result->m_raw_message_size <= mutable_msg_bytes.size());
76  assert(result->m_raw_message_size == CMessageHeader::HEADER_SIZE + result->m_message_size);
77  assert(result->m_time == m_time);
78 
79  std::vector<unsigned char> header;
80  auto msg = CNetMsgMaker{result->m_recv.GetVersion()}.Make(result->m_command, MakeUCharSpan(result->m_recv));
81  serializer.prepareForTransport(msg, header);
82  }
83  }
84  }
85 }
V1TransportSerializer
Definition: net.h:387
NodeId
int64_t NodeId
Definition: net.h:87
CMessageHeader::CHECKSUM_OFFSET
static constexpr size_t CHECKSUM_OFFSET
Definition: protocol.h:38
assert
assert(!tx.IsCoinBase())
CHash256::Write
CHash256 & Write(Span< const unsigned char > input)
Definition: hash.h:37
MakeUCharSpan
constexpr auto MakeUCharSpan(V &&v) -> decltype(UCharSpanCast(MakeSpan(std::forward< V >(v))))
Like MakeSpan, but for (const) unsigned char member types only.
Definition: span.h:249
CMessageHeader::MESSAGE_SIZE_SIZE
static constexpr size_t MESSAGE_SIZE_SIZE
Definition: protocol.h:35
chainparams.h
Span
A Span is an object that can refer to a contiguous sequence of objects.
Definition: span.h:92
CBaseChainParams::REGTEST
static const std::string REGTEST
Definition: chainparamsbase.h:25
FuzzedDataProvider.h
CMessageHeader::COMMAND_SIZE
static constexpr size_t COMMAND_SIZE
Definition: protocol.h:34
CHash256::Finalize
void Finalize(Span< unsigned char > output)
Definition: hash.h:30
SelectParams
void SelectParams(const std::string &network)
Sets the params returned by Params() to those for the given chain name.
Definition: chainparams.cpp:555
CNetMsgMaker
Definition: netmessagemaker.h:12
CChainParams::MessageStart
const CMessageHeader::MessageStartChars & MessageStart() const
Definition: chainparams.h:83
CMessageHeader::CHECKSUM_SIZE
static constexpr size_t CHECKSUM_SIZE
Definition: protocol.h:36
initialize_p2p_transport_serialization
void initialize_p2p_transport_serialization()
Definition: p2p_transport_serialization.cpp:19
netmessagemaker.h
FUZZ_TARGET_INIT
FUZZ_TARGET_INIT(p2p_transport_serialization, initialize_p2p_transport_serialization)
Definition: p2p_transport_serialization.cpp:24
fuzz.h
FuzzedDataProvider
Definition: FuzzedDataProvider.h:31
V1TransportDeserializer
Definition: net.h:315
Params
const CChainParams & Params()
Return the currently selected parameters.
Definition: chainparams.cpp:536
CMessageHeader::HEADER_SIZE
static constexpr size_t HEADER_SIZE
Definition: protocol.h:39
SER_NETWORK
@ SER_NETWORK
Definition: serialize.h:138
CHash256
A hasher class for Bitcoin's 256-bit hash (double SHA-256).
Definition: hash.h:24
CNetMsgMaker::Make
CSerializedNetMsg Make(int nFlags, std::string msg_type, Args &&... args) const
Definition: netmessagemaker.h:18
FuzzedDataProvider::ConsumeBool
bool ConsumeBool()
Definition: FuzzedDataProvider.h:288
INIT_PROTO_VERSION
static const int INIT_PROTO_VERSION
initial proto version, to be increased after version/verack negotiation
Definition: version.h:15