mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-03-12 00:26:03 +01:00
Replace relevant services logic with a function suite.
Adds HasAllRelevantServices and GetRelevantServices, which check for NETWORK|WITNESS. This changes the following: * Removes nRelevantServices from CConnman, disconnecting it a bit more from protocol-level logic. * Replaces our sometimes-connect-to-!WITNESS-nodes logic with simply always requiring WITNESS|NETWORK for outbound non-feeler connections (feelers still only require NETWORK). * This has the added benefit of removing nServicesExpected from CNode - instead letting net_processing's VERSION message handling simply check HasAllRelevantServices. * This implies we believe WITNESS nodes to continue to be a significant majority of nodes on the network, but also because we cannot sync properly from !WITNESS nodes, it is strange to continue using our valuable outbound slots on them. * In order to prevent this change from preventing connection to -connect= nodes which have !WITNESS, -connect nodes are now given the "addnode" flag. This also allows outbound connections to !NODE_NETWORK nodes for -connect nodes (which was already true of addnodes). * Has the (somewhat unintended) consequence of changing one of the eviction metrics from the same sometimes-connect-to-!WITNESS-nodes metric to requiring HasRelevantServices. This should make NODE_NETWORK_LIMITED much simpler to implement.
This commit is contained in:
40
src/net.cpp
40
src/net.cpp
@@ -444,7 +444,6 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
|
||||
uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize();
|
||||
CAddress addr_bind = GetBindAddress(hSocket);
|
||||
CNode* pnode = new CNode(id, nLocalServices, GetBestHeight(), hSocket, addrConnect, CalculateKeyedNetGroup(addrConnect), nonce, addr_bind, pszDest ? pszDest : "", false);
|
||||
pnode->nServicesExpected = ServiceFlags(addrConnect.nServices & nRelevantServices);
|
||||
pnode->AddRef();
|
||||
|
||||
return pnode;
|
||||
@@ -985,7 +984,7 @@ bool CConnman::AttemptToEvictConnection()
|
||||
continue;
|
||||
NodeEvictionCandidate candidate = {node->GetId(), node->nTimeConnected, node->nMinPingUsecTime,
|
||||
node->nLastBlockTime, node->nLastTXTime,
|
||||
(node->nServices & nRelevantServices) == nRelevantServices,
|
||||
HasAllDesirableServiceFlags(node->nServices),
|
||||
node->fRelayTxes, node->pfilter != nullptr, node->addr, node->nKeyedNetGroup};
|
||||
vEvictionCandidates.push_back(candidate);
|
||||
}
|
||||
@@ -1602,7 +1601,7 @@ void CConnman::ThreadDNSAddressSeed()
|
||||
LOCK(cs_vNodes);
|
||||
int nRelevant = 0;
|
||||
for (auto pnode : vNodes) {
|
||||
nRelevant += pnode->fSuccessfullyConnected && ((pnode->nServices & nRelevantServices) == nRelevantServices);
|
||||
nRelevant += pnode->fSuccessfullyConnected && HasAllDesirableServiceFlags(pnode->nServices);
|
||||
}
|
||||
if (nRelevant >= 2) {
|
||||
LogPrintf("P2P peers available. Skipped DNS seeding.\n");
|
||||
@@ -1624,7 +1623,7 @@ void CConnman::ThreadDNSAddressSeed()
|
||||
} else {
|
||||
std::vector<CNetAddr> vIPs;
|
||||
std::vector<CAddress> vAdd;
|
||||
ServiceFlags requiredServiceBits = nRelevantServices;
|
||||
ServiceFlags requiredServiceBits = GetDesirableServiceFlags(NODE_NONE);
|
||||
std::string host = GetDNSHost(seed, &requiredServiceBits);
|
||||
CNetAddr resolveSource;
|
||||
if (!resolveSource.SetInternal(host)) {
|
||||
@@ -1705,7 +1704,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
|
||||
for (const std::string& strAddr : connect)
|
||||
{
|
||||
CAddress addr(CService(), NODE_NONE);
|
||||
OpenNetworkConnection(addr, false, nullptr, strAddr.c_str());
|
||||
OpenNetworkConnection(addr, false, nullptr, strAddr.c_str(), false, false, true);
|
||||
for (int i = 0; i < 10 && i < nLoop; i++)
|
||||
{
|
||||
if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
|
||||
@@ -1753,17 +1752,11 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
|
||||
// Only connect out to one peer per network group (/16 for IPv4).
|
||||
// Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
|
||||
int nOutbound = 0;
|
||||
int nOutboundRelevant = 0;
|
||||
std::set<std::vector<unsigned char> > setConnected;
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
for (CNode* pnode : vNodes) {
|
||||
if (!pnode->fInbound && !pnode->fAddnode) {
|
||||
|
||||
// Count the peers that have all relevant services
|
||||
if (pnode->fSuccessfullyConnected && !pnode->fFeeler && ((pnode->nServices & nRelevantServices) == nRelevantServices)) {
|
||||
nOutboundRelevant++;
|
||||
}
|
||||
// Netgroups for inbound and addnode peers are not excluded because our goal here
|
||||
// is to not use multiple of our limited outbound slots on a single netgroup
|
||||
// but inbound and addnode peers do not use our outbound slots. Inbound peers
|
||||
@@ -1818,21 +1811,16 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
|
||||
if (IsLimited(addr))
|
||||
continue;
|
||||
|
||||
// only connect to full nodes
|
||||
if ((addr.nServices & REQUIRED_SERVICES) != REQUIRED_SERVICES)
|
||||
continue;
|
||||
|
||||
// only consider very recently tried nodes after 30 failed attempts
|
||||
if (nANow - addr.nLastTry < 600 && nTries < 30)
|
||||
continue;
|
||||
|
||||
// only consider nodes missing relevant services after 40 failed attempts and only if less than half the outbound are up.
|
||||
ServiceFlags nRequiredServices = nRelevantServices;
|
||||
if (nTries >= 40 && nOutbound < (nMaxOutbound >> 1)) {
|
||||
nRequiredServices = REQUIRED_SERVICES;
|
||||
}
|
||||
|
||||
if ((addr.nServices & nRequiredServices) != nRequiredServices) {
|
||||
// for non-feelers, require all the services we'll want,
|
||||
// for feelers, only require they be a full node (only because most
|
||||
// SPV clients don't have a good address DB available)
|
||||
if (!fFeeler && !HasAllDesirableServiceFlags(addr.nServices)) {
|
||||
continue;
|
||||
} else if (fFeeler && !MayHaveUsefulAddressDB(addr.nServices)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1841,13 +1829,6 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
|
||||
continue;
|
||||
|
||||
addrConnect = addr;
|
||||
|
||||
// regardless of the services assumed to be available, only require the minimum if half or more outbound have relevant services
|
||||
if (nOutboundRelevant >= (nMaxOutbound >> 1)) {
|
||||
addrConnect.nServices = REQUIRED_SERVICES;
|
||||
} else {
|
||||
addrConnect.nServices = nRequiredServices;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2712,7 +2693,6 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn
|
||||
nSendVersion(0)
|
||||
{
|
||||
nServices = NODE_NONE;
|
||||
nServicesExpected = NODE_NONE;
|
||||
hSocket = hSocketIn;
|
||||
nRecvVersion = INIT_PROTO_VERSION;
|
||||
nLastSend = 0;
|
||||
|
||||
Reference in New Issue
Block a user