mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-28 12:07:32 -03:00
fae216a73d
-BEGIN VERIFY SCRIPT- # Rename sed -i -e 's/MakeFuzzingContext/MakeNoLogFileContext/g' $(git grep -l MakeFuzzingContext) # Bump the copyright of touched files in this scripted diff to avoid touching them again later ./contrib/devtools/copyright_header.py update ./src/test/fuzz/ -END VERIFY SCRIPT-
300 lines
10 KiB
C++
300 lines
10 KiB
C++
// Copyright (c) 2009-2021 The Bitcoin Core developers
|
|
// Distributed under the MIT software license, see the accompanying
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
#include <addrdb.h>
|
|
#include <addrman.h>
|
|
#include <blockencodings.h>
|
|
#include <blockfilter.h>
|
|
#include <chain.h>
|
|
#include <coins.h>
|
|
#include <compressor.h>
|
|
#include <consensus/merkle.h>
|
|
#include <key.h>
|
|
#include <merkleblock.h>
|
|
#include <net.h>
|
|
#include <netbase.h>
|
|
#include <node/utxo_snapshot.h>
|
|
#include <optional.h>
|
|
#include <primitives/block.h>
|
|
#include <protocol.h>
|
|
#include <psbt.h>
|
|
#include <pubkey.h>
|
|
#include <script/keyorigin.h>
|
|
#include <streams.h>
|
|
#include <undo.h>
|
|
#include <version.h>
|
|
|
|
#include <exception>
|
|
#include <stdexcept>
|
|
#include <stdint.h>
|
|
#include <unistd.h>
|
|
|
|
#include <test/fuzz/fuzz.h>
|
|
|
|
void initialize_deserialize()
|
|
{
|
|
// Fuzzers using pubkey must hold an ECCVerifyHandle.
|
|
static const ECCVerifyHandle verify_handle;
|
|
}
|
|
|
|
#define FUZZ_TARGET_DESERIALIZE(name, code) \
|
|
FUZZ_TARGET_INIT(name, initialize_deserialize) \
|
|
{ \
|
|
try { \
|
|
code \
|
|
} catch (const invalid_fuzzing_input_exception&) { \
|
|
} \
|
|
}
|
|
|
|
namespace {
|
|
|
|
struct invalid_fuzzing_input_exception : public std::exception {
|
|
};
|
|
|
|
template <typename T>
|
|
CDataStream Serialize(const T& obj, const int version = INIT_PROTO_VERSION)
|
|
{
|
|
CDataStream ds(SER_NETWORK, version);
|
|
ds << obj;
|
|
return ds;
|
|
}
|
|
|
|
template <typename T>
|
|
T Deserialize(CDataStream ds)
|
|
{
|
|
T obj;
|
|
ds >> obj;
|
|
return obj;
|
|
}
|
|
|
|
template <typename T>
|
|
void DeserializeFromFuzzingInput(FuzzBufferType buffer, T& obj, const Optional<int> protocol_version = nullopt)
|
|
{
|
|
CDataStream ds(buffer, SER_NETWORK, INIT_PROTO_VERSION);
|
|
if (protocol_version) {
|
|
ds.SetVersion(*protocol_version);
|
|
} else {
|
|
try {
|
|
int version;
|
|
ds >> version;
|
|
ds.SetVersion(version);
|
|
} catch (const std::ios_base::failure&) {
|
|
throw invalid_fuzzing_input_exception();
|
|
}
|
|
}
|
|
try {
|
|
ds >> obj;
|
|
} catch (const std::ios_base::failure&) {
|
|
throw invalid_fuzzing_input_exception();
|
|
}
|
|
assert(buffer.empty() || !Serialize(obj).empty());
|
|
}
|
|
|
|
template <typename T>
|
|
void AssertEqualAfterSerializeDeserialize(const T& obj, const int version = INIT_PROTO_VERSION)
|
|
{
|
|
assert(Deserialize<T>(Serialize(obj, version)) == obj);
|
|
}
|
|
|
|
} // namespace
|
|
|
|
FUZZ_TARGET_DESERIALIZE(block_filter_deserialize, {
|
|
BlockFilter block_filter;
|
|
DeserializeFromFuzzingInput(buffer, block_filter);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(addr_info_deserialize, {
|
|
CAddrInfo addr_info;
|
|
DeserializeFromFuzzingInput(buffer, addr_info);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(block_file_info_deserialize, {
|
|
CBlockFileInfo block_file_info;
|
|
DeserializeFromFuzzingInput(buffer, block_file_info);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(block_header_and_short_txids_deserialize, {
|
|
CBlockHeaderAndShortTxIDs block_header_and_short_txids;
|
|
DeserializeFromFuzzingInput(buffer, block_header_and_short_txids);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(fee_rate_deserialize, {
|
|
CFeeRate fee_rate;
|
|
DeserializeFromFuzzingInput(buffer, fee_rate);
|
|
AssertEqualAfterSerializeDeserialize(fee_rate);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(merkle_block_deserialize, {
|
|
CMerkleBlock merkle_block;
|
|
DeserializeFromFuzzingInput(buffer, merkle_block);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(out_point_deserialize, {
|
|
COutPoint out_point;
|
|
DeserializeFromFuzzingInput(buffer, out_point);
|
|
AssertEqualAfterSerializeDeserialize(out_point);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(partial_merkle_tree_deserialize, {
|
|
CPartialMerkleTree partial_merkle_tree;
|
|
DeserializeFromFuzzingInput(buffer, partial_merkle_tree);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(pub_key_deserialize, {
|
|
CPubKey pub_key;
|
|
DeserializeFromFuzzingInput(buffer, pub_key);
|
|
// TODO: The following equivalence should hold for CPubKey? Fix.
|
|
// AssertEqualAfterSerializeDeserialize(pub_key);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(script_deserialize, {
|
|
CScript script;
|
|
DeserializeFromFuzzingInput(buffer, script);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(sub_net_deserialize, {
|
|
CSubNet sub_net_1;
|
|
DeserializeFromFuzzingInput(buffer, sub_net_1, INIT_PROTO_VERSION);
|
|
AssertEqualAfterSerializeDeserialize(sub_net_1, INIT_PROTO_VERSION);
|
|
CSubNet sub_net_2;
|
|
DeserializeFromFuzzingInput(buffer, sub_net_2, INIT_PROTO_VERSION | ADDRV2_FORMAT);
|
|
AssertEqualAfterSerializeDeserialize(sub_net_2, INIT_PROTO_VERSION | ADDRV2_FORMAT);
|
|
CSubNet sub_net_3;
|
|
DeserializeFromFuzzingInput(buffer, sub_net_3);
|
|
AssertEqualAfterSerializeDeserialize(sub_net_3, INIT_PROTO_VERSION | ADDRV2_FORMAT);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(tx_in_deserialize, {
|
|
CTxIn tx_in;
|
|
DeserializeFromFuzzingInput(buffer, tx_in);
|
|
AssertEqualAfterSerializeDeserialize(tx_in);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(flat_file_pos_deserialize, {
|
|
FlatFilePos flat_file_pos;
|
|
DeserializeFromFuzzingInput(buffer, flat_file_pos);
|
|
AssertEqualAfterSerializeDeserialize(flat_file_pos);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(key_origin_info_deserialize, {
|
|
KeyOriginInfo key_origin_info;
|
|
DeserializeFromFuzzingInput(buffer, key_origin_info);
|
|
AssertEqualAfterSerializeDeserialize(key_origin_info);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(partially_signed_transaction_deserialize, {
|
|
PartiallySignedTransaction partially_signed_transaction;
|
|
DeserializeFromFuzzingInput(buffer, partially_signed_transaction);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(prefilled_transaction_deserialize, {
|
|
PrefilledTransaction prefilled_transaction;
|
|
DeserializeFromFuzzingInput(buffer, prefilled_transaction);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(psbt_input_deserialize, {
|
|
PSBTInput psbt_input;
|
|
DeserializeFromFuzzingInput(buffer, psbt_input);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(psbt_output_deserialize, {
|
|
PSBTOutput psbt_output;
|
|
DeserializeFromFuzzingInput(buffer, psbt_output);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(block_deserialize, {
|
|
CBlock block;
|
|
DeserializeFromFuzzingInput(buffer, block);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(blocklocator_deserialize, {
|
|
CBlockLocator bl;
|
|
DeserializeFromFuzzingInput(buffer, bl);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(blockmerkleroot, {
|
|
CBlock block;
|
|
DeserializeFromFuzzingInput(buffer, block);
|
|
bool mutated;
|
|
BlockMerkleRoot(block, &mutated);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(addrman_deserialize, {
|
|
CAddrMan am;
|
|
DeserializeFromFuzzingInput(buffer, am);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(blockheader_deserialize, {
|
|
CBlockHeader bh;
|
|
DeserializeFromFuzzingInput(buffer, bh);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(banentry_deserialize, {
|
|
CBanEntry be;
|
|
DeserializeFromFuzzingInput(buffer, be);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(txundo_deserialize, {
|
|
CTxUndo tu;
|
|
DeserializeFromFuzzingInput(buffer, tu);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(blockundo_deserialize, {
|
|
CBlockUndo bu;
|
|
DeserializeFromFuzzingInput(buffer, bu);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(coins_deserialize, {
|
|
Coin coin;
|
|
DeserializeFromFuzzingInput(buffer, coin);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(netaddr_deserialize, {
|
|
CNetAddr na;
|
|
DeserializeFromFuzzingInput(buffer, na);
|
|
if (na.IsAddrV1Compatible()) {
|
|
AssertEqualAfterSerializeDeserialize(na);
|
|
}
|
|
AssertEqualAfterSerializeDeserialize(na, INIT_PROTO_VERSION | ADDRV2_FORMAT);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(service_deserialize, {
|
|
CService s;
|
|
DeserializeFromFuzzingInput(buffer, s);
|
|
if (s.IsAddrV1Compatible()) {
|
|
AssertEqualAfterSerializeDeserialize(s);
|
|
}
|
|
AssertEqualAfterSerializeDeserialize(s, INIT_PROTO_VERSION | ADDRV2_FORMAT);
|
|
CService s1;
|
|
DeserializeFromFuzzingInput(buffer, s1, INIT_PROTO_VERSION);
|
|
AssertEqualAfterSerializeDeserialize(s1, INIT_PROTO_VERSION);
|
|
assert(s1.IsAddrV1Compatible());
|
|
CService s2;
|
|
DeserializeFromFuzzingInput(buffer, s2, INIT_PROTO_VERSION | ADDRV2_FORMAT);
|
|
AssertEqualAfterSerializeDeserialize(s2, INIT_PROTO_VERSION | ADDRV2_FORMAT);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(messageheader_deserialize, {
|
|
CMessageHeader mh;
|
|
DeserializeFromFuzzingInput(buffer, mh);
|
|
(void)mh.IsCommandValid();
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(address_deserialize, {
|
|
CAddress a;
|
|
DeserializeFromFuzzingInput(buffer, a);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(inv_deserialize, {
|
|
CInv i;
|
|
DeserializeFromFuzzingInput(buffer, i);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(bloomfilter_deserialize, {
|
|
CBloomFilter bf;
|
|
DeserializeFromFuzzingInput(buffer, bf);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(diskblockindex_deserialize, {
|
|
CDiskBlockIndex dbi;
|
|
DeserializeFromFuzzingInput(buffer, dbi);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(txoutcompressor_deserialize, {
|
|
CTxOut to;
|
|
auto toc = Using<TxOutCompression>(to);
|
|
DeserializeFromFuzzingInput(buffer, toc);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(blocktransactions_deserialize, {
|
|
BlockTransactions bt;
|
|
DeserializeFromFuzzingInput(buffer, bt);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(blocktransactionsrequest_deserialize, {
|
|
BlockTransactionsRequest btr;
|
|
DeserializeFromFuzzingInput(buffer, btr);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(snapshotmetadata_deserialize, {
|
|
SnapshotMetadata snapshot_metadata;
|
|
DeserializeFromFuzzingInput(buffer, snapshot_metadata);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(uint160_deserialize, {
|
|
uint160 u160;
|
|
DeserializeFromFuzzingInput(buffer, u160);
|
|
AssertEqualAfterSerializeDeserialize(u160);
|
|
})
|
|
FUZZ_TARGET_DESERIALIZE(uint256_deserialize, {
|
|
uint256 u256;
|
|
DeserializeFromFuzzingInput(buffer, u256);
|
|
AssertEqualAfterSerializeDeserialize(u256);
|
|
})
|
|
// Classes intentionally not covered in this file since their deserialization code is
|
|
// fuzzed elsewhere:
|
|
// * Deserialization of CTxOut is fuzzed in test/fuzz/tx_out.cpp
|
|
// * Deserialization of CMutableTransaction is fuzzed in src/test/fuzz/transaction.cpp
|