Bitcoin Core  22.99.0
P2P Digital Currency
p2p_transport_serialization.cpp
Go to the documentation of this file.
1 // Copyright (c) 2019-2021 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  bool reject_message{false};
72  CNetMessage msg = deserializer.GetMessage(m_time, reject_message);
74  assert(msg.m_raw_message_size <= mutable_msg_bytes.size());
76  assert(msg.m_time == m_time);
77 
78  std::vector<unsigned char> header;
79  auto msg2 = CNetMsgMaker{msg.m_recv.GetVersion()}.Make(msg.m_type, MakeUCharSpan(msg.m_recv));
80  serializer.prepareForTransport(msg2, header);
81  }
82  }
83 }
V1TransportSerializer
Definition: net.h:388
NodeId
int64_t NodeId
Definition: net.h:88
CMessageHeader::CHECKSUM_OFFSET
static constexpr size_t CHECKSUM_OFFSET
Definition: protocol.h:38
MakeUCharSpan
constexpr auto MakeUCharSpan(V &&v) -> decltype(UCharSpanCast(Span
Like the Span constructor, but for (const) unsigned char member types only.
Definition: span.h:285
assert
assert(!tx.IsCoinBase())
CHash256::Write
CHash256 & Write(Span< const unsigned char > input)
Definition: hash.h:37
CMessageHeader::MESSAGE_SIZE_SIZE
static constexpr size_t MESSAGE_SIZE_SIZE
Definition: protocol.h:35
chainparams.h
CNetMessage::m_type
std::string m_type
Definition: net.h:289
Span
A Span is an object that can refer to a contiguous sequence of objects.
Definition: span.h:96
CBaseChainParams::REGTEST
static const std::string REGTEST
Definition: chainparamsbase.h:25
CNetMessage::m_time
std::chrono::microseconds m_time
time of message receipt
Definition: net.h:286
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:580
CNetMsgMaker
Definition: netmessagemaker.h:12
CNetMessage::m_recv
CDataStream m_recv
received message data
Definition: net.h:285
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
CDataStream::GetVersion
int GetVersion() const
Definition: streams.h:277
netmessagemaker.h
CNetMessage::m_message_size
uint32_t m_message_size
size of the payload
Definition: net.h:287
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:316
CNetMessage
Transport protocol agnostic message container.
Definition: net.h:283
Params
const CChainParams & Params()
Return the currently selected parameters.
Definition: chainparams.cpp:561
CMessageHeader::HEADER_SIZE
static constexpr size_t HEADER_SIZE
Definition: protocol.h:39
SER_NETWORK
@ SER_NETWORK
Definition: serialize.h:131
CHash256
A hasher class for Bitcoin's 256-bit hash (double SHA-256).
Definition: hash.h:24
FuzzedDataProvider::ConsumeBool
bool ConsumeBool()
Definition: FuzzedDataProvider.h:288
CNetMessage::m_raw_message_size
uint32_t m_raw_message_size
used wire size of the message (including header/checksum)
Definition: net.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