Skip to content

Commit 8e09f91

Browse files
committed
Decide eviction group ties based on time.
This corrects a bug the case of tying group size where the code may fail to select the group with the newest member. Since newest time is the final selection criteria, failing to break ties on it on the step before can undermine the final selection. Tied netgroups are very common.
1 parent 46dbcd4 commit 8e09f91

File tree

1 file changed

+10
-6
lines changed

1 file changed

+10
-6
lines changed

src/net.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -914,30 +914,34 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) {
914914

915915
if (vEvictionCandidates.empty()) return false;
916916

917-
// Identify the network group with the most connections
917+
// Identify the network group with the most connections and youngest member.
918+
// (vEvictionCandidates is already sorted by reverse connect time)
918919
std::vector<unsigned char> naMostConnections;
919920
unsigned int nMostConnections = 0;
921+
int64_t nMostConnectionsTime = 0;
920922
std::map<std::vector<unsigned char>, std::vector<CNodeRef> > mapAddrCounts;
921923
BOOST_FOREACH(const CNodeRef &node, vEvictionCandidates) {
922924
mapAddrCounts[node->addr.GetGroup()].push_back(node);
925+
int64_t grouptime = mapAddrCounts[node->addr.GetGroup()][0]->nTimeConnected;
926+
size_t groupsize = mapAddrCounts[node->addr.GetGroup()].size();
923927

924-
if (mapAddrCounts[node->addr.GetGroup()].size() > nMostConnections) {
925-
nMostConnections = mapAddrCounts[node->addr.GetGroup()].size();
928+
if (groupsize > nMostConnections || (groupsize == nMostConnections && grouptime > nMostConnectionsTime)) {
929+
nMostConnections = groupsize;
930+
nMostConnectionsTime = grouptime;
926931
naMostConnections = node->addr.GetGroup();
927932
}
928933
}
929934

930935
// Reduce to the network group with the most connections
931936
vEvictionCandidates = mapAddrCounts[naMostConnections];
932937

933-
// Do not disconnect peers if there is only 1 connection from their network group
938+
// Do not disconnect peers if there is only one unprotected connection from their network group.
934939
if (vEvictionCandidates.size() <= 1)
935940
// unless we prefer the new connection (for whitelisted peers)
936941
if (!fPreferNewConnection)
937942
return false;
938943

939-
// Disconnect the most recent connection from the network group with the most connections
940-
std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeTimeConnected);
944+
// Disconnect from the network group with the most connections
941945
vEvictionCandidates[0]->fDisconnect = true;
942946

943947
return true;

0 commit comments

Comments
 (0)