Skip to content

Commit 9f36e59

Browse files
committed
net: move state dependent peer services flags
No behavior change. Just an intermediate refactoring. By relocating the peer desirable services flags into the peer manager, we allow the connections acceptance process to handle post-IBD potential stalling scenarios. In the follow-up commit(s), the desirable service flags will be dynamically adjusted to detect post-IBD stalling scenarios (such as a +48-hour inactive node that must prefer full node connections instead of limited peer connections because they cannot provide historical blocks). Additionally, this encapsulation enable us to customize the connections decision-making process based on new user's configurations in the future.
1 parent f9ac96b commit 9f36e59

File tree

7 files changed

+50
-44
lines changed

7 files changed

+50
-44
lines changed

src/net.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2637,7 +2637,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
26372637
const CAddress addr = m_anchors.back();
26382638
m_anchors.pop_back();
26392639
if (!addr.IsValid() || IsLocal(addr) || !g_reachable_nets.Contains(addr) ||
2640-
!HasAllDesirableServiceFlags(addr.nServices) ||
2640+
!m_msgproc->HasAllDesirableServiceFlags(addr.nServices) ||
26412641
outbound_ipv46_peer_netgroups.count(m_netgroupman.GetGroup(addr))) continue;
26422642
addrConnect = addr;
26432643
LogPrint(BCLog::NET, "Trying to make an anchor connection to %s\n", addrConnect.ToStringAddrPort());
@@ -2703,7 +2703,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
27032703
// for non-feelers, require all the services we'll want,
27042704
// for feelers, only require they be a full node (only because most
27052705
// SPV clients don't have a good address DB available)
2706-
if (!fFeeler && !HasAllDesirableServiceFlags(addr.nServices)) {
2706+
if (!fFeeler && !m_msgproc->HasAllDesirableServiceFlags(addr.nServices)) {
27072707
continue;
27082708
} else if (fFeeler && !MayHaveUsefulAddressDB(addr.nServices)) {
27092709
continue;

src/net.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,6 +1005,12 @@ class NetEventsInterface
10051005
/** Handle removal of a peer (clear state) */
10061006
virtual void FinalizeNode(const CNode& node) = 0;
10071007

1008+
/**
1009+
* Callback to determine whether the given set of service flags are sufficient
1010+
* for a peer to be "relevant".
1011+
*/
1012+
virtual bool HasAllDesirableServiceFlags(ServiceFlags services) const = 0;
1013+
10081014
/**
10091015
* Process protocol messages received from a given node
10101016
*

src/net_processing.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,7 @@ class PeerManagerImpl final : public PeerManager
499499
/** Implement NetEventsInterface */
500500
void InitializeNode(CNode& node, ServiceFlags our_services) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
501501
void FinalizeNode(const CNode& node) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, !m_headers_presync_mutex);
502+
bool HasAllDesirableServiceFlags(ServiceFlags services) const override;
502503
bool ProcessMessages(CNode* pfrom, std::atomic<bool>& interrupt) override
503504
EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, !m_recent_confirmed_transactions_mutex, !m_most_recent_block_mutex, !m_headers_presync_mutex, g_msgproc_mutex);
504505
bool SendMessages(CNode* pto) override
@@ -523,6 +524,7 @@ class PeerManagerImpl final : public PeerManager
523524
const std::chrono::microseconds time_received, const std::atomic<bool>& interruptMsgProc) override
524525
EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, !m_recent_confirmed_transactions_mutex, !m_most_recent_block_mutex, !m_headers_presync_mutex, g_msgproc_mutex);
525526
void UpdateLastBlockAnnounceTime(NodeId node, int64_t time_in_seconds) override;
527+
ServiceFlags GetDesirableServiceFlags(ServiceFlags services) const override;
526528

527529
private:
528530
/** Consider evicting an outbound peer based on the amount of time they've been behind our tip */
@@ -1668,6 +1670,20 @@ void PeerManagerImpl::FinalizeNode(const CNode& node)
16681670
LogPrint(BCLog::NET, "Cleared nodestate for peer=%d\n", nodeid);
16691671
}
16701672

