@@ -870,13 +870,15 @@ static bool CompareNodeBlockRelayOnlyTime(const NodeEvictionCandidate &a, const
870
870
return a.nTimeConnected > b.nTimeConnected ;
871
871
}
872
872
873
- // ! Sort an array by the specified comparator, then erase the last K elements.
874
- template <typename T, typename Comparator>
875
- static void EraseLastKElements (std::vector<T> &elements, Comparator comparator, size_t k)
873
+ // ! Sort an array by the specified comparator, then erase the last K elements where predicate is true.
874
+ template <typename T, typename Comparator>
875
+ static void EraseLastKElements (
876
+ std::vector<T>& elements, Comparator comparator, size_t k,
877
+ std::function<bool (const NodeEvictionCandidate&)> predicate = [](const NodeEvictionCandidate& n) { return true ; })
876
878
{
877
879
std::sort (elements.begin (), elements.end (), comparator);
878
880
size_t eraseSize = std::min (k, elements.size ());
879
- elements.erase (elements.end () - eraseSize, elements.end ());
881
+ elements.erase (std::remove_if ( elements.end () - eraseSize, elements. end (), predicate) , elements.end ());
880
882
}
881
883
882
884
void ProtectEvictionCandidatesByRatio (std::vector<NodeEvictionCandidate>& vEvictionCandidates)
@@ -886,13 +888,14 @@ void ProtectEvictionCandidatesByRatio(std::vector<NodeEvictionCandidate>& vEvict
886
888
// Reserve half of these protected spots for localhost peers, even if
887
889
// they're not longest-uptime overall. This helps protect tor peers, which
888
890
// tend to be otherwise disadvantaged under our eviction criteria.
889
- size_t initial_size = vEvictionCandidates.size ();
891
+ const size_t initial_size = vEvictionCandidates.size ();
890
892
size_t total_protect_size = initial_size / 2 ;
891
893
892
894
// Pick out up to 1/4 peers that are localhost, sorted by longest uptime.
893
- std::sort (vEvictionCandidates.begin (), vEvictionCandidates.end (), CompareLocalHostTimeConnected);
894
- size_t local_erase_size = total_protect_size / 2 ;
895
- vEvictionCandidates.erase (std::remove_if (vEvictionCandidates.end () - local_erase_size, vEvictionCandidates.end (), [](NodeEvictionCandidate const &n) { return n.m_is_local ; }), vEvictionCandidates.end ());
895
+ const size_t local_erase_size = total_protect_size / 2 ;
896
+ EraseLastKElements (vEvictionCandidates, CompareLocalHostTimeConnected, local_erase_size,
897
+ [](const NodeEvictionCandidate& n) { return n.m_is_local ; });
898
+
896
899
// Calculate how many we removed, and update our total number of peers that
897
900
// we want to protect based on uptime accordingly.
898
901
total_protect_size -= initial_size - vEvictionCandidates.size ();
@@ -913,9 +916,9 @@ void ProtectEvictionCandidatesByRatio(std::vector<NodeEvictionCandidate>& vEvict
913
916
// An attacker cannot manipulate this metric without performing useful work.
914
917
EraseLastKElements (vEvictionCandidates, CompareNodeTXTime, 4 );
915
918
// Protect up to 8 non-tx-relay peers that have sent us novel blocks.
916
- std::sort (vEvictionCandidates. begin ( ), vEvictionCandidates.end (), CompareNodeBlockRelayOnlyTime );
917
- size_t erase_size = std::min ( size_t ( 8 ), vEvictionCandidates. size ());
918
- vEvictionCandidates. erase ( std::remove_if (vEvictionCandidates. end () - erase_size, vEvictionCandidates. end (), [](NodeEvictionCandidate const & n) { return !n.fRelayTxes && n.fRelevantServices ; }), vEvictionCandidates. end () );
919
+ const size_t erase_size = std::min ( size_t ( 8 ), vEvictionCandidates.size () );
920
+ EraseLastKElements (vEvictionCandidates, CompareNodeBlockRelayOnlyTime, erase_size,
921
+ [](const NodeEvictionCandidate& n) { return !n.fRelayTxes && n.fRelevantServices ; });
919
922
920
923
// Protect 4 nodes that most recently sent us novel blocks.
921
924
// An attacker cannot manipulate this metric without performing useful work.
@@ -944,7 +947,7 @@ void ProtectEvictionCandidatesByRatio(std::vector<NodeEvictionCandidate>& vEvict
944
947
for (const NodeEvictionCandidate &node : vEvictionCandidates) {
945
948
std::vector<NodeEvictionCandidate> &group = mapNetGroupNodes[node.nKeyedNetGroup ];
946
949
group.push_back (node);
947
- int64_t grouptime = group[0 ].nTimeConnected ;
950
+ const int64_t grouptime = group[0 ].nTimeConnected ;
948
951
949
952
if (group.size () > nMostConnections || (group.size () == nMostConnections && grouptime > nMostConnectionsTime)) {
950
953
nMostConnections = group.size ();
0 commit comments