MCPcopy Create free account
hub / github.com/bitcoin/bitcoin / SelectNodeToEvict

Function SelectNodeToEvict

src/node/eviction.cpp:178–240  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

176}
177
178[[nodiscard]] std::optional<NodeId> SelectNodeToEvict(std::vector<NodeEvictionCandidate>&& vEvictionCandidates)
179{
180 // Protect connections with certain characteristics
181
182 ProtectNoBanConnections(vEvictionCandidates);
183
184 ProtectOutboundConnections(vEvictionCandidates);
185
186 // Deterministically select 4 peers to protect by netgroup.
187 // An attacker cannot predict which netgroups will be protected
188 EraseLastKElements(vEvictionCandidates, CompareNetGroupKeyed, 4);
189 // Protect the 8 nodes with the lowest minimum ping time.
190 // An attacker cannot manipulate this metric without physically moving nodes closer to the target.
191 EraseLastKElements(vEvictionCandidates, ReverseCompareNodeMinPingTime, 8);
192 // Protect 4 nodes that most recently sent us novel transactions accepted into our mempool.
193 // An attacker cannot manipulate this metric without performing useful work.
194 EraseLastKElements(vEvictionCandidates, CompareNodeTXTime, 4);
195 // Protect up to 8 non-tx-relay peers that have sent us novel blocks.
196 EraseLastKElements(vEvictionCandidates, CompareNodeBlockRelayOnlyTime, 8,
197 [](const NodeEvictionCandidate& n) { return !n.m_relay_txs && n.fRelevantServices; });
198
199 // Protect 4 nodes that most recently sent us novel blocks.
200 // An attacker cannot manipulate this metric without performing useful work.
201 EraseLastKElements(vEvictionCandidates, CompareNodeBlockTime, 4);
202
203 // Protect some of the remaining eviction candidates by ratios of desirable
204 // or disadvantaged characteristics.
205 ProtectEvictionCandidatesByRatio(vEvictionCandidates);
206
207 if (vEvictionCandidates.empty()) return std::nullopt;
208
209 // If any remaining peers are preferred for eviction consider only them.
210 // This happens after the other preferences since if a peer is really the best by other criteria (esp relaying blocks)
211 // then we probably don't want to evict it no matter what.
212 if (std::any_of(vEvictionCandidates.begin(),vEvictionCandidates.end(),[](NodeEvictionCandidate const &n){return n.prefer_evict;})) {
213 vEvictionCandidates.erase(std::remove_if(vEvictionCandidates.begin(),vEvictionCandidates.end(),
214 [](NodeEvictionCandidate const &n){return !n.prefer_evict;}),vEvictionCandidates.end());
215 }
216
217 // Identify the network group with the most connections and youngest member.
218 // (vEvictionCandidates is already sorted by reverse connect time)
219 uint64_t naMostConnections;
220 unsigned int nMostConnections = 0;
221 NodeClock::time_point nMostConnectionsTime{NodeClock::epoch};
222 std::map<uint64_t, std::vector<NodeEvictionCandidate> > mapNetGroupNodes;
223 for (const NodeEvictionCandidate &node : vEvictionCandidates) {
224 std::vector<NodeEvictionCandidate> &group = mapNetGroupNodes[node.nKeyedNetGroup];
225 group.push_back(node);
226 const auto grouptime{group[0].m_connected};
227
228 if (group.size() > nMostConnections || (group.size() == nMostConnections && grouptime > nMostConnectionsTime)) {
229 nMostConnections = group.size();
230 nMostConnectionsTime = grouptime;
231 naMostConnections = node.nKeyedNetGroup;
232 }
233 }
234
235 // Reduce to the network group with the most connections

Callers 4

IsEvictedFunction · 0.85
BOOST_AUTO_TEST_CASEFunction · 0.85
FUZZ_TARGETFunction · 0.85

Calls 12

ProtectNoBanConnectionsFunction · 0.85
EraseLastKElementsFunction · 0.85
any_ofClass · 0.85
emptyMethod · 0.45
beginMethod · 0.45
endMethod · 0.45
eraseMethod · 0.45
push_backMethod · 0.45
sizeMethod · 0.45
frontMethod · 0.45

Tested by 3

IsEvictedFunction · 0.68
BOOST_AUTO_TEST_CASEFunction · 0.68
FUZZ_TARGETFunction · 0.68