partial bitcoin#20228: Make addrman a top-level component

This commit is contained in:
Kittywhiskers Van Gogh 2023-02-16 06:34:06 +00:00 committed by UdjinM6
parent 3e993abf10
commit 40906b2bbb
11 changed files with 86 additions and 119 deletions

View File

@ -278,6 +278,7 @@ void PrepareShutdown(NodeContext& node)
node.peer_logic.reset(); node.peer_logic.reset();
node.connman.reset(); node.connman.reset();
node.banman.reset(); node.banman.reset();
node.addrman.reset();
if (node.mempool && node.mempool->IsLoaded() && node.args->GetArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) { if (node.mempool && node.mempool->IsLoaded() && node.args->GetArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) {
DumpMempool(*node.mempool); DumpMempool(*node.mempool);
@ -1755,10 +1756,12 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
fDiscover = args.GetBoolArg("-discover", true); fDiscover = args.GetBoolArg("-discover", true);
g_relay_txes = !args.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY); g_relay_txes = !args.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY);
assert(!node.addrman);
node.addrman = std::make_unique<CAddrMan>();
assert(!node.banman); assert(!node.banman);
node.banman = std::make_unique<BanMan>(GetDataDir() / "banlist.dat", &uiInterface, args.GetArg("-bantime", DEFAULT_MISBEHAVING_BANTIME)); node.banman = std::make_unique<BanMan>(GetDataDir() / "banlist.dat", &uiInterface, args.GetArg("-bantime", DEFAULT_MISBEHAVING_BANTIME));
assert(!node.connman); assert(!node.connman);
node.connman = std::make_unique<CConnman>(GetRand(std::numeric_limits<uint64_t>::max()), GetRand(std::numeric_limits<uint64_t>::max())); node.connman = std::make_unique<CConnman>(GetRand(std::numeric_limits<uint64_t>::max()), GetRand(std::numeric_limits<uint64_t>::max()), *node.addrman);
assert(!node.fee_estimator); assert(!node.fee_estimator);
// Don't initialize fee estimation with old data if we don't relay transactions, // Don't initialize fee estimation with old data if we don't relay transactions,
@ -1774,7 +1777,7 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
ChainstateManager& chainman = *Assert(node.chainman); ChainstateManager& chainman = *Assert(node.chainman);
node.peer_logic.reset(new PeerLogicValidation( node.peer_logic.reset(new PeerLogicValidation(
*node.connman, node.banman.get(), *node.scheduler, chainman, *node.mempool, node.llmq_ctx *node.connman, *node.addrman, node.banman.get(), *node.scheduler, chainman, *node.mempool, node.llmq_ctx
)); ));
RegisterValidationInterface(node.peer_logic.get()); RegisterValidationInterface(node.peer_logic.get());

View File