1673+
bool PeerManagerImpl::HasAllDesirableServiceFlags(ServiceFlags services) const
1674+
{
1675+
// Shortcut for (services & GetDesirableServiceFlags(services)) == GetDesirableServiceFlags(services)
1676+
return !(GetDesirableServiceFlags(services) & (~services));
1677+
}
1678+
1679+
ServiceFlags PeerManagerImpl::GetDesirableServiceFlags(ServiceFlags services) const
1680+
{
1681+
if (services & NODE_NETWORK_LIMITED && GetServicesFlagsIBDCache()) {
1682+
return ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS);
1683+
}
1684+
return ServiceFlags(NODE_NETWORK | NODE_WITNESS);
1685+
}
1686+
16711687
PeerRef PeerManagerImpl::GetPeerRef(NodeId id) const
16721688
{
16731689
LOCK(m_peer_mutex);

src/net_processing.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,29 @@ class PeerManager : public CValidationInterface, public NetEventsInterface
110110

111111
/** This function is used for testing the stale tip eviction logic, see denialofservice_tests.cpp */
112112
virtual void UpdateLastBlockAnnounceTime(NodeId node, int64_t time_in_seconds) = 0;
113+
114+
/**
115+
* Gets the set of service flags which are "desirable" for a given peer.
116+
*
117+
* These are the flags which are required for a peer to support for them
118+
* to be "interesting" to us, ie for us to wish to use one of our few
119+
* outbound connection slots for or for us to wish to prioritize keeping
120+
* their connection around.
121+
*
122+
* Relevant service flags may be peer- and state-specific in that the
123+
* version of the peer may determine which flags are required (eg in the
124+
* case of NODE_NETWORK_LIMITED where we seek out NODE_NETWORK peers
125+
* unless they set NODE_NETWORK_LIMITED and we are out of IBD, in which
126+
* case NODE_NETWORK_LIMITED suffices).
127+
*
128+
* Thus, generally, avoid calling with 'services' == NODE_NONE, unless
129+
* state-specific flags must absolutely be avoided. When called with
130+
* 'services' == NODE_NONE, the returned desirable service flags are
131+
* guaranteed to not change dependent on state - ie they are suitable for
132+
* use when describing peers which we know to be desirable, but for which
133+
* we do not have a confirmed set of service flags.
134+
*/
135+
virtual ServiceFlags GetDesirableServiceFlags(ServiceFlags services) const = 0;
113136
};
114137

115138
#endif // BITCOIN_NET_PROCESSING_H

src/protocol.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -125,18 +125,12 @@ bool CMessageHeader::IsCommandValid() const
125125
return true;
126126
}
127127

128-
129-
ServiceFlags GetDesirableServiceFlags(ServiceFlags services) {
130-
if ((services & NODE_NETWORK_LIMITED) && g_initial_block_download_completed) {
131-
return ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS);
132-
}
133-
return ServiceFlags(NODE_NETWORK | NODE_WITNESS);
134-
}
135-
136128
void SetServiceFlagsIBDCache(bool state) {
137129
g_initial_block_download_completed = state;
138130
}
139131

132+
bool GetServicesFlagsIBDCache() { return g_initial_block_download_completed; }
133+
140134
CInv::CInv()
141135
{
142136
type = 0;

src/protocol.h

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -310,29 +310,6 @@ enum ServiceFlags : uint64_t {
310310
*/
311311
std::vector<std::string> serviceFlagsToStr(uint64_t flags);
312312

313-
/**
314-
* Gets the set of service flags which are "desirable" for a given peer.
315-
*
316-
* These are the flags which are required for a peer to support for them
317-
* to be "interesting" to us, ie for us to wish to use one of our few
318-
* outbound connection slots for or for us to wish to prioritize keeping
319-
* their connection around.
320-
*
321-
* Relevant service flags may be peer- and state-specific in that the
322-
* version of the peer may determine which flags are required (eg in the
323-
* case of NODE_NETWORK_LIMITED where we seek out NODE_NETWORK peers
324-
* unless they set NODE_NETWORK_LIMITED and we are out of IBD, in which
325-
* case NODE_NETWORK_LIMITED suffices).
326-
*
327-
* Thus, generally, avoid calling with peerServices == NODE_NONE, unless
328-
* state-specific flags must absolutely be avoided. When called with
329-
* peerServices == NODE_NONE, the returned desirable service flags are
330-
* guaranteed to not change dependent on state - ie they are suitable for
331-
* use when describing peers which we know to be desirable, but for which
332-
* we do not have a confirmed set of service flags.
333-
*/
334-
ServiceFlags GetDesirableServiceFlags(ServiceFlags services);
335-
336313
/**
337314
* State independent service flags.
338315
* If the return value is changed, contrib/seeds/makeseeds.py
@@ -343,16 +320,7 @@ constexpr ServiceFlags SeedsServiceFlags() { return ServiceFlags(NODE_NETWORK |
343320

344321
/** Set the current IBD status in order to figure out the desirable service flags */
345322
void SetServiceFlagsIBDCache(bool status);
346-
347-
/**
348-
* A shortcut for (services & GetDesirableServiceFlags(services))
349-
* == GetDesirableServiceFlags(services), ie determines whether the given
350-
* set of service flags are sufficient for a peer to be "relevant".
351-
*/
352-
static inline bool HasAllDesirableServiceFlags(ServiceFlags services)
353-
{
354-
return !(GetDesirableServiceFlags(services) & (~services));
355-
}
323+
bool GetServicesFlagsIBDCache();
356324

357325
/**
358326
* Checks if a peer with the given service flags may be capable of having a

src/test/fuzz/integer.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,6 @@ FUZZ_TARGET(integer, .init = initialize_integer)
213213

214214
{
215215
const ServiceFlags service_flags = (ServiceFlags)u64;
216-
(void)HasAllDesirableServiceFlags(service_flags);
217216
(void)MayHaveUsefulAddressDB(service_flags);
218217
}
219218

0 commit comments

Comments
 (0)