bitcoin/src/test/fuzz/net.cpp
Vasil Dimov 75acdcbaa9
net: replace manual reference counting of CNode with shared_ptr
Before this change the code used to count references to `CNode` objects
manually via `CNode::nRefCount`. Unneeded `CNode`s were scheduled for
deletion by putting them in `CConnman::m_nodes_disconnected` and were
deleted after their reference count reached zero. Deleting consists of
calling `PeerManager::FinalizeNode()` and destroying the `CNode` object.

Replace this scheme with `std::shared_ptr`. This simplifies the code and
removes:
`CNode::nRefCount`
`CNode::GetRefCount()`
`CNode::AddRef()`
`CNode::Release()`
`CConnman::m_nodes_disconnected`
`CConnman::NodesSnapshot`

Now creating a snapshot of `CConnman::m_nodes` is done by simply copying
it (under the mutex).

Call `PeerManager::FinalizeNode()` from the destructor of `CNode`, which
is called when the reference count reaches 0.
2025-04-15 17:03:28 +02:00

105 lines
3.3 KiB
C++

// Copyright (c) 2020-2022 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 <chainparams.h>
#include <net.h>
#include <net_permissions.h>
#include <netaddress.h>
#include <protocol.h>
#include <random.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <test/fuzz/util/net.h>
#include <test/util/net.h>
#include <test/util/setup_common.h>
#include <util/asmap.h>
#include <util/chaintype.h>
#include <util/time.h>
#include <cstdint>
#include <optional>
#include <string>
#include <vector>
void initialize_net()
{
static const auto testing_setup = MakeNoLogFileContext<>(ChainType::MAIN);
}
FUZZ_TARGET(net, .init = initialize_net)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
SetMockTime(ConsumeTime(fuzzed_data_provider));
CNode node{ConsumeNode(fuzzed_data_provider)};
node.SetCommonVersion(fuzzed_data_provider.ConsumeIntegral<int>());
if (const auto service_opt =
ConsumeDeserializable<CService>(fuzzed_data_provider, ConsumeDeserializationParams<CNetAddr::SerParams>(fuzzed_data_provider)))
{
node.SetAddrLocal(*service_opt);
}
LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 10000) {
CallOneOf(
fuzzed_data_provider,
[&] {
node.CloseSocketDisconnect();
},
[&] {
CNodeStats stats;
node.CopyStats(stats);
},
[&] {
const std::vector<uint8_t> b = ConsumeRandomLengthByteVector(fuzzed_data_provider);
bool complete;
node.ReceiveMsgBytes(b, complete);
});
}
(void)node.GetAddrLocal();
(void)node.GetId();
(void)node.GetLocalNonce();
(void)node.GetCommonVersion();
const NetPermissionFlags net_permission_flags = ConsumeWeakEnum(fuzzed_data_provider, ALL_NET_PERMISSION_FLAGS);
(void)node.HasPermission(net_permission_flags);
(void)node.ConnectedThroughNetwork();
}
FUZZ_TARGET(local_address, .init = initialize_net)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
SetMockTime(ConsumeTime(fuzzed_data_provider));
CService service{ConsumeService(fuzzed_data_provider)};
CNode node{ConsumeNode(fuzzed_data_provider)};
{
LOCK(g_maplocalhost_mutex);
mapLocalHost.clear();
}
LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 10000) {
CallOneOf(
fuzzed_data_provider,
[&] {
service = ConsumeService(fuzzed_data_provider);
},
[&] {
const bool added{AddLocal(service, fuzzed_data_provider.ConsumeIntegralInRange<int>(0, LOCAL_MAX - 1))};
if (!added) return;
assert(service.IsRoutable());
assert(IsLocal(service));
assert(SeenLocal(service));
},
[&] {
(void)RemoveLocal(service);
},
[&] {
(void)SeenLocal(service);
},
[&] {
(void)IsLocal(service);
},
[&] {
(void)GetLocalAddress(node);
});
}
}