@ -2949,9 +2949,8 @@ void CConnman::SetNetworkActive(bool active)
uiInterface.NotifyNetworkActiveChanged(fNetworkActive); uiInterface.NotifyNetworkActiveChanged(fNetworkActive);
} }
CConnman::CConnman(uint64_t nSeed0In, uint64_t nSeed1In) : CConnman::CConnman(uint64_t nSeed0In, uint64_t nSeed1In, CAddrMan& addrman_in) :
addrman(Params().AllowMultiplePorts()), addrman(addrman_in), nSeed0(nSeed0In), nSeed1(nSeed1In)
nSeed0(nSeed0In), nSeed1(nSeed1In)
{ {
SetTryNewOutboundPeer(false); SetTryNewOutboundPeer(false);
@ -3309,11 +3308,7 @@ void CConnman::Stop()
void CConnman::DeleteNode(CNode* pnode) void CConnman::DeleteNode(CNode* pnode)
{ {
assert(pnode); assert(pnode);
bool fUpdateConnectionTime = false; m_msgproc->FinalizeNode(*pnode);
m_msgproc->FinalizeNode(*pnode, fUpdateConnectionTime);
if(fUpdateConnectionTime) {
addrman.Connected(pnode->addr);
}
delete pnode; delete pnode;
} }
@ -3323,21 +3318,6 @@ CConnman::~CConnman()
Stop(); Stop();
} }
void CConnman::SetServices(const CService &addr, ServiceFlags nServices)
{
addrman.SetServices(addr, nServices);
}
void CConnman::MarkAddressGood(const CAddress& addr)
{
addrman.Good(addr);
}
void CConnman::AddNewAddresses(const std::vector<CAddress>& vAddr, const CAddress& addrFrom, int64_t nTimePenalty)
{
addrman.Add(vAddr, addrFrom, nTimePenalty);
}
std::vector<CAddress> CConnman::GetAddresses() std::vector<CAddress> CConnman::GetAddresses()
{ {
return addrman.GetAddr(); return addrman.GetAddr();

View File

@ -213,7 +213,7 @@ public:
socketEventsMode = connOptions.socketEventsMode; socketEventsMode = connOptions.socketEventsMode;
} }
CConnman(uint64_t seed0, uint64_t seed1); CConnman(uint64_t seed0, uint64_t seed1, CAddrMan& addrman);
~CConnman(); ~CConnman();
bool Start(CScheduler& scheduler, const Options& options); bool Start(CScheduler& scheduler, const Options& options);
@ -399,9 +399,6 @@ public:
void RelayInvFiltered(CInv &inv, const uint256 &relatedTxHash, const int minProtoVersion = MIN_PEER_PROTO_VERSION); void RelayInvFiltered(CInv &inv, const uint256 &relatedTxHash, const int minProtoVersion = MIN_PEER_PROTO_VERSION);
// Addrman functions // Addrman functions
void SetServices(const CService &addr, ServiceFlags nServices);
void MarkAddressGood(const CAddress& addr);
void AddNewAddresses(const std::vector<CAddress>& vAddr, const CAddress& addrFrom, int64_t nTimePenalty = 0);
std::vector<CAddress> GetAddresses(); std::vector<CAddress> GetAddresses();
// This allows temporarily exceeding m_max_outbound_full_relay, with the goal of finding // This allows temporarily exceeding m_max_outbound_full_relay, with the goal of finding
@ -580,7 +577,7 @@ private:
std::vector<ListenSocket> vhListenSocket; std::vector<ListenSocket> vhListenSocket;
std::atomic<bool> fNetworkActive{true}; std::atomic<bool> fNetworkActive{true};
bool fAddressesInitialized{false}; bool fAddressesInitialized{false};
CAddrMan addrman; CAddrMan& addrman;
std::deque<std::string> vOneShots GUARDED_BY(cs_vOneShots); std::deque<std::string> vOneShots GUARDED_BY(cs_vOneShots);
CCriticalSection cs_vOneShots; CCriticalSection cs_vOneShots;
std::vector<std::string> vAddedNodes GUARDED_BY(cs_vAddedNodes); std::vector<std::string> vAddedNodes GUARDED_BY(cs_vAddedNodes);
@ -708,7 +705,7 @@ public:
virtual bool ProcessMessages(CNode* pnode, std::atomic<bool>& interrupt) = 0; virtual bool ProcessMessages(CNode* pnode, std::atomic<bool>& interrupt) = 0;
virtual bool SendMessages(CNode* pnode) = 0; virtual bool SendMessages(CNode* pnode) = 0;
virtual void InitializeNode(CNode* pnode) = 0; virtual void InitializeNode(CNode* pnode) = 0;
virtual void FinalizeNode(const CNode& node, bool& update_connection_time) = 0; virtual void FinalizeNode(const CNode& node) = 0;
protected: protected:
/** /**

View File

@ -965,11 +965,11 @@ void PeerLogicValidation::ReattemptInitialBroadcast(CScheduler& scheduler) const
scheduler.scheduleFromNow([&] { ReattemptInitialBroadcast(scheduler); }, delta); scheduler.scheduleFromNow([&] { ReattemptInitialBroadcast(scheduler); }, delta);
} }
void PeerLogicValidation::FinalizeNode(const CNode& node, bool& fUpdateConnectionTime) { void PeerLogicValidation::FinalizeNode(const CNode& node) {
NodeId nodeid = node.GetId(); NodeId nodeid = node.GetId();
fUpdateConnectionTime = false;
LOCK(cs_main);
int misbehavior{0}; int misbehavior{0};
LOCK(cs_main);
{
{ {
PeerRef peer = GetPeerRef(nodeid); PeerRef peer = GetPeerRef(nodeid);
assert(peer != nullptr); assert(peer != nullptr);
@ -983,11 +983,6 @@ void PeerLogicValidation::FinalizeNode(const CNode& node, bool& fUpdateConnectio
if (state->fSyncStarted) if (state->fSyncStarted)
nSyncStarted--; nSyncStarted--;
if (node.fSuccessfullyConnected && misbehavior == 0 && !node.m_block_relay_only_peer && !node.fInbound) {
// Note: we avoid changing visible addrman state for block-relay-only peers
fUpdateConnectionTime = true;
}
for (const QueuedBlock& entry : state->vBlocksInFlight) { for (const QueuedBlock& entry : state->vBlocksInFlight) {
mapBlocksInFlight.erase(entry.hash); mapBlocksInFlight.erase(entry.hash);
} }
@ -1007,6 +1002,15 @@ void PeerLogicValidation::FinalizeNode(const CNode& node, bool& fUpdateConnectio
assert(nPeersWithValidatedDownloads == 0); assert(nPeersWithValidatedDownloads == 0);
assert(g_outbound_peers_with_protect_from_disconnect == 0); assert(g_outbound_peers_with_protect_from_disconnect == 0);
} }
} // cs_main
if (node.fSuccessfullyConnected && misbehavior == 0 && !node.m_block_relay_only_peer && !node.fInbound) {
// Only change visible addrman state for full outbound peers. We don't
// call Connected() for feeler connections since they don't have
// fSuccessfullyConnected set.
m_addrman.Connected(node.addr);
}
LogPrint(BCLog::NET, "Cleared nodestate for peer=%d\n", nodeid); LogPrint(BCLog::NET, "Cleared nodestate for peer=%d\n", nodeid);
} }
@ -1296,9 +1300,10 @@ static bool BlockRequestAllowed(const CBlockIndex* pindex, const Consensus::Para
(GetBlockProofEquivalentTime(*pindexBestHeader, *pindex, *pindexBestHeader, consensusParams) < STALE_RELAY_AGE_LIMIT); (GetBlockProofEquivalentTime(*pindexBestHeader, *pindex, *pindexBestHeader, consensusParams) < STALE_RELAY_AGE_LIMIT);
} }
PeerLogicValidation::PeerLogicValidation(CConnman& connman, BanMan* banman, CScheduler &scheduler, ChainstateManager& chainman, CTxMemPool& pool, PeerLogicValidation::PeerLogicValidation(CConnman& connman, CAddrMan& addrman, BanMan* banman, CScheduler &scheduler, ChainstateManager& chainman, CTxMemPool& pool,
std::unique_ptr<LLMQContext>& llmq_ctx) std::unique_ptr<LLMQContext>& llmq_ctx)
: m_connman(connman), : m_connman(connman),
m_addrman(addrman),
m_banman(banman), m_banman(banman),
m_chainman(chainman), m_chainman(chainman),
m_mempool(pool), m_mempool(pool),
@ -2644,7 +2649,7 @@ void PeerLogicValidation::ProcessMessage(
nServices = ServiceFlags(nServiceInt); nServices = ServiceFlags(nServiceInt);
if (!pfrom.fInbound) if (!pfrom.fInbound)
{ {
m_connman.SetServices(pfrom.addr, nServices); m_addrman.SetServices(pfrom.addr, nServices);
} }
if (!pfrom.fInbound && !pfrom.fFeeler && !pfrom.m_manual_connection && !HasAllDesirableServiceFlags(nServices)) if (!pfrom.fInbound && !pfrom.fFeeler && !pfrom.m_manual_connection && !HasAllDesirableServiceFlags(nServices))
{ {
@ -2782,7 +2787,7 @@ void PeerLogicValidation::ProcessMessage(
// Get recent addresses // Get recent addresses
m_connman.PushMessage(&pfrom, CNetMsgMaker(nSendVersion).Make(NetMsgType::GETADDR)); m_connman.PushMessage(&pfrom, CNetMsgMaker(nSendVersion).Make(NetMsgType::GETADDR));
pfrom.fGetAddr = true; pfrom.fGetAddr = true;
m_connman.MarkAddressGood(pfrom.addr); m_addrman.Good(pfrom.addr);
} }
std::string remoteAddr; std::string remoteAddr;
@ -2954,7 +2959,7 @@ void PeerLogicValidation::ProcessMessage(
if (fReachable) if (fReachable)
vAddrOk.push_back(addr); vAddrOk.push_back(addr);
} }
m_connman.AddNewAddresses(vAddrOk, pfrom.addr, 2 * 60 * 60); m_addrman.Add(vAddrOk, pfrom.addr, 2 * 60 * 60);
if (vAddr.size() < 1000) if (vAddr.size() < 1000)
pfrom.fGetAddr = false; pfrom.fGetAddr = false;
if (pfrom.fOneShot) if (pfrom.fOneShot)

View File

@ -11,6 +11,7 @@
#include <sync.h> #include <sync.h>
#include <validationinterface.h> #include <validationinterface.h>
class CAddrMan;
class CTxMemPool; class CTxMemPool;
class ChainstateManager; class ChainstateManager;
struct LLMQContext; struct LLMQContext;
@ -28,6 +29,7 @@ class PeerLogicValidation final : public CValidationInterface, public NetEventsI
private: private:
CConnman& m_connman; CConnman& m_connman;
BanMan* const m_banman; BanMan* const m_banman;
CAddrMan& m_addrman;
ChainstateManager& m_chainman; ChainstateManager& m_chainman;
CTxMemPool& m_mempool; CTxMemPool& m_mempool;
std::unique_ptr<LLMQContext>& m_llmq_ctx; std::unique_ptr<LLMQContext>& m_llmq_ctx;
@ -35,7 +37,7 @@ private:
bool MaybeDiscourageAndDisconnect(CNode& pnode); bool MaybeDiscourageAndDisconnect(CNode& pnode);
public: public:
PeerLogicValidation(CConnman& connman, BanMan* banman, CScheduler &scheduler, ChainstateManager& chainman, CTxMemPool& pool, PeerLogicValidation(CConnman& connman, CAddrMan& addrman, BanMan* banman, CScheduler &scheduler, ChainstateManager& chainman, CTxMemPool& pool,
std::unique_ptr<LLMQContext>& llmq_ctx); std::unique_ptr<LLMQContext>& llmq_ctx);
/** /**
@ -59,7 +61,7 @@ public:
/** Initialize a peer by adding it to mapNodeState and pushing a message requesting its version */ /** Initialize a peer by adding it to mapNodeState and pushing a message requesting its version */
void InitializeNode(CNode* pnode) override; void InitializeNode(CNode* pnode) override;
/** Handle removal of a peer by updating various state and removing it from mapNodeState */ /** Handle removal of a peer by updating various state and removing it from mapNodeState */
void FinalizeNode(const CNode& node, bool& fUpdateConnectionTime) override; void FinalizeNode(const CNode& node) override;
/** /**
* Process protocol messages received from a given node * Process protocol messages received from a given node
* *

View File

@ -4,6 +4,7 @@
#include <node/context.h> #include <node/context.h>
#include <addrman.h>
#include <banman.h> #include <banman.h>
#include <interfaces/chain.h> #include <interfaces/chain.h>
#include <llmq/context.h> #include <llmq/context.h>

View File

@ -12,6 +12,7 @@
class ArgsManager; class ArgsManager;
class BanMan; class BanMan;
class CAddrMan;
class CBlockPolicyEstimator; class CBlockPolicyEstimator;
class CConnman; class CConnman;
class CScheduler; class CScheduler;
@ -37,6 +38,7 @@ class WalletClient;
//! any member functions. It should just be a collection of references that can //! any member functions. It should just be a collection of references that can
//! be used without pulling in unwanted dependencies or functionality. //! be used without pulling in unwanted dependencies or functionality.
struct NodeContext { struct NodeContext {
std::unique_ptr<CAddrMan> addrman;
std::unique_ptr<CConnman> connman; std::unique_ptr<CConnman> connman;
std::unique_ptr<CTxMemPool> mempool; std::unique_ptr<CTxMemPool> mempool;
std::unique_ptr<CBlockPolicyEstimator> fee_estimator; std::unique_ptr<CBlockPolicyEstimator> fee_estimator;

View File

@ -80,9 +80,9 @@ BOOST_FIXTURE_TEST_SUITE(denialofservice_tests, TestingSetup)
// work. // work.
BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction) BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction)
{ {
auto connman = std::make_unique<CConnman>(0x1337, 0x1337); auto connman = std::make_unique<CConnman>(0x1337, 0x1337, *m_node.addrman);
auto peerLogic = std::make_unique<PeerLogicValidation>( auto peerLogic = std::make_unique<PeerLogicValidation>(
*connman, nullptr, *m_node.scheduler, *m_node.chainman, *m_node.mempool, m_node.llmq_ctx *connman, *m_node.addrman, nullptr, *m_node.scheduler, *m_node.chainman, *m_node.mempool, m_node.llmq_ctx
); );
// Mock an outbound peer // Mock an outbound peer
@ -133,8 +133,7 @@ BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction)
BOOST_CHECK(dummyNode1.fDisconnect == true); BOOST_CHECK(dummyNode1.fDisconnect == true);
SetMockTime(0); SetMockTime(0);
bool dummy; peerLogic->FinalizeNode(dummyNode1);
peerLogic->FinalizeNode(dummyNode1, dummy);
} }
static void AddRandomOutboundPeer(std::vector<CNode *> &vNodes, PeerLogicValidation &peerLogic, CConnmanTest* connman) static void AddRandomOutboundPeer(std::vector<CNode *> &vNodes, PeerLogicValidation &peerLogic, CConnmanTest* connman)
@ -153,9 +152,9 @@ static void AddRandomOutboundPeer(std::vector<CNode *> &vNodes, PeerLogicValidat
BOOST_AUTO_TEST_CASE(stale_tip_peer_management) BOOST_AUTO_TEST_CASE(stale_tip_peer_management)
{ {
auto connman = std::make_unique<CConnmanTest>(0x1337, 0x1337); auto connman = std::make_unique<CConnmanTest>(0x1337, 0x1337, *m_node.addrman);
auto peerLogic = std::make_unique<PeerLogicValidation>( auto peerLogic = std::make_unique<PeerLogicValidation>(
*connman, nullptr, *m_node.scheduler, *m_node.chainman, *m_node.mempool, m_node.llmq_ctx *connman, *m_node.addrman, nullptr, *m_node.scheduler, *m_node.chainman, *m_node.mempool, m_node.llmq_ctx
); );
const Consensus::Params& consensusParams = Params().GetConsensus(); const Consensus::Params& consensusParams = Params().GetConsensus();
@ -217,9 +216,8 @@ BOOST_AUTO_TEST_CASE(stale_tip_peer_management)
BOOST_CHECK(vNodes[max_outbound_full_relay-1]->fDisconnect == true); BOOST_CHECK(vNodes[max_outbound_full_relay-1]->fDisconnect == true);
BOOST_CHECK(vNodes.back()->fDisconnect == false); BOOST_CHECK(vNodes.back()->fDisconnect == false);
bool dummy;
for (const CNode *node : vNodes) { for (const CNode *node : vNodes) {
peerLogic->FinalizeNode(*node, dummy); peerLogic->FinalizeNode(*node);
} }
connman->ClearNodes(); connman->ClearNodes();
@ -228,9 +226,9 @@ BOOST_AUTO_TEST_CASE(stale_tip_peer_management)
BOOST_AUTO_TEST_CASE(DoS_banning) BOOST_AUTO_TEST_CASE(DoS_banning)
{ {
auto banman = std::make_unique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME); auto banman = std::make_unique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME);
auto connman = std::make_unique<CConnman>(0x1337, 0x1337); auto connman = std::make_unique<CConnman>(0x1337, 0x1337, *m_node.addrman);
auto peerLogic = std::make_unique<PeerLogicValidation>( auto peerLogic = std::make_unique<PeerLogicValidation>(
*connman, banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool, m_node.llmq_ctx *connman, *m_node.addrman, banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool, m_node.llmq_ctx
); );
banman->ClearBanned(); banman->ClearBanned();
@ -268,17 +266,16 @@ BOOST_AUTO_TEST_CASE(DoS_banning)
} }
BOOST_CHECK(banman->IsDiscouraged(addr2)); BOOST_CHECK(banman->IsDiscouraged(addr2));
bool dummy; peerLogic->FinalizeNode(dummyNode1);
peerLogic->FinalizeNode(dummyNode1, dummy); peerLogic->FinalizeNode(dummyNode2);
peerLogic->FinalizeNode(dummyNode2, dummy);
} }
BOOST_AUTO_TEST_CASE(DoS_banscore) BOOST_AUTO_TEST_CASE(DoS_banscore)
{ {
auto banman = std::make_unique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME); auto banman = std::make_unique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME);
auto connman = std::make_unique<CConnman>(0x1337, 0x1337); auto connman = std::make_unique<CConnman>(0x1337, 0x1337, *m_node.addrman);
auto peerLogic = std::make_unique<PeerLogicValidation>( auto peerLogic = std::make_unique<PeerLogicValidation>(
*connman, banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool, m_node.llmq_ctx *connman, *m_node.addrman, banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool, m_node.llmq_ctx
); );
banman->ClearBanned(); banman->ClearBanned();
@ -315,16 +312,15 @@ BOOST_AUTO_TEST_CASE(DoS_banscore)
BOOST_CHECK(banman->IsDiscouraged(addr1)); BOOST_CHECK(banman->IsDiscouraged(addr1));
gArgs.ForceSetArg("-banscore", ToString(DEFAULT_BANSCORE_THRESHOLD)); gArgs.ForceSetArg("-banscore", ToString(DEFAULT_BANSCORE_THRESHOLD));
bool dummy; peerLogic->FinalizeNode(dummyNode1);
peerLogic->FinalizeNode(dummyNode1, dummy);
} }
BOOST_AUTO_TEST_CASE(DoS_bantime) BOOST_AUTO_TEST_CASE(DoS_bantime)
{ {
auto banman = std::make_unique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME); auto banman = std::make_unique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME);
auto connman = std::make_unique<CConnman>(0x1337, 0x1337); auto connman = std::make_unique<CConnman>(0x1337, 0x1337, *m_node.addrman);
auto peerLogic = std::make_unique<PeerLogicValidation>( auto peerLogic = std::make_unique<PeerLogicValidation>(
*connman, banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool, m_node.llmq_ctx *connman, *m_node.addrman, banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool, m_node.llmq_ctx
); );
banman->ClearBanned(); banman->ClearBanned();
@ -345,8 +341,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime)
} }
BOOST_CHECK(banman->IsDiscouraged(addr)); BOOST_CHECK(banman->IsDiscouraged(addr));
bool dummy; peerLogic->FinalizeNode(dummyNode);
peerLogic->FinalizeNode(dummyNode, dummy);
} }
static CTransactionRef RandomOrphan() static CTransactionRef RandomOrphan()

View File

@ -23,116 +23,94 @@ void initialize_connman()
FUZZ_TARGET_INIT(connman, initialize_connman) FUZZ_TARGET_INIT(connman, initialize_connman)
{ {
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
CConnman connman{fuzzed_data_provider.ConsumeIntegral<uint64_t>(), fuzzed_data_provider.ConsumeIntegral<uint64_t>()}; CAddrMan addrman;
CAddress random_address; CConnman connman{fuzzed_data_provider.ConsumeIntegral<uint64_t>(), fuzzed_data_provider.ConsumeIntegral<uint64_t>(), addrman};
CNetAddr random_netaddr; CNetAddr random_netaddr;
CNode random_node = ConsumeNode(fuzzed_data_provider); CNode random_node = ConsumeNode(fuzzed_data_provider);
CService random_service;
CSubNet random_subnet; CSubNet random_subnet;
std::string random_string; std::string random_string;
while (fuzzed_data_provider.ConsumeBool()) { while (fuzzed_data_provider.ConsumeBool()) {
switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 28)) { switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 23)) {
case 0: case 0:
random_address = ConsumeAddress(fuzzed_data_provider);
break;
case 1:
random_netaddr = ConsumeNetAddr(fuzzed_data_provider); random_netaddr = ConsumeNetAddr(fuzzed_data_provider);
break; break;
case 2: case 1:
random_service = ConsumeService(fuzzed_data_provider);
break;
case 3:
random_subnet = ConsumeSubNet(fuzzed_data_provider); random_subnet = ConsumeSubNet(fuzzed_data_provider);
break; break;
case 4: case 2:
random_string = fuzzed_data_provider.ConsumeRandomLengthString(64); random_string = fuzzed_data_provider.ConsumeRandomLengthString(64);
break; break;
case 5: { case 3:
std::vector<CAddress> addresses;
while (fuzzed_data_provider.ConsumeBool()) {
addresses.push_back(ConsumeAddress(fuzzed_data_provider));
}
// Limit nTimePenalty to int32_t to avoid signed integer overflow
(void)connman.AddNewAddresses(addresses, ConsumeAddress(fuzzed_data_provider), fuzzed_data_provider.ConsumeIntegral<int32_t>());
break;
}
case 6:
connman.AddNode(random_string); connman.AddNode(random_string);
break; break;
case 7: case 4:
connman.CheckIncomingNonce(fuzzed_data_provider.ConsumeIntegral<uint64_t>()); connman.CheckIncomingNonce(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
break; break;
case 8: case 5:
connman.DisconnectNode(fuzzed_data_provider.ConsumeIntegral<NodeId>()); connman.DisconnectNode(fuzzed_data_provider.ConsumeIntegral<NodeId>());
break; break;
case 9: case 6:
connman.DisconnectNode(random_netaddr); connman.DisconnectNode(random_netaddr);
break; break;
case 10: case 7:
connman.DisconnectNode(random_string); connman.DisconnectNode(random_string);
break; break;
case 11: case 8:
connman.DisconnectNode(random_subnet); connman.DisconnectNode(random_subnet);
break; break;
case 12: case 9:
connman.ForEachNode([](auto) {}); connman.ForEachNode([](auto) {});
break; break;
case 13: case 10:
connman.ForEachNodeThen([](auto) {}, []() {}); connman.ForEachNodeThen([](auto) {}, []() {});
break; break;
case 14: case 11:
(void)connman.ForNode(fuzzed_data_provider.ConsumeIntegral<NodeId>(), [&](auto) { return fuzzed_data_provider.ConsumeBool(); }); (void)connman.ForNode(fuzzed_data_provider.ConsumeIntegral<NodeId>(), [&](auto) { return fuzzed_data_provider.ConsumeBool(); });
break; break;
case 15: case 12:
(void)connman.GetAddresses(); (void)connman.GetAddresses();
break; break;
case 16: { case 13: {
(void)connman.GetAddresses(); (void)connman.GetAddresses();
break; break;
} }
case 17: case 14:
(void)connman.GetDeterministicRandomizer(fuzzed_data_provider.ConsumeIntegral<uint64_t>()); (void)connman.GetDeterministicRandomizer(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
break; break;
case 18: case 15:
(void)connman.GetNodeCount(fuzzed_data_provider.PickValueInArray({CConnman::CONNECTIONS_NONE, CConnman::CONNECTIONS_IN, CConnman::CONNECTIONS_OUT, CConnman::CONNECTIONS_ALL})); (void)connman.GetNodeCount(fuzzed_data_provider.PickValueInArray({CConnman::CONNECTIONS_NONE, CConnman::CONNECTIONS_IN, CConnman::CONNECTIONS_OUT, CConnman::CONNECTIONS_ALL}));
break; break;
case 19: case 16:
connman.MarkAddressGood(random_address);
break;
case 20:
(void)connman.OutboundTargetReached(fuzzed_data_provider.ConsumeBool()); (void)connman.OutboundTargetReached(fuzzed_data_provider.ConsumeBool());
break; break;
case 21: case 17:
// Limit now to int32_t to avoid signed integer overflow // Limit now to int32_t to avoid signed integer overflow
(void)connman.PoissonNextSendInbound(fuzzed_data_provider.ConsumeIntegral<int32_t>(), fuzzed_data_provider.ConsumeIntegral<int>()); (void)connman.PoissonNextSendInbound(fuzzed_data_provider.ConsumeIntegral<int32_t>(), fuzzed_data_provider.ConsumeIntegral<int>());
break; break;
case 22: { case 18: {
CSerializedNetMsg serialized_net_msg; CSerializedNetMsg serialized_net_msg;
serialized_net_msg.command = fuzzed_data_provider.ConsumeRandomLengthString(CMessageHeader::COMMAND_SIZE); serialized_net_msg.command = fuzzed_data_provider.ConsumeRandomLengthString(CMessageHeader::COMMAND_SIZE);
serialized_net_msg.data = ConsumeRandomLengthByteVector(fuzzed_data_provider); serialized_net_msg.data = ConsumeRandomLengthByteVector(fuzzed_data_provider);
connman.PushMessage(&random_node, std::move(serialized_net_msg)); connman.PushMessage(&random_node, std::move(serialized_net_msg));
break; break;
} }
case 23: case 19:
connman.RemoveAddedNode(random_string); connman.RemoveAddedNode(random_string);
break; break;
case 24: { case 20: {
const std::vector<bool> asmap = ConsumeRandomLengthBitVector(fuzzed_data_provider); const std::vector<bool> asmap = ConsumeRandomLengthBitVector(fuzzed_data_provider);
if (SanityCheckASMap(asmap)) { if (SanityCheckASMap(asmap)) {
connman.SetAsmap(asmap); connman.SetAsmap(asmap);
} }
break; break;
} }
case 25: case 21:
connman.SetBestHeight(fuzzed_data_provider.ConsumeIntegral<int>()); connman.SetBestHeight(fuzzed_data_provider.ConsumeIntegral<int>());
break; break;
case 26: case 22:
connman.SetNetworkActive(fuzzed_data_provider.ConsumeBool()); connman.SetNetworkActive(fuzzed_data_provider.ConsumeBool());
break; break;
case 27: case 23:
connman.SetServices(random_service, static_cast<ServiceFlags>(fuzzed_data_provider.ConsumeIntegral<uint64_t>()));
break;
case 28:
connman.SetTryNewOutboundPeer(fuzzed_data_provider.ConsumeBool()); connman.SetTryNewOutboundPeer(fuzzed_data_provider.ConsumeBool());
break; break;
} }

View File

@ -52,7 +52,8 @@ FUZZ_TARGET_INIT(net, initialize_net)
while (fuzzed_data_provider.ConsumeBool()) { while (fuzzed_data_provider.ConsumeBool()) {
switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 12)) { switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 12)) {
case 0: { case 0: {
CConnman connman{fuzzed_data_provider.ConsumeIntegral<uint64_t>(), fuzzed_data_provider.ConsumeIntegral<uint64_t>()}; CAddrMan addrman;
CConnman connman{fuzzed_data_provider.ConsumeIntegral<uint64_t>(), fuzzed_data_provider.ConsumeIntegral<uint64_t>(), addrman};
node.CloseSocketDisconnect(&connman); node.CloseSocketDisconnect(&connman);
break; break;
} }

View File

@ -4,6 +4,7 @@
#include <test/util/setup_common.h> #include <test/util/setup_common.h>
#include <addrman.h>
#include <banman.h> #include <banman.h>
#include <chainparams.h> #include <chainparams.h>
#include <consensus/consensus.h> #include <consensus/consensus.h>
@ -131,11 +132,12 @@ BasicTestingSetup::BasicTestingSetup(const std::string& chainName, const std::ve
SetupNetworking(); SetupNetworking();
InitSignatureCache(); InitSignatureCache();
InitScriptExecutionCache(); InitScriptExecutionCache();
m_node.addrman = std::make_unique<CAddrMan>();
m_node.chain = interfaces::MakeChain(m_node); m_node.chain = interfaces::MakeChain(m_node);
g_wallet_init_interface.Construct(m_node); g_wallet_init_interface.Construct(m_node);
fCheckBlockIndex = true; fCheckBlockIndex = true;
m_node.evodb = std::make_unique<CEvoDB>(1 << 20, true, true); m_node.evodb = std::make_unique<CEvoDB>(1 << 20, true, true);
connman = std::make_unique<CConnman>(0x1337, 0x1337); connman = std::make_unique<CConnman>(0x1337, 0x1337, *m_node.addrman);
deterministicMNManager.reset(new CDeterministicMNManager(*m_node.evodb, *connman)); deterministicMNManager.reset(new CDeterministicMNManager(*m_node.evodb, *connman));
llmq::quorumSnapshotManager.reset(new llmq::CQuorumSnapshotManager(*m_node.evodb)); llmq::quorumSnapshotManager.reset(new llmq::CQuorumSnapshotManager(*m_node.evodb));
static bool noui_connected = false; static bool noui_connected = false;
@ -175,7 +177,7 @@ ChainTestingSetup::ChainTestingSetup(const std::string& chainName, const std::ve
m_node.chainman = &::g_chainman; m_node.chainman = &::g_chainman;
m_node.connman = std::make_unique<CConnman>(0x1337, 0x1337); // Deterministic randomness for tests. m_node.connman = std::make_unique<CConnman>(0x1337, 0x1337, *m_node.addrman); // Deterministic randomness for tests.
::sporkManager = std::make_unique<CSporkManager>(); ::sporkManager = std::make_unique<CSporkManager>();
::governance = std::make_unique<CGovernanceManager>(); ::governance = std::make_unique<CGovernanceManager>();
@ -211,10 +213,11 @@ ChainTestingSetup::~ChainTestingSetup()
::governance.reset(); ::governance.reset();
::sporkManager.reset(); ::sporkManager.reset();
m_node.connman.reset(); m_node.connman.reset();
m_node.addrman.reset();
m_node.args = nullptr;
m_node.banman.reset(); m_node.banman.reset();
UnloadBlockIndex(m_node.mempool.get()); UnloadBlockIndex(m_node.mempool.get());
m_node.mempool.reset(); m_node.mempool.reset();
m_node.args = nullptr;
m_node.scheduler.reset(); m_node.scheduler.reset();
m_node.llmq_ctx.reset(); m_node.llmq_ctx.reset();
m_node.chainman->Reset(); m_node.chainman->Reset();
@ -242,7 +245,7 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector<const
m_node.banman = std::make_unique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME); m_node.banman = std::make_unique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME);
m_node.peer_logic = std::make_unique<PeerLogicValidation>( m_node.peer_logic = std::make_unique<PeerLogicValidation>(
*m_node.connman, m_node.banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool, m_node.llmq_ctx *m_node.connman, *m_node.addrman, m_node.banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool, m_node.llmq_ctx
); );
{ {
CConnman::Options options; CConnman::Options options;