aboutsummaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorMarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz>2023-01-31 18:04:44 +0100
committerMarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz>2023-09-05 10:13:25 +0200
commitfac81affb527132945773a5315bd27fec61ec52f (patch)
tree90aa401bd50bf12519a45737f335856256ff614e /src/test
parentfaec591d64e40ba7ec7656cbfdda1a05953bde13 (diff)
Use serialization parameters for CAddress serialization
This also cleans up the addrman (de)serialization code paths to only allow `Disk` serialization. Some unit tests previously forced a `Network` serialization, which does not make sense, because Bitcoin Core in production will always `Disk` serialize. This cleanup idea was suggested by Pieter Wuille and implemented by Anthony Towns. Co-authored-by: Pieter Wuille <pieter@wuille.net> Co-authored-by: Anthony Towns <aj@erisian.com.au>
Diffstat (limited to 'src/test')
-rw-r--r--src/test/addrman_tests.cpp22
-rw-r--r--src/test/fuzz/addrman.cpp16
-rw-r--r--src/test/fuzz/deserialize.cpp151
-rw-r--r--src/test/fuzz/net.cpp2
-rw-r--r--src/test/fuzz/script_sign.cpp3
-rw-r--r--src/test/fuzz/util.h21
-rw-r--r--src/test/fuzz/util/net.cpp21
-rw-r--r--src/test/net_tests.cpp81
-rw-r--r--src/test/netbase_tests.cpp16
-rw-r--r--src/test/util/net.cpp4
10 files changed, 197 insertions, 140 deletions
diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp
index 329b89554d..941018a820 100644
--- a/src/test/addrman_tests.cpp
+++ b/src/test/addrman_tests.cpp
@@ -697,7 +697,7 @@ BOOST_AUTO_TEST_CASE(addrman_serialization)
auto addrman_asmap1_dup = std::make_unique<AddrMan>(netgroupman, DETERMINISTIC, ratio);
auto addrman_noasmap = std::make_unique<AddrMan>(EMPTY_NETGROUPMAN, DETERMINISTIC, ratio);
- CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
+ DataStream stream{};
CAddress addr = CAddress(ResolveService("250.1.1.1"), NODE_NONE);
CNetAddr default_source;
@@ -757,7 +757,7 @@ BOOST_AUTO_TEST_CASE(remove_invalid)
// Confirm that invalid addresses are ignored in unserialization.
auto addrman = std::make_unique<AddrMan>(EMPTY_NETGROUPMAN, DETERMINISTIC, GetCheckRatio(m_node));
- CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
+ DataStream stream{};
const CAddress new1{ResolveService("5.5.5.5"), NODE_NONE};
const CAddress new2{ResolveService("6.6.6.6"), NODE_NONE};
@@ -940,9 +940,9 @@ BOOST_AUTO_TEST_CASE(addrman_evictionworks)
BOOST_CHECK(!addr_pos36.tried);
}
-static CDataStream AddrmanToStream(const AddrMan& addrman)
+static auto AddrmanToStream(const AddrMan& addrman)
{
- CDataStream ssPeersIn(SER_DISK, CLIENT_VERSION);
+ DataStream ssPeersIn{};
ssPeersIn << Params().MessageStart();
ssPeersIn << addrman;
return ssPeersIn;
@@ -972,7 +972,7 @@ BOOST_AUTO_TEST_CASE(load_addrman)
BOOST_CHECK(addrman.Size() == 3);
// Test that the de-serialization does not throw an exception.
- CDataStream ssPeers1 = AddrmanToStream(addrman);
+ auto ssPeers1{AddrmanToStream(addrman)};
bool exceptionThrown = false;
AddrMan addrman1{EMPTY_NETGROUPMAN, !DETERMINISTIC, GetCheckRatio(m_node)};
@@ -989,7 +989,7 @@ BOOST_AUTO_TEST_CASE(load_addrman)
BOOST_CHECK(exceptionThrown == false);
// Test that ReadFromStream creates an addrman with the correct number of addrs.
- CDataStream ssPeers2 = AddrmanToStream(addrman);
+ DataStream ssPeers2 = AddrmanToStream(addrman);
AddrMan addrman2{EMPTY_NETGROUPMAN, !DETERMINISTIC, GetCheckRatio(m_node)};
BOOST_CHECK(addrman2.Size() == 0);
@@ -998,9 +998,9 @@ BOOST_AUTO_TEST_CASE(load_addrman)
}
// Produce a corrupt peers.dat that claims 20 addrs when it only has one addr.
-static CDataStream MakeCorruptPeersDat()
+static auto MakeCorruptPeersDat()
{
- CDataStream s(SER_DISK, CLIENT_VERSION);
+ DataStream s{};
s << ::Params().MessageStart();
unsigned char nVersion = 1;
@@ -1019,7 +1019,7 @@ static CDataStream MakeCorruptPeersDat()
std::optional<CNetAddr> resolved{LookupHost("252.2.2.2", false)};
BOOST_REQUIRE(resolved.has_value());
AddrInfo info = AddrInfo(addr, resolved.value());
- s << info;
+ s << WithParams(CAddress::V1_DISK, info);
return s;
}
@@ -1027,7 +1027,7 @@ static CDataStream MakeCorruptPeersDat()
BOOST_AUTO_TEST_CASE(load_addrman_corrupted)
{
// Test that the de-serialization of corrupted peers.dat throws an exception.
- CDataStream ssPeers1 = MakeCorruptPeersDat();
+ auto ssPeers1{MakeCorruptPeersDat()};
bool exceptionThrown = false;
AddrMan addrman1{EMPTY_NETGROUPMAN, !DETERMINISTIC, GetCheckRatio(m_node)};
BOOST_CHECK(addrman1.Size() == 0);
@@ -1041,7 +1041,7 @@ BOOST_AUTO_TEST_CASE(load_addrman_corrupted)
BOOST_CHECK(exceptionThrown);
// Test that ReadFromStream fails if peers.dat is corrupt
- CDataStream ssPeers2 = MakeCorruptPeersDat();
+ auto ssPeers2{MakeCorruptPeersDat()};
AddrMan addrman2{EMPTY_NETGROUPMAN, !DETERMINISTIC, GetCheckRatio(m_node)};
BOOST_CHECK(addrman2.Size() == 0);
diff --git a/src/test/fuzz/addrman.cpp b/src/test/fuzz/addrman.cpp
index 02df4590de..9611a872ec 100644
--- a/src/test/fuzz/addrman.cpp
+++ b/src/test/fuzz/addrman.cpp
@@ -49,7 +49,7 @@ void initialize_addrman()
FUZZ_TARGET(data_stream_addr_man, .init = initialize_addrman)
{
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
- CDataStream data_stream = ConsumeDataStream(fuzzed_data_provider);
+ DataStream data_stream = ConsumeDataStream(fuzzed_data_provider);
NetGroupManager netgroupman{ConsumeNetGroupManager(fuzzed_data_provider)};
AddrMan addr_man(netgroupman, /*deterministic=*/false, GetCheckRatio());
try {
@@ -78,12 +78,12 @@ CNetAddr RandAddr(FuzzedDataProvider& fuzzed_data_provider, FastRandomContext& f
net = 6;
}
- CDataStream s(SER_NETWORK, PROTOCOL_VERSION | ADDRV2_FORMAT);
+ DataStream s{};
s << net;
s << fast_random_context.randbytes(net_len_map.at(net));
- s >> addr;
+ s >> WithParams(CAddress::V2_NETWORK, addr);
}
// Return a dummy IPv4 5.5.5.5 if we generated an invalid address.
@@ -241,9 +241,7 @@ FUZZ_TARGET(addrman, .init = initialize_addrman)
auto addr_man_ptr = std::make_unique<AddrManDeterministic>(netgroupman, fuzzed_data_provider);
if (fuzzed_data_provider.ConsumeBool()) {
const std::vector<uint8_t> serialized_data{ConsumeRandomLengthByteVector(fuzzed_data_provider)};
- CDataStream ds(serialized_data, SER_DISK, INIT_PROTO_VERSION);
- const auto ser_version{fuzzed_data_provider.ConsumeIntegral<int32_t>()};
- ds.SetVersion(ser_version);
+ DataStream ds{serialized_data};
try {
ds >> *addr_man_ptr;
} catch (const std::ios_base::failure&) {
@@ -295,7 +293,7 @@ FUZZ_TARGET(addrman, .init = initialize_addrman)
in_new = fuzzed_data_provider.ConsumeBool();
}
(void)const_addr_man.Size(network, in_new);
- CDataStream data_stream(SER_NETWORK, PROTOCOL_VERSION);
+ DataStream data_stream{};
data_stream << const_addr_man;
}
@@ -309,10 +307,10 @@ FUZZ_TARGET(addrman_serdeser, .init = initialize_addrman)
AddrManDeterministic addr_man1{netgroupman, fuzzed_data_provider};
AddrManDeterministic addr_man2{netgroupman, fuzzed_data_provider};
- CDataStream data_stream(SER_NETWORK, PROTOCOL_VERSION);
+ DataStream data_stream{};
FillAddrman(addr_man1, fuzzed_data_provider);
data_stream << addr_man1;
data_stream >> addr_man2;
assert(addr_man1 == addr_man2);
-} \ No newline at end of file
+}
diff --git a/src/test/fuzz/deserialize.cpp b/src/test/fuzz/deserialize.cpp
index 09402233bd..100a6b4ee4 100644
--- a/src/test/fuzz/deserialize.cpp
+++ b/src/test/fuzz/deserialize.cpp
@@ -24,6 +24,8 @@
#include <pubkey.h>
#include <script/keyorigin.h>
#include <streams.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
#include <test/util/setup_common.h>
#include <undo.h>
#include <version.h>
@@ -34,8 +36,6 @@
#include <stdint.h>
#include <unistd.h>
-#include <test/fuzz/fuzz.h>
-
using node::SnapshotMetadata;
namespace {
@@ -62,6 +62,34 @@ namespace {
struct invalid_fuzzing_input_exception : public std::exception {
};
+template <typename T, typename P>
+DataStream Serialize(const T& obj, const P& params)
+{
+ DataStream ds{};
+ ds << WithParams(params, obj);
+ return ds;
+}
+
+template <typename T, typename P>
+T Deserialize(DataStream&& ds, const P& params)
+{
+ T obj;
+ ds >> WithParams(params, obj);
+ return obj;
+}
+
+template <typename T, typename P>
+void DeserializeFromFuzzingInput(FuzzBufferType buffer, T&& obj, const P& params)
+{
+ DataStream ds{buffer};
+ try {
+ ds >> WithParams(params, obj);
+ } catch (const std::ios_base::failure&) {
+ throw invalid_fuzzing_input_exception();
+ }
+ assert(buffer.empty() || !Serialize(obj, params).empty());
+}
+
template <typename T>
CDataStream Serialize(const T& obj, const int version = INIT_PROTO_VERSION, const int ser_type = SER_NETWORK)
{
@@ -79,7 +107,7 @@ T Deserialize(CDataStream ds)
}
template <typename T>
-void DeserializeFromFuzzingInput(FuzzBufferType buffer, T& obj, const std::optional<int> protocol_version = std::nullopt, const int ser_type = SER_NETWORK)
+void DeserializeFromFuzzingInput(FuzzBufferType buffer, T&& obj, const std::optional<int> protocol_version = std::nullopt, const int ser_type = SER_NETWORK)
{
CDataStream ds(buffer, ser_type, INIT_PROTO_VERSION);
if (protocol_version) {
@@ -101,6 +129,11 @@ void DeserializeFromFuzzingInput(FuzzBufferType buffer, T& obj, const std::optio
assert(buffer.empty() || !Serialize(obj).empty());
}
+template <typename T, typename P>
+void AssertEqualAfterSerializeDeserialize(const T& obj, const P& params)
+{
+ assert(Deserialize<T>(Serialize(obj, params), params) == obj);
+}
template <typename T>
void AssertEqualAfterSerializeDeserialize(const T& obj, const int version = INIT_PROTO_VERSION, const int ser_type = SER_NETWORK)
{
@@ -113,10 +146,11 @@ FUZZ_TARGET_DESERIALIZE(block_filter_deserialize, {
BlockFilter block_filter;
DeserializeFromFuzzingInput(buffer, block_filter);
})
-FUZZ_TARGET_DESERIALIZE(addr_info_deserialize, {
- AddrInfo addr_info;
- DeserializeFromFuzzingInput(buffer, addr_info);
-})
+FUZZ_TARGET(addr_info_deserialize, .init = initialize_deserialize)
+{
+ FuzzedDataProvider fdp{buffer.data(), buffer.size()};
+ (void)ConsumeDeserializable<AddrInfo>(fdp, ConsumeDeserializationParams<CAddress::SerParams>(fdp));
+}
FUZZ_TARGET_DESERIALIZE(block_file_info_deserialize, {
CBlockFileInfo block_file_info;
DeserializeFromFuzzingInput(buffer, block_file_info);
@@ -197,13 +231,6 @@ FUZZ_TARGET_DESERIALIZE(blockmerkleroot, {
bool mutated;
BlockMerkleRoot(block, &mutated);
})
-FUZZ_TARGET_DESERIALIZE(addrman_deserialize, {
- NetGroupManager netgroupman{std::vector<bool>()};
- AddrMan am(netgroupman,
- /*deterministic=*/false,
- g_setup->m_node.args->GetIntArg("-checkaddrman", 0));
- DeserializeFromFuzzingInput(buffer, am);
-})
FUZZ_TARGET_DESERIALIZE(blockheader_deserialize, {
CBlockHeader bh;
DeserializeFromFuzzingInput(buffer, bh);
@@ -220,66 +247,62 @@ FUZZ_TARGET_DESERIALIZE(coins_deserialize, {
Coin coin;
DeserializeFromFuzzingInput(buffer, coin);
})
-FUZZ_TARGET_DESERIALIZE(netaddr_deserialize, {
- CNetAddr na;
- DeserializeFromFuzzingInput(buffer, na);
+FUZZ_TARGET(netaddr_deserialize, .init = initialize_deserialize)
+{
+ FuzzedDataProvider fdp{buffer.data(), buffer.size()};
+ const auto maybe_na{ConsumeDeserializable<CNetAddr>(fdp, ConsumeDeserializationParams<CNetAddr::SerParams>(fdp))};
+ if (!maybe_na) return;
+ const CNetAddr& na{*maybe_na};
if (na.IsAddrV1Compatible()) {
- AssertEqualAfterSerializeDeserialize(na);
+ AssertEqualAfterSerializeDeserialize(na, ConsumeDeserializationParams<CNetAddr::SerParams>(fdp));
}
- AssertEqualAfterSerializeDeserialize(na, INIT_PROTO_VERSION | ADDRV2_FORMAT);
-})
-FUZZ_TARGET_DESERIALIZE(service_deserialize, {
- CService s;
- DeserializeFromFuzzingInput(buffer, s);
+ AssertEqualAfterSerializeDeserialize(na, CNetAddr::V2);
+}
+FUZZ_TARGET(service_deserialize, .init = initialize_deserialize)
+{
+ FuzzedDataProvider fdp{buffer.data(), buffer.size()};
+ const auto ser_params{ConsumeDeserializationParams<CNetAddr::SerParams>(fdp)};
+ const auto maybe_s{ConsumeDeserializable<CService>(fdp, ser_params)};
+ if (!maybe_s) return;
+ const CService& s{*maybe_s};
if (s.IsAddrV1Compatible()) {
- AssertEqualAfterSerializeDeserialize(s);
+ AssertEqualAfterSerializeDeserialize(s, ConsumeDeserializationParams<CNetAddr::SerParams>(fdp));
}
- 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);
-})
+ AssertEqualAfterSerializeDeserialize(s, CNetAddr::V2);
+ if (ser_params.enc == CNetAddr::Encoding::V1) {
+ assert(s.IsAddrV1Compatible());
+ }
+}
FUZZ_TARGET_DESERIALIZE(messageheader_deserialize, {
CMessageHeader mh;
DeserializeFromFuzzingInput(buffer, mh);
(void)mh.IsCommandValid();
})
-FUZZ_TARGET_DESERIALIZE(address_deserialize_v1_notime, {
- CAddress a;
- DeserializeFromFuzzingInput(buffer, a, INIT_PROTO_VERSION);
- // A CAddress without nTime (as is expected under INIT_PROTO_VERSION) will roundtrip
- // in all 5 formats (with/without nTime, v1/v2, network/disk)
- AssertEqualAfterSerializeDeserialize(a, INIT_PROTO_VERSION);
- AssertEqualAfterSerializeDeserialize(a, PROTOCOL_VERSION);
- AssertEqualAfterSerializeDeserialize(a, 0, SER_DISK);
- AssertEqualAfterSerializeDeserialize(a, PROTOCOL_VERSION | ADDRV2_FORMAT);
- AssertEqualAfterSerializeDeserialize(a, ADDRV2_FORMAT, SER_DISK);
-})
-FUZZ_TARGET_DESERIALIZE(address_deserialize_v1_withtime, {
- CAddress a;
- DeserializeFromFuzzingInput(buffer, a, PROTOCOL_VERSION);
- // A CAddress in V1 mode will roundtrip in all 4 formats that have nTime.
- AssertEqualAfterSerializeDeserialize(a, PROTOCOL_VERSION);
- AssertEqualAfterSerializeDeserialize(a, 0, SER_DISK);
- AssertEqualAfterSerializeDeserialize(a, PROTOCOL_VERSION | ADDRV2_FORMAT);
- AssertEqualAfterSerializeDeserialize(a, ADDRV2_FORMAT, SER_DISK);
-})
-FUZZ_TARGET_DESERIALIZE(address_deserialize_v2, {
- CAddress a;
- DeserializeFromFuzzingInput(buffer, a, PROTOCOL_VERSION | ADDRV2_FORMAT);
- // A CAddress in V2 mode will roundtrip in both V2 formats, and also in the V1 formats
- // with time if it's V1 compatible.
- if (a.IsAddrV1Compatible()) {
- AssertEqualAfterSerializeDeserialize(a, PROTOCOL_VERSION);
- AssertEqualAfterSerializeDeserialize(a, 0, SER_DISK);
+FUZZ_TARGET(address_deserialize, .init = initialize_deserialize)
+{
+ FuzzedDataProvider fdp{buffer.data(), buffer.size()};
+ const auto ser_enc{ConsumeDeserializationParams<CNetAddr::SerParams>(fdp)};
+ const auto maybe_a{ConsumeDeserializable<CAddress>(fdp, CAddress::SerParams{{ser_enc}, CAddress::Format::Network})};
+ if (!maybe_a) return;
+ const CAddress& a{*maybe_a};
+ // A CAddress in V1 mode will roundtrip
+ // in all 4 formats (v1/v2, network/disk)
+ if (ser_enc.enc == CNetAddr::Encoding::V1) {
+ AssertEqualAfterSerializeDeserialize(a, CAddress::V1_NETWORK);
+ AssertEqualAfterSerializeDeserialize(a, CAddress::V1_DISK);
+ AssertEqualAfterSerializeDeserialize(a, CAddress::V2_NETWORK);
+ AssertEqualAfterSerializeDeserialize(a, CAddress::V2_DISK);
+ } else {
+ // A CAddress in V2 mode will roundtrip in both V2 formats, and also in the V1 formats
+ // if it's V1 compatible.
+ if (a.IsAddrV1Compatible()) {
+ AssertEqualAfterSerializeDeserialize(a, CAddress::V1_DISK);
+ AssertEqualAfterSerializeDeserialize(a, CAddress::V1_NETWORK);
+ }
+ AssertEqualAfterSerializeDeserialize(a, CAddress::V2_NETWORK);
+ AssertEqualAfterSerializeDeserialize(a, CAddress::V2_DISK);
}
- AssertEqualAfterSerializeDeserialize(a, PROTOCOL_VERSION | ADDRV2_FORMAT);
- AssertEqualAfterSerializeDeserialize(a, ADDRV2_FORMAT, SER_DISK);
-})
+}
FUZZ_TARGET_DESERIALIZE(inv_deserialize, {
CInv i;
DeserializeFromFuzzingInput(buffer, i);
diff --git a/src/test/fuzz/net.cpp b/src/test/fuzz/net.cpp
index ddf919f2e6..c882bd766a 100644
--- a/src/test/fuzz/net.cpp
+++ b/src/test/fuzz/net.cpp
@@ -53,7 +53,7 @@ FUZZ_TARGET(net, .init = initialize_net)
}
},
[&] {
- const std::optional<CService> service_opt = ConsumeDeserializable<CService>(fuzzed_data_provider);
+ const std::optional<CService> service_opt = ConsumeDeserializable<CService>(fuzzed_data_provider, ConsumeDeserializationParams<CNetAddr::SerParams>(fuzzed_data_provider));
if (!service_opt) {
return;
}
diff --git a/src/test/fuzz/script_sign.cpp b/src/test/fuzz/script_sign.cpp
index cec98432e1..07b99846c9 100644
--- a/src/test/fuzz/script_sign.cpp
+++ b/src/test/fuzz/script_sign.cpp
@@ -36,7 +36,8 @@ FUZZ_TARGET(script_sign, .init = initialize_script_sign)
const std::vector<uint8_t> key = ConsumeRandomLengthByteVector(fuzzed_data_provider, 128);
{
- CDataStream random_data_stream = ConsumeDataStream(fuzzed_data_provider);
+ DataStream stream{ConsumeDataStream(fuzzed_data_provider)};
+ CDataStream random_data_stream{stream, SER_NETWORK, INIT_PROTO_VERSION}; // temporary copy, to be removed along with the version flag SERIALIZE_TRANSACTION_NO_WITNESS
std::map<CPubKey, KeyOriginInfo> hd_keypaths;
try {
DeserializeHDKeypaths(random_data_stream, key, hd_keypaths);
diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h
index 5d27d2a180..8881ae16e7 100644
--- a/src/test/fuzz/util.h
+++ b/src/test/fuzz/util.h
@@ -70,9 +70,9 @@ template<typename B = uint8_t>
return BytesToBits(ConsumeRandomLengthByteVector(fuzzed_data_provider, max_length));
}
-[[nodiscard]] inline CDataStream ConsumeDataStream(FuzzedDataProvider& fuzzed_data_provider, const std::optional<size_t>& max_length = std::nullopt) noexcept
+[[nodiscard]] inline DataStream ConsumeDataStream(FuzzedDataProvider& fuzzed_data_provider, const std::optional<size_t>& max_length = std::nullopt) noexcept
{
- return CDataStream{ConsumeRandomLengthByteVector(fuzzed_data_provider, max_length), SER_NETWORK, INIT_PROTO_VERSION};
+ return DataStream{ConsumeRandomLengthByteVector(fuzzed_data_provider, max_length)};
}
[[nodiscard]] inline std::vector<std::string> ConsumeRandomLengthStringVector(FuzzedDataProvider& fuzzed_data_provider, const size_t max_vector_size = 16, const size_t max_string_length = 16) noexcept
@@ -96,6 +96,23 @@ template <typename T>
return r;
}
+template <typename P>
+[[nodiscard]] P ConsumeDeserializationParams(FuzzedDataProvider& fuzzed_data_provider) noexcept;
+
+template <typename T, typename P>
+[[nodiscard]] std::optional<T> ConsumeDeserializable(FuzzedDataProvider& fuzzed_data_provider, const P& params, const std::optional<size_t>& max_length = std::nullopt) noexcept
+{
+ const std::vector<uint8_t> buffer{ConsumeRandomLengthByteVector(fuzzed_data_provider, max_length)};
+ DataStream ds{buffer};
+ T obj;
+ try {
+ ds >> WithParams(params, obj);
+ } catch (const std::ios_base::failure&) {
+ return std::nullopt;
+ }
+ return obj;
+}
+
template <typename T>
[[nodiscard]] inline std::optional<T> ConsumeDeserializable(FuzzedDataProvider& fuzzed_data_provider, const std::optional<size_t>& max_length = std::nullopt) noexcept
{
diff --git a/src/test/fuzz/util/net.cpp b/src/test/fuzz/util/net.cpp
index 65bc336297..1545e11065 100644
--- a/src/test/fuzz/util/net.cpp
+++ b/src/test/fuzz/util/net.cpp
@@ -55,6 +55,27 @@ CAddress ConsumeAddress(FuzzedDataProvider& fuzzed_data_provider) noexcept
return {ConsumeService(fuzzed_data_provider), ConsumeWeakEnum(fuzzed_data_provider, ALL_SERVICE_FLAGS), NodeSeconds{std::chrono::seconds{fuzzed_data_provider.ConsumeIntegral<uint32_t>()}}};
}
+template <typename P>
+P ConsumeDeserializationParams(FuzzedDataProvider& fuzzed_data_provider) noexcept
+{
+ constexpr std::array ADDR_ENCODINGS{
+ CNetAddr::Encoding::V1,
+ CNetAddr::Encoding::V2,
+ };
+ constexpr std::array ADDR_FORMATS{
+ CAddress::Format::Disk,
+ CAddress::Format::Network,
+ };
+ if constexpr (std::is_same_v<P, CNetAddr::SerParams>) {
+ return P{PickValue(fuzzed_data_provider, ADDR_ENCODINGS)};
+ }
+ if constexpr (std::is_same_v<P, CAddress::SerParams>) {
+ return P{{PickValue(fuzzed_data_provider, ADDR_ENCODINGS)}, PickValue(fuzzed_data_provider, ADDR_FORMATS)};
+ }
+}
+template CNetAddr::SerParams ConsumeDeserializationParams(FuzzedDataProvider&) noexcept;
+template CAddress::SerParams ConsumeDeserializationParams(FuzzedDataProvider&) noexcept;
+
FuzzedSock::FuzzedSock(FuzzedDataProvider& fuzzed_data_provider)
: m_fuzzed_data_provider{fuzzed_data_provider}, m_selectable{fuzzed_data_provider.ConsumeBool()}
{
diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp
index ae342a6278..295cb78b36 100644
--- a/src/test/net_tests.cpp
+++ b/src/test/net_tests.cpp
@@ -327,19 +327,20 @@ BOOST_AUTO_TEST_CASE(cnetaddr_tostring_canonical_ipv6)
BOOST_AUTO_TEST_CASE(cnetaddr_serialize_v1)
{
CNetAddr addr;
- CDataStream s(SER_NETWORK, PROTOCOL_VERSION);
+ DataStream s{};
+ const auto ser_params{CAddress::V1_NETWORK};
- s << addr;
+ s << WithParams(ser_params, addr);
BOOST_CHECK_EQUAL(HexStr(s), "00000000000000000000000000000000");
s.clear();
addr = LookupHost("1.2.3.4", false).value();
- s << addr;
+ s << WithParams(ser_params, addr);
BOOST_CHECK_EQUAL(HexStr(s), "00000000000000000000ffff01020304");
s.clear();
addr = LookupHost("1a1b:2a2b:3a3b:4a4b:5a5b:6a6b:7a7b:8a8b", false).value();
- s << addr;
+ s << WithParams(ser_params, addr);
BOOST_CHECK_EQUAL(HexStr(s), "1a1b2a2b3a3b4a4b5a5b6a6b7a7b8a8b");
s.clear();
@@ -347,12 +348,12 @@ BOOST_AUTO_TEST_CASE(cnetaddr_serialize_v1)
BOOST_CHECK(!addr.SetSpecial("6hzph5hv6337r6p2.onion"));
BOOST_REQUIRE(addr.SetSpecial("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion"));
- s << addr;
+ s << WithParams(ser_params, addr);
BOOST_CHECK_EQUAL(HexStr(s), "00000000000000000000000000000000");
s.clear();
addr.SetInternal("a");
- s << addr;
+ s << WithParams(ser_params, addr);
BOOST_CHECK_EQUAL(HexStr(s), "fd6b88c08724ca978112ca1bbdcafac2");
s.clear();
}
@@ -360,22 +361,20 @@ BOOST_AUTO_TEST_CASE(cnetaddr_serialize_v1)
BOOST_AUTO_TEST_CASE(cnetaddr_serialize_v2)
{
CNetAddr addr;
- CDataStream s(SER_NETWORK, PROTOCOL_VERSION);
- // Add ADDRV2_FORMAT to the version so that the CNetAddr
- // serialize method produces an address in v2 format.
- s.SetVersion(s.GetVersion() | ADDRV2_FORMAT);
+ DataStream s{};
+ const auto ser_params{CAddress::V2_NETWORK};
- s << addr;
+ s << WithParams(ser_params, addr);
BOOST_CHECK_EQUAL(HexStr(s), "021000000000000000000000000000000000");
s.clear();
addr = LookupHost("1.2.3.4", false).value();
- s << addr;
+ s << WithParams(ser_params, addr);
BOOST_CHECK_EQUAL(HexStr(s), "010401020304");
s.clear();
addr = LookupHost("1a1b:2a2b:3a3b:4a4b:5a5b:6a6b:7a7b:8a8b", false).value();
- s << addr;
+ s << WithParams(ser_params, addr);
BOOST_CHECK_EQUAL(HexStr(s), "02101a1b2a2b3a3b4a4b5a5b6a6b7a7b8a8b");
s.clear();
@@ -383,12 +382,12 @@ BOOST_AUTO_TEST_CASE(cnetaddr_serialize_v2)
BOOST_CHECK(!addr.SetSpecial("6hzph5hv6337r6p2.onion"));
BOOST_REQUIRE(addr.SetSpecial("kpgvmscirrdqpekbqjsvw5teanhatztpp2gl6eee4zkowvwfxwenqaid.onion"));
- s << addr;
+ s << WithParams(ser_params, addr);
BOOST_CHECK_EQUAL(HexStr(s), "042053cd5648488c4707914182655b7664034e09e66f7e8cbf1084e654eb56c5bd88");
s.clear();
BOOST_REQUIRE(addr.SetInternal("a"));
- s << addr;
+ s << WithParams(ser_params, addr);
BOOST_CHECK_EQUAL(HexStr(s), "0210fd6b88c08724ca978112ca1bbdcafac2");
s.clear();
}
@@ -396,16 +395,14 @@ BOOST_AUTO_TEST_CASE(cnetaddr_serialize_v2)
BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
{
CNetAddr addr;
- CDataStream s(SER_NETWORK, PROTOCOL_VERSION);
- // Add ADDRV2_FORMAT to the version so that the CNetAddr
- // unserialize method expects an address in v2 format.
- s.SetVersion(s.GetVersion() | ADDRV2_FORMAT);
+ DataStream s{};
+ const auto ser_params{CAddress::V2_NETWORK};
// Valid IPv4.
s << Span{ParseHex("01" // network type (IPv4)
"04" // address length
"01020304")}; // address
- s >> addr;
+ s >> WithParams(ser_params, addr);
BOOST_CHECK(addr.IsValid());
BOOST_CHECK(addr.IsIPv4());
BOOST_CHECK(addr.IsAddrV1Compatible());
@@ -416,7 +413,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
s << Span{ParseHex("01" // network type (IPv4)
"04" // address length
"0102")}; // address
- BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure, HasReason("end of data"));
+ BOOST_CHECK_EXCEPTION(s >> WithParams(ser_params, addr), std::ios_base::failure, HasReason("end of data"));
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
s.clear();
@@ -424,7 +421,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
s << Span{ParseHex("01" // network type (IPv4)
"05" // address length
"01020304")}; // address
- BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
+ BOOST_CHECK_EXCEPTION(s >> WithParams(ser_params, addr), std::ios_base::failure,
HasReason("BIP155 IPv4 address with length 5 (should be 4)"));
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
s.clear();
@@ -433,7 +430,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
s << Span{ParseHex("01" // network type (IPv4)
"fd0102" // address length (513 as CompactSize)
"01020304")}; // address
- BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
+ BOOST_CHECK_EXCEPTION(s >> WithParams(ser_params, addr), std::ios_base::failure,
HasReason("Address too long: 513 > 512"));
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
s.clear();
@@ -442,7 +439,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
s << Span{ParseHex("02" // network type (IPv6)
"10" // address length
"0102030405060708090a0b0c0d0e0f10")}; // address
- s >> addr;
+ s >> WithParams(ser_params, addr);
BOOST_CHECK(addr.IsValid());
BOOST_CHECK(addr.IsIPv6());
BOOST_CHECK(addr.IsAddrV1Compatible());
@@ -455,7 +452,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"10" // address length
"fd6b88c08724ca978112ca1bbdcafac2")}; // address: 0xfd + sha256("bitcoin")[0:5] +
// sha256(name)[0:10]
- s >> addr;
+ s >> WithParams(ser_params, addr);
BOOST_CHECK(addr.IsInternal());
BOOST_CHECK(addr.IsAddrV1Compatible());
BOOST_CHECK_EQUAL(addr.ToStringAddr(), "zklycewkdo64v6wc.internal");
@@ -465,7 +462,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
s << Span{ParseHex("02" // network type (IPv6)
"04" // address length
"00")}; // address
- BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
+ BOOST_CHECK_EXCEPTION(s >> WithParams(ser_params, addr), std::ios_base::failure,
HasReason("BIP155 IPv6 address with length 4 (should be 16)"));
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
s.clear();
@@ -474,7 +471,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
s << Span{ParseHex("02" // network type (IPv6)
"10" // address length
"00000000000000000000ffff01020304")}; // address
- s >> addr;
+ s >> WithParams(ser_params, addr);
BOOST_CHECK(!addr.IsValid());
BOOST_REQUIRE(s.empty());
@@ -482,7 +479,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
s << Span{ParseHex("02" // network type (IPv6)
"10" // address length
"fd87d87eeb430102030405060708090a")}; // address
- s >> addr;
+ s >> WithParams(ser_params, addr);
BOOST_CHECK(!addr.IsValid());
BOOST_REQUIRE(s.empty());
@@ -490,7 +487,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
s << Span{ParseHex("03" // network type (TORv2)
"0a" // address length
"f1f2f3f4f5f6f7f8f9fa")}; // address
- s >> addr;
+ s >> WithParams(ser_params, addr);
BOOST_CHECK(!addr.IsValid());
BOOST_REQUIRE(s.empty());
@@ -500,7 +497,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"79bcc625184b05194975c28b66b66b04" // address
"69f7f6556fb1ac3189a79b40dda32f1f"
)};
- s >> addr;
+ s >> WithParams(ser_params, addr);
BOOST_CHECK(addr.IsValid());
BOOST_CHECK(addr.IsTor());
BOOST_CHECK(!addr.IsAddrV1Compatible());
@@ -513,7 +510,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"00" // address length
"00" // address
)};
- BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
+ BOOST_CHECK_EXCEPTION(s >> WithParams(ser_params, addr), std::ios_base::failure,
HasReason("BIP155 TORv3 address with length 0 (should be 32)"));
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
s.clear();
@@ -523,7 +520,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"20" // address length
"a2894dabaec08c0051a481a6dac88b64" // address
"f98232ae42d4b6fd2fa81952dfe36a87")};
- s >> addr;
+ s >> WithParams(ser_params, addr);
BOOST_CHECK(addr.IsValid());
BOOST_CHECK(addr.IsI2P());
BOOST_CHECK(!addr.IsAddrV1Compatible());
@@ -536,7 +533,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"03" // address length
"00" // address
)};
- BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
+ BOOST_CHECK_EXCEPTION(s >> WithParams(ser_params, addr), std::ios_base::failure,
HasReason("BIP155 I2P address with length 3 (should be 32)"));
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
s.clear();
@@ -546,7 +543,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"10" // address length
"fc000001000200030004000500060007" // address
)};
- s >> addr;
+ s >> WithParams(ser_params, addr);
BOOST_CHECK(addr.IsValid());
BOOST_CHECK(addr.IsCJDNS());
BOOST_CHECK(!addr.IsAddrV1Compatible());
@@ -558,7 +555,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"10" // address length
"aa000001000200030004000500060007" // address
)};
- s >> addr;
+ s >> WithParams(ser_params, addr);
BOOST_CHECK(addr.IsCJDNS());
BOOST_CHECK(!addr.IsValid());
BOOST_REQUIRE(s.empty());
@@ -568,7 +565,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"01" // address length
"00" // address
)};
- BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
+ BOOST_CHECK_EXCEPTION(s >> WithParams(ser_params, addr), std::ios_base::failure,
HasReason("BIP155 CJDNS address with length 1 (should be 16)"));
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
s.clear();
@@ -578,7 +575,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"fe00000002" // address length (CompactSize's MAX_SIZE)
"01020304050607" // address
)};
- BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
+ BOOST_CHECK_EXCEPTION(s >> WithParams(ser_params, addr), std::ios_base::failure,
HasReason("Address too long: 33554432 > 512"));
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
s.clear();
@@ -588,7 +585,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"04" // address length
"01020304" // address
)};
- s >> addr;
+ s >> WithParams(ser_params, addr);
BOOST_CHECK(!addr.IsValid());
BOOST_REQUIRE(s.empty());
@@ -597,7 +594,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"00" // address length
"" // address
)};
- s >> addr;
+ s >> WithParams(ser_params, addr);
BOOST_CHECK(!addr.IsValid());
BOOST_REQUIRE(s.empty());
}
@@ -852,7 +849,7 @@ BOOST_AUTO_TEST_CASE(initial_advertise_from_version_message)
std::chrono::microseconds time_received_dummy{0};
const auto msg_version =
- msg_maker.Make(NetMsgType::VERSION, PROTOCOL_VERSION, services, time, services, peer_us);
+ msg_maker.Make(NetMsgType::VERSION, PROTOCOL_VERSION, services, time, services, WithParams(CAddress::V1_NETWORK, peer_us));
CDataStream msg_version_stream{msg_version.data, SER_NETWORK, PROTOCOL_VERSION};
m_node.peerman->ProcessMessage(
@@ -875,10 +872,10 @@ BOOST_AUTO_TEST_CASE(initial_advertise_from_version_message)
Span<const unsigned char> data,
bool is_incoming) -> void {
if (!is_incoming && msg_type == "addr") {
- CDataStream s(data, SER_NETWORK, PROTOCOL_VERSION);
+ DataStream s{data};
std::vector<CAddress> addresses;
- s >> addresses;
+ s >> WithParams(CAddress::V1_NETWORK, addresses);
for (const auto& addr : addresses) {
if (addr == expected) {
diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp
index 05953bfd10..e22bf7e7c0 100644
--- a/src/test/netbase_tests.cpp
+++ b/src/test/netbase_tests.cpp
@@ -559,35 +559,35 @@ static constexpr const char* stream_addrv2_hex =
BOOST_AUTO_TEST_CASE(caddress_serialize_v1)
{
- CDataStream s(SER_NETWORK, PROTOCOL_VERSION);
+ DataStream s{};
- s << fixture_addresses;
+ s << WithParams(CAddress::V1_NETWORK, fixture_addresses);
BOOST_CHECK_EQUAL(HexStr(s), stream_addrv1_hex);
}
BOOST_AUTO_TEST_CASE(caddress_unserialize_v1)
{
- CDataStream s(ParseHex(stream_addrv1_hex), SER_NETWORK, PROTOCOL_VERSION);
+ DataStream s{ParseHex(stream_addrv1_hex)};
std::vector<CAddress> addresses_unserialized;
- s >> addresses_unserialized;
+ s >> WithParams(CAddress::V1_NETWORK, addresses_unserialized);
BOOST_CHECK(fixture_addresses == addresses_unserialized);
}
BOOST_AUTO_TEST_CASE(caddress_serialize_v2)
{
- CDataStream s(SER_NETWORK, PROTOCOL_VERSION | ADDRV2_FORMAT);
+ DataStream s{};
- s << fixture_addresses;
+ s << WithParams(CAddress::V2_NETWORK, fixture_addresses);
BOOST_CHECK_EQUAL(HexStr(s), stream_addrv2_hex);
}
BOOST_AUTO_TEST_CASE(caddress_unserialize_v2)
{
- CDataStream s(ParseHex(stream_addrv2_hex), SER_NETWORK, PROTOCOL_VERSION | ADDRV2_FORMAT);
+ DataStream s{ParseHex(stream_addrv2_hex)};
std::vector<CAddress> addresses_unserialized;
- s >> addresses_unserialized;
+ s >> WithParams(CAddress::V2_NETWORK, addresses_unserialized);
BOOST_CHECK(fixture_addresses == addresses_unserialized);
}
diff --git a/src/test/util/net.cpp b/src/test/util/net.cpp
index 8015db3e80..5696f8d13c 100644
--- a/src/test/util/net.cpp
+++ b/src/test/util/net.cpp
@@ -33,9 +33,9 @@ void ConnmanTestMsg::Handshake(CNode& node,
Using<CustomUintFormatter<8>>(remote_services), //
int64_t{}, // dummy time
int64_t{}, // ignored service bits
- CService{}, // dummy
+ WithParams(CNetAddr::V1, CService{}), // dummy
int64_t{}, // ignored service bits
- CService{}, // ignored
+ WithParams(CNetAddr::V1, CService{}), // ignored
uint64_t{1}, // dummy nonce
std::string{}, // dummy subver
int32_t{}, // dummy starting_height