MCPcopy Create free account
hub / github.com/ElementsProject/elements / SelectNodeToEvict

Function SelectNodeToEvict

src/net.cpp:1034–1092  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1032}
1033
1034[[nodiscard]] std::optional<NodeId> SelectNodeToEvict(std::vector<NodeEvictionCandidate>&& vEvictionCandidates)
1035{
1036 // Protect connections with certain characteristics
1037
1038 // Deterministically select 4 peers to protect by netgroup.
1039 // An attacker cannot predict which netgroups will be protected
1040 EraseLastKElements(vEvictionCandidates, CompareNetGroupKeyed, 4);
1041 // Protect the 8 nodes with the lowest minimum ping time.
1042 // An attacker cannot manipulate this metric without physically moving nodes closer to the target.
1043 EraseLastKElements(vEvictionCandidates, ReverseCompareNodeMinPingTime, 8);
1044 // Protect 4 nodes that most recently sent us novel transactions accepted into our mempool.
1045 // An attacker cannot manipulate this metric without performing useful work.
1046 EraseLastKElements(vEvictionCandidates, CompareNodeTXTime, 4);
1047 // Protect up to 8 non-tx-relay peers that have sent us novel blocks.
1048 EraseLastKElements(vEvictionCandidates, CompareNodeBlockRelayOnlyTime, 8,
1049 [](const NodeEvictionCandidate& n) { return !n.fRelayTxes && n.fRelevantServices; });
1050
1051 // Protect 4 nodes that most recently sent us novel blocks.
1052 // An attacker cannot manipulate this metric without performing useful work.
1053 EraseLastKElements(vEvictionCandidates, CompareNodeBlockTime, 4);
1054
1055 // Protect some of the remaining eviction candidates by ratios of desirable
1056 // or disadvantaged characteristics.
1057 ProtectEvictionCandidatesByRatio(vEvictionCandidates);
1058
1059 if (vEvictionCandidates.empty()) return std::nullopt;
1060
1061 // If any remaining peers are preferred for eviction consider only them.
1062 // This happens after the other preferences since if a peer is really the best by other criteria (esp relaying blocks)
1063 // then we probably don't want to evict it no matter what.
1064 if (std::any_of(vEvictionCandidates.begin(),vEvictionCandidates.end(),[](NodeEvictionCandidate const &n){return n.prefer_evict;})) {
1065 vEvictionCandidates.erase(std::remove_if(vEvictionCandidates.begin(),vEvictionCandidates.end(),
1066 [](NodeEvictionCandidate const &n){return !n.prefer_evict;}),vEvictionCandidates.end());
1067 }
1068
1069 // Identify the network group with the most connections and youngest member.
1070 // (vEvictionCandidates is already sorted by reverse connect time)
1071 uint64_t naMostConnections;
1072 unsigned int nMostConnections = 0;
1073 std::chrono::seconds nMostConnectionsTime{0};
1074 std::map<uint64_t, std::vector<NodeEvictionCandidate> > mapNetGroupNodes;
1075 for (const NodeEvictionCandidate &node : vEvictionCandidates) {
1076 std::vector<NodeEvictionCandidate> &group = mapNetGroupNodes[node.nKeyedNetGroup];
1077 group.push_back(node);
1078 const auto grouptime{group[0].m_connected};
1079
1080 if (group.size() > nMostConnections || (group.size() == nMostConnections && grouptime > nMostConnectionsTime)) {
1081 nMostConnections = group.size();
1082 nMostConnectionsTime = grouptime;
1083 naMostConnections = node.nKeyedNetGroup;
1084 }
1085 }
1086
1087 // Reduce to the network group with the most connections
1088 vEvictionCandidates = std::move(mapNetGroupNodes[naMostConnections]);
1089
1090 // Disconnect from the network group with the most connections
1091 return vEvictionCandidates.front().id;

Callers 4

IsEvictedFunction · 0.85
BOOST_AUTO_TEST_CASEFunction · 0.85
FUZZ_TARGETFunction · 0.85

Calls 8

EraseLastKElementsFunction · 0.85
emptyMethod · 0.45
beginMethod · 0.45
endMethod · 0.45
eraseMethod · 0.45
push_backMethod · 0.45
sizeMethod · 0.45

Tested by 3

IsEvictedFunction · 0.68
BOOST_AUTO_TEST_CASEFunction · 0.68
FUZZ_TARGETFunction · 0.68