Bitcoin Core 22.99.0
P2P Digital Currency
deserialize.cpp
Go to the documentation of this file.
1// Copyright (c) 2009-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 <addrdb.h>
6#include <addrman.h>
7#include <addrman_impl.h>
8#include <blockencodings.h>
9#include <blockfilter.h>
10#include <chain.h>
11#include <coins.h>
12#include <compressor.h>
13#include <consensus/merkle.h>
14#include <key.h>
15#include <merkleblock.h>
16#include <net.h>
17#include <netbase.h>
18#include <node/utxo_snapshot.h>
19#include <primitives/block.h>
20#include <protocol.h>
21#include <psbt.h>
22#include <pubkey.h>
23#include <script/keyorigin.h>
24#include <streams.h>
25#include <undo.h>
26#include <version.h>
27
28#include <exception>
29#include <optional>
30#include <stdexcept>
31#include <stdint.h>
32#include <unistd.h>
33
34#include <test/fuzz/fuzz.h>
35
37{
38 // Fuzzers using pubkey must hold an ECCVerifyHandle.
39 static const ECCVerifyHandle verify_handle;
40}
41
42#define FUZZ_TARGET_DESERIALIZE(name, code) \
43 FUZZ_TARGET_INIT(name, initialize_deserialize) \
44 { \
45 try { \
46 code \
47 } catch (const invalid_fuzzing_input_exception&) { \
48 } \
49 }
50
51namespace {
52
53struct invalid_fuzzing_input_exception : public std::exception {
54};
55
56template <typename T>
57CDataStream Serialize(const T& obj, const int version = INIT_PROTO_VERSION, const int ser_type = SER_NETWORK)
58{
59 CDataStream ds(ser_type, version);
60 ds << obj;
61 return ds;
62}
63
64template <typename T>
65T Deserialize(CDataStream ds)
66{
67 T obj;
68 ds >> obj;
69 return obj;
70}
71
72template <typename T>
73void DeserializeFromFuzzingInput(FuzzBufferType buffer, T& obj, const std::optional<int> protocol_version = std::nullopt, const int ser_type = SER_NETWORK)
74{
75 CDataStream ds(buffer, ser_type, INIT_PROTO_VERSION);
76 if (protocol_version) {
77 ds.SetVersion(*protocol_version);
78 } else {
79 try {
80 int version;
81 ds >> version;
82 ds.SetVersion(version);
83 } catch (const std::ios_base::failure&) {
84 throw invalid_fuzzing_input_exception();
85 }
86 }
87 try {
88 ds >> obj;
89 } catch (const std::ios_base::failure&) {
90 throw invalid_fuzzing_input_exception();
91 }
92 assert(buffer.empty() || !Serialize(obj).empty());
93}
94
95template <typename T>
96void AssertEqualAfterSerializeDeserialize(const T& obj, const int version = INIT_PROTO_VERSION, const int ser_type = SER_NETWORK)
97{
98 assert(Deserialize<T>(Serialize(obj, version, ser_type)) == obj);
99}
100
101} // namespace
102
103FUZZ_TARGET_DESERIALIZE(block_filter_deserialize, {
104 BlockFilter block_filter;
105 DeserializeFromFuzzingInput(buffer, block_filter);
106})
107FUZZ_TARGET_DESERIALIZE(addr_info_deserialize, {
108 AddrInfo addr_info;
109 DeserializeFromFuzzingInput(buffer, addr_info);
110})
111FUZZ_TARGET_DESERIALIZE(block_file_info_deserialize, {
112 CBlockFileInfo block_file_info;
113 DeserializeFromFuzzingInput(buffer, block_file_info);
114})
115FUZZ_TARGET_DESERIALIZE(block_header_and_short_txids_deserialize, {
116 CBlockHeaderAndShortTxIDs block_header_and_short_txids;
117 DeserializeFromFuzzingInput(buffer, block_header_and_short_txids);
118})
119FUZZ_TARGET_DESERIALIZE(fee_rate_deserialize, {
120 CFeeRate fee_rate;
121 DeserializeFromFuzzingInput(buffer, fee_rate);
123})
124FUZZ_TARGET_DESERIALIZE(merkle_block_deserialize, {
125 CMerkleBlock merkle_block;
126 DeserializeFromFuzzingInput(buffer, merkle_block);
127})
128FUZZ_TARGET_DESERIALIZE(out_point_deserialize, {
129 COutPoint out_point;
130 DeserializeFromFuzzingInput(buffer, out_point);
132})
133FUZZ_TARGET_DESERIALIZE(partial_merkle_tree_deserialize, {
134 CPartialMerkleTree partial_merkle_tree;
135 DeserializeFromFuzzingInput(buffer, partial_merkle_tree);
136})
137FUZZ_TARGET_DESERIALIZE(pub_key_deserialize, {
138 CPubKey pub_key;
139 DeserializeFromFuzzingInput(buffer, pub_key);
141})
142FUZZ_TARGET_DESERIALIZE(script_deserialize, {
143 CScript script;
145})
146FUZZ_TARGET_DESERIALIZE(tx_in_deserialize, {
147 CTxIn tx_in;
148 DeserializeFromFuzzingInput(buffer, tx_in);
150})
151FUZZ_TARGET_DESERIALIZE(flat_file_pos_deserialize, {
152 FlatFilePos flat_file_pos;
153 DeserializeFromFuzzingInput(buffer, flat_file_pos);
155})
156FUZZ_TARGET_DESERIALIZE(key_origin_info_deserialize, {
157 KeyOriginInfo key_origin_info;
158 DeserializeFromFuzzingInput(buffer, key_origin_info);
160})
161FUZZ_TARGET_DESERIALIZE(partially_signed_transaction_deserialize, {
162 PartiallySignedTransaction partially_signed_transaction;
163 DeserializeFromFuzzingInput(buffer, partially_signed_transaction);
164})
165FUZZ_TARGET_DESERIALIZE(prefilled_transaction_deserialize, {
166 PrefilledTransaction prefilled_transaction;
167 DeserializeFromFuzzingInput(buffer, prefilled_transaction);
168})
169FUZZ_TARGET_DESERIALIZE(psbt_input_deserialize, {
170 PSBTInput psbt_input;
171 DeserializeFromFuzzingInput(buffer, psbt_input);
172})
173FUZZ_TARGET_DESERIALIZE(psbt_output_deserialize, {
174 PSBTOutput psbt_output;
175 DeserializeFromFuzzingInput(buffer, psbt_output);
176})
177FUZZ_TARGET_DESERIALIZE(block_deserialize, {
178 CBlock block;
180})
181FUZZ_TARGET_DESERIALIZE(blocklocator_deserialize, {
182 CBlockLocator bl;
183 DeserializeFromFuzzingInput(buffer, bl);
184})
185FUZZ_TARGET_DESERIALIZE(blockmerkleroot, {
186 CBlock block;
187 DeserializeFromFuzzingInput(buffer, block);
190})
191FUZZ_TARGET_DESERIALIZE(addrman_deserialize, {
192 AddrMan am(/* asmap */ std::vector<bool>(), /* deterministic */ false, /* consistency_check_ratio */ 0);
193 DeserializeFromFuzzingInput(buffer, am);
194})
195FUZZ_TARGET_DESERIALIZE(blockheader_deserialize, {
196 CBlockHeader bh;
198})
199FUZZ_TARGET_DESERIALIZE(txundo_deserialize, {
200 CTxUndo tu;
201 DeserializeFromFuzzingInput(buffer, tu);
202})
203FUZZ_TARGET_DESERIALIZE(blockundo_deserialize, {
204 CBlockUndo bu;
206})
207FUZZ_TARGET_DESERIALIZE(coins_deserialize, {
208 Coin coin;
209 DeserializeFromFuzzingInput(buffer, coin);
210})
211FUZZ_TARGET_DESERIALIZE(netaddr_deserialize, {
212 CNetAddr na;
216 }
218})
219FUZZ_TARGET_DESERIALIZE(service_deserialize, {
220 CService s;
222 if (s.IsAddrV1Compatible()) {
224 }
226 CService s1;
230 CService s2;
233})
234FUZZ_TARGET_DESERIALIZE(messageheader_deserialize, {
237 (void)mh.IsCommandValid();
238})
239FUZZ_TARGET_DESERIALIZE(address_deserialize_v1_notime, {
240 CAddress a;
242 // A CAddress without nTime (as is expected under INIT_PROTO_VERSION) will roundtrip
243 // in all 5 formats (with/without nTime, v1/v2, network/disk)
249})
250FUZZ_TARGET_DESERIALIZE(address_deserialize_v1_withtime, {
251 CAddress a;
253 // A CAddress in V1 mode will roundtrip in all 4 formats that have nTime.
258})
259FUZZ_TARGET_DESERIALIZE(address_deserialize_v2, {
260 CAddress a;
262 // A CAddress in V2 mode will roundtrip in both V2 formats, and also in the V1 formats
263 // with time if it's V1 compatible.
264 if (a.IsAddrV1Compatible()) {
267 }
270})
271FUZZ_TARGET_DESERIALIZE(inv_deserialize, {
272 CInv i;
274})
275FUZZ_TARGET_DESERIALIZE(bloomfilter_deserialize, {
276 CBloomFilter bf;
277 DeserializeFromFuzzingInput(buffer, bf);
278})
279FUZZ_TARGET_DESERIALIZE(diskblockindex_deserialize, {
280 CDiskBlockIndex dbi;
282})
283FUZZ_TARGET_DESERIALIZE(txoutcompressor_deserialize, {
284 CTxOut to;
285 auto toc = Using<TxOutCompression>(to);
286 DeserializeFromFuzzingInput(buffer, toc);
287})
288FUZZ_TARGET_DESERIALIZE(blocktransactions_deserialize, {
291})
292FUZZ_TARGET_DESERIALIZE(blocktransactionsrequest_deserialize, {
294 DeserializeFromFuzzingInput(buffer, btr);
295})
296FUZZ_TARGET_DESERIALIZE(snapshotmetadata_deserialize, {
297 SnapshotMetadata snapshot_metadata;
298 DeserializeFromFuzzingInput(buffer, snapshot_metadata);
299})
300FUZZ_TARGET_DESERIALIZE(uint160_deserialize, {
301 uint160 u160;
302 DeserializeFromFuzzingInput(buffer, u160);
304})
305FUZZ_TARGET_DESERIALIZE(uint256_deserialize, {
306 uint256 u256;
309})
310// Classes intentionally not covered in this file since their deserialization code is
311// fuzzed elsewhere:
312// * Deserialization of CTxOut is fuzzed in test/fuzz/tx_out.cpp
313// * Deserialization of CMutableTransaction is fuzzed in src/test/fuzz/transaction.cpp
Extended statistics about a CAddress.
Definition: addrman_impl.h:37
Stochastic address manager.
Definition: addrman.h:55
Complete block filter struct as defined in BIP 157.
Definition: blockfilter.h:111
A CService with information about it as peer.
Definition: protocol.h:359
Nodes collect new transactions into a block, hash them into a hash tree, and scan through nonce value...
Definition: block.h:21
Definition: block.h:63
Undo information for a CBlock.
Definition: undo.h:64
BloomFilter is a probabilistic filter which SPV clients provide so that we can filter the transaction...
Definition: bloom.h:45
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:205
void SetVersion(int n)
Definition: streams.h:362
Used to marshal pointers into hashes for db storage.
Definition: chain.h:352
Fee rate in satoshis per kilobyte: CAmount / kB.
Definition: feerate.h:30
inv message data
Definition: protocol.h:477
Used to relay blocks as header + vector<merkle branch> to filtered nodes.
Definition: merkleblock.h:125
Message header.
Definition: protocol.h:31
bool IsCommandValid() const
Definition: protocol.cpp:107
Network address.
Definition: netaddress.h:119
bool IsAddrV1Compatible() const
Check if the current object can be serialized in pre-ADDRv2/BIP155 format.
Definition: netaddress.cpp:505
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:27
Data structure that represents a partial merkle tree.
Definition: merkleblock.h:55
An encapsulated public key.
Definition: pubkey.h:33
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:406
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:523
An input of a transaction.
Definition: transaction.h:66
An output of a transaction.
Definition: transaction.h:129
Undo information for a CTransaction.
Definition: undo.h:54
A UTXO entry.
Definition: coins.h:31
Users of this module must hold an ECCVerifyHandle.
Definition: pubkey.h:316
Metadata describing a serialized version of a UTXO set from which an assumeutxo CChainState can be co...
Definition: utxo_snapshot.h:15
A Span is an object that can refer to a contiguous sequence of objects.
Definition: span.h:93
constexpr bool empty() const noexcept
Definition: span.h:183
160-bit opaque blob.
Definition: uint256.h:113
256-bit opaque blob.
Definition: uint256.h:124
AssertEqualAfterSerializeDeserialize(flat_file_pos)
BlockMerkleRoot(block, &mutated)
bool mutated
DeserializeFromFuzzingInput(buffer, addr_info)
#define FUZZ_TARGET_DESERIALIZE(name, code)
Definition: deserialize.cpp:42
void initialize_deserialize()
Definition: deserialize.cpp:36
#define T(expected, seed, data)
static constexpr int ADDRV2_FORMAT
A flag that is ORed into the protocol version to designate that addresses should be serialized in (un...
Definition: netaddress.h:34
@ SER_DISK
Definition: serialize.h:139
@ SER_NETWORK
Definition: serialize.h:138
void Serialize(Stream &s, char a)
Definition: serialize.h:199
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
Definition: block.h:115
A structure for PSBTs which contain per-input information.
Definition: psbt.h:50
A structure for PSBTs which contains per output information.
Definition: psbt.h:277
A version of CTransaction with the PSBT format.
Definition: psbt.h:392
assert(!tx.IsCoinBase())
static const int INIT_PROTO_VERSION
initial proto version, to be increased after version/verack negotiation
Definition: version.h:15
static const int PROTOCOL_VERSION
network protocol versioning
Definition: version.h:12