Bitcoin Core  22.99.0
P2P Digital Currency
net_peer_eviction_tests.cpp
Go to the documentation of this file.
1 // Copyright (c) 2021 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <netaddress.h>
6 #include <net.h>
7 #include <test/util/net.h>
9 
10 #include <boost/test/unit_test.hpp>
11 
12 #include <algorithm>
13 #include <functional>
14 #include <optional>
15 #include <unordered_set>
16 #include <vector>
17 
18 BOOST_FIXTURE_TEST_SUITE(net_peer_eviction_tests, BasicTestingSetup)
19 
20 // Create `num_peers` random nodes, apply setup function `candidate_setup_fn`,
21 // call ProtectEvictionCandidatesByRatio() to apply protection logic, and then
22 // return true if all of `protected_peer_ids` and none of `unprotected_peer_ids`
23 // are protected from eviction, i.e. removed from the eviction candidates.
24 bool IsProtected(int num_peers,
25  std::function<void(NodeEvictionCandidate&)> candidate_setup_fn,
26  const std::unordered_set<NodeId>& protected_peer_ids,
27  const std::unordered_set<NodeId>& unprotected_peer_ids,
28  FastRandomContext& random_context)
29 {
30  std::vector<NodeEvictionCandidate> candidates{GetRandomNodeEvictionCandidates(num_peers, random_context)};
31  for (NodeEvictionCandidate& candidate : candidates) {
32  candidate_setup_fn(candidate);
33  }
34  Shuffle(candidates.begin(), candidates.end(), random_context);
35 
36  const size_t size{candidates.size()};
37  const size_t expected{size - size / 2}; // Expect half the candidates will be protected.
39  BOOST_CHECK_EQUAL(candidates.size(), expected);
40 
41  size_t unprotected_count{0};
42  for (const NodeEvictionCandidate& candidate : candidates) {
43  if (protected_peer_ids.count(candidate.id)) {
44  // this peer should have been removed from the eviction candidates
45  BOOST_TEST_MESSAGE(strprintf("expected candidate to be protected: %d", candidate.id));
46  return false;
47  }
48  if (unprotected_peer_ids.count(candidate.id)) {
49  // this peer remains in the eviction candidates, as expected
50  ++unprotected_count;
51  }
52  }
53 
54  const bool is_protected{unprotected_count == unprotected_peer_ids.size()};
55  if (!is_protected) {
56  BOOST_TEST_MESSAGE(strprintf("unprotected: expected %d, actual %d",
57  unprotected_peer_ids.size(), unprotected_count));
58  }
59  return is_protected;
60 }
61 
62 BOOST_AUTO_TEST_CASE(peer_protection_test)
63 {
64  FastRandomContext random_context{true};
65  int num_peers{12};
66 
67  // Expect half of the peers with greatest uptime (the lowest nTimeConnected)
68  // to be protected from eviction.
70  num_peers, [](NodeEvictionCandidate& c) {
71  c.nTimeConnected = c.id;
72  c.m_is_local = false;
73  c.m_network = NET_IPV4;
74  },
75  /* protected_peer_ids */ {0, 1, 2, 3, 4, 5},
76  /* unprotected_peer_ids */ {6, 7, 8, 9, 10, 11},
77  random_context));
78 
79  // Verify in the opposite direction.
81  num_peers, [num_peers](NodeEvictionCandidate& c) {
82  c.nTimeConnected = num_peers - c.id;
83  c.m_is_local = false;
84  c.m_network = NET_IPV6;
85  },
86  /* protected_peer_ids */ {6, 7, 8, 9, 10, 11},
87  /* unprotected_peer_ids */ {0, 1, 2, 3, 4, 5},
88  random_context));
89 
90  // Test protection of onion, localhost, and I2P peers...
91 
92  // Expect 1/4 onion peers to be protected from eviction,
93  // if no localhost or I2P peers.
95  num_peers, [](NodeEvictionCandidate& c) {
96  c.m_is_local = false;
97  c.m_network = (c.id == 3 || c.id == 8 || c.id == 9) ? NET_ONION : NET_IPV4;
98  },
99  /* protected_peer_ids */ {3, 8, 9},
100  /* unprotected_peer_ids */ {},
101  random_context));
102 
103  // Expect 1/4 onion peers and 1/4 of the other peers to be protected,
104  // sorted by longest uptime (lowest nTimeConnected), if no localhost or I2P peers.
106  num_peers, [](NodeEvictionCandidate& c) {
107  c.nTimeConnected = c.id;
108  c.m_is_local = false;
109  c.m_network = (c.id == 3 || c.id > 7) ? NET_ONION : NET_IPV6;
110  },
111  /* protected_peer_ids */ {0, 1, 2, 3, 8, 9},
112  /* unprotected_peer_ids */ {4, 5, 6, 7, 10, 11},
113  random_context));
114 
115  // Expect 1/4 localhost peers to be protected from eviction,
116  // if no onion or I2P peers.
118  num_peers, [](NodeEvictionCandidate& c) {
119  c.m_is_local = (c.id == 1 || c.id == 9 || c.id == 11);
120  c.m_network = NET_IPV4;
121  },
122  /* protected_peer_ids */ {1, 9, 11},
123  /* unprotected_peer_ids */ {},
124  random_context));
125 
126  // Expect 1/4 localhost peers and 1/4 of the other peers to be protected,
127  // sorted by longest uptime (lowest nTimeConnected), if no onion or I2P peers.
129  num_peers, [](NodeEvictionCandidate& c) {
130  c.nTimeConnected = c.id;
131  c.m_is_local = (c.id > 6);
132  c.m_network = NET_IPV6;
133  },
134  /* protected_peer_ids */ {0, 1, 2, 7, 8, 9},
135  /* unprotected_peer_ids */ {3, 4, 5, 6, 10, 11},
136  random_context));
137 
138  // Expect 1/4 I2P peers to be protected from eviction,
139  // if no onion or localhost peers.
141  num_peers, [](NodeEvictionCandidate& c) {
142  c.m_is_local = false;
143  c.m_network = (c.id == 2 || c.id == 7 || c.id == 10) ? NET_I2P : NET_IPV4;
144  },
145  /* protected_peer_ids */ {2, 7, 10},
146  /* unprotected_peer_ids */ {},
147  random_context));
148 
149  // Expect 1/4 I2P peers and 1/4 of the other peers to be protected,
150  // sorted by longest uptime (lowest nTimeConnected), if no onion or localhost peers.
152  num_peers, [](NodeEvictionCandidate& c) {
153  c.nTimeConnected = c.id;
154  c.m_is_local = false;
155  c.m_network = (c.id == 4 || c.id > 8) ? NET_I2P : NET_IPV6;
156  },
157  /* protected_peer_ids */ {0, 1, 2, 4, 9, 10},
158  /* unprotected_peer_ids */ {3, 5, 6, 7, 8, 11},
159  random_context));
160 
161  // Tests with 2 networks...
162 
163  // Combined test: expect having 1 localhost and 1 onion peer out of 4 to
164  // protect 1 localhost, 0 onion and 1 other peer, sorted by longest uptime;
165  // stable sort breaks tie with array order of localhost first.
167  4, [](NodeEvictionCandidate& c) {
168  c.nTimeConnected = c.id;
169  c.m_is_local = (c.id == 4);
170  c.m_network = (c.id == 3) ? NET_ONION : NET_IPV4;
171  },
172  /* protected_peer_ids */ {0, 4},
173  /* unprotected_peer_ids */ {1, 2},
174  random_context));
175 
176  // Combined test: expect having 1 localhost and 1 onion peer out of 7 to
177  // protect 1 localhost, 0 onion, and 2 other peers (3 total), sorted by
178  // uptime; stable sort breaks tie with array order of localhost first.
180  7, [](NodeEvictionCandidate& c) {
181  c.nTimeConnected = c.id;
182  c.m_is_local = (c.id == 6);
183  c.m_network = (c.id == 5) ? NET_ONION : NET_IPV4;
184  },
185  /* protected_peer_ids */ {0, 1, 6},
186  /* unprotected_peer_ids */ {2, 3, 4, 5},
187  random_context));
188 
189  // Combined test: expect having 1 localhost and 1 onion peer out of 8 to
190  // protect protect 1 localhost, 1 onion and 2 other peers (4 total), sorted
191  // by uptime; stable sort breaks tie with array order of localhost first.
193  8, [](NodeEvictionCandidate& c) {
194  c.nTimeConnected = c.id;
195  c.m_is_local = (c.id == 6);
196  c.m_network = (c.id == 5) ? NET_ONION : NET_IPV4;
197  },
198  /* protected_peer_ids */ {0, 1, 5, 6},
199  /* unprotected_peer_ids */ {2, 3, 4, 7},
200  random_context));
201 
202  // Combined test: expect having 3 localhost and 3 onion peers out of 12 to
203  // protect 2 localhost and 1 onion, plus 3 other peers, sorted by longest
204  // uptime; stable sort breaks ties with the array order of localhost first.
206  num_peers, [](NodeEvictionCandidate& c) {
207  c.nTimeConnected = c.id;
208  c.m_is_local = (c.id == 6 || c.id == 9 || c.id == 11);
209  c.m_network = (c.id == 7 || c.id == 8 || c.id == 10) ? NET_ONION : NET_IPV6;
210  },
211  /* protected_peer_ids */ {0, 1, 2, 6, 7, 9},
212  /* unprotected_peer_ids */ {3, 4, 5, 8, 10, 11},
213  random_context));
214 
215  // Combined test: expect having 4 localhost and 1 onion peer out of 12 to
216  // protect 2 localhost and 1 onion, plus 3 other peers, sorted by longest uptime.
218  num_peers, [](NodeEvictionCandidate& c) {
219  c.nTimeConnected = c.id;
220  c.m_is_local = (c.id > 4 && c.id < 9);
221  c.m_network = (c.id == 10) ? NET_ONION : NET_IPV4;
222  },
223  /* protected_peer_ids */ {0, 1, 2, 5, 6, 10},
224  /* unprotected_peer_ids */ {3, 4, 7, 8, 9, 11},
225  random_context));
226 
227  // Combined test: expect having 4 localhost and 2 onion peers out of 16 to
228  // protect 2 localhost and 2 onions, plus 4 other peers, sorted by longest uptime.
230  16, [](NodeEvictionCandidate& c) {
231  c.nTimeConnected = c.id;
232  c.m_is_local = (c.id == 6 || c.id == 9 || c.id == 11 || c.id == 12);
233  c.m_network = (c.id == 8 || c.id == 10) ? NET_ONION : NET_IPV6;
234  },
235  /* protected_peer_ids */ {0, 1, 2, 3, 6, 8, 9, 10},
236  /* unprotected_peer_ids */ {4, 5, 7, 11, 12, 13, 14, 15},
237  random_context));
238 
239  // Combined test: expect having 5 localhost and 1 onion peer out of 16 to
240  // protect 3 localhost (recovering the unused onion slot), 1 onion, and 4
241  // others, sorted by longest uptime.
243  16, [](NodeEvictionCandidate& c) {
244  c.nTimeConnected = c.id;
245  c.m_is_local = (c.id > 10);
246  c.m_network = (c.id == 10) ? NET_ONION : NET_IPV4;
247  },
248  /* protected_peer_ids */ {0, 1, 2, 3, 10, 11, 12, 13},
249  /* unprotected_peer_ids */ {4, 5, 6, 7, 8, 9, 14, 15},
250  random_context));
251 
252  // Combined test: expect having 1 localhost and 4 onion peers out of 16 to
253  // protect 1 localhost and 3 onions (recovering the unused localhost slot),
254  // plus 4 others, sorted by longest uptime.
256  16, [](NodeEvictionCandidate& c) {
257  c.nTimeConnected = c.id;
258  c.m_is_local = (c.id == 15);
259  c.m_network = (c.id > 6 && c.id < 11) ? NET_ONION : NET_IPV6;
260  },
261  /* protected_peer_ids */ {0, 1, 2, 3, 7, 8, 9, 15},
262  /* unprotected_peer_ids */ {5, 6, 10, 11, 12, 13, 14},
263  random_context));
264 
265  // Combined test: expect having 2 onion and 4 I2P out of 12 peers to protect
266  // 2 onion (prioritized for having fewer candidates) and 1 I2P, plus 3
267  // others, sorted by longest uptime.
269  num_peers, [](NodeEvictionCandidate& c) {
270  c.nTimeConnected = c.id;
271  c.m_is_local = false;
272  if (c.id == 8 || c.id == 10) {
273  c.m_network = NET_ONION;
274  } else if (c.id == 6 || c.id == 9 || c.id == 11 || c.id == 12) {
275  c.m_network = NET_I2P;
276  } else {
277  c.m_network = NET_IPV4;
278  }
279  },
280  /* protected_peer_ids */ {0, 1, 2, 6, 8, 10},
281  /* unprotected_peer_ids */ {3, 4, 5, 7, 9, 11},
282  random_context));
283 
284  // Tests with 3 networks...
285 
286  // Combined test: expect having 1 localhost, 1 I2P and 1 onion peer out of 4
287  // to protect 1 I2P, 0 localhost, 0 onion and 1 other peer (2 total), sorted
288  // by longest uptime; stable sort breaks tie with array order of I2P first.
290  4, [](NodeEvictionCandidate& c) {
291  c.nTimeConnected = c.id;
292  c.m_is_local = (c.id == 3);
293  if (c.id == 4) {
294  c.m_network = NET_I2P;
295  } else if (c.id == 2) {
296  c.m_network = NET_ONION;
297  } else {
298  c.m_network = NET_IPV6;
299  }
300  },
301  /* protected_peer_ids */ {0, 4},
302  /* unprotected_peer_ids */ {1, 2},
303  random_context));
304 
305  // Combined test: expect having 1 localhost, 1 I2P and 1 onion peer out of 7
306  // to protect 1 I2P, 0 localhost, 0 onion and 2 other peers (3 total) sorted
307  // by longest uptime; stable sort breaks tie with array order of I2P first.
309  7, [](NodeEvictionCandidate& c) {
310  c.nTimeConnected = c.id;
311  c.m_is_local = (c.id == 4);
312  if (c.id == 6) {
313  c.m_network = NET_I2P;
314  } else if (c.id == 5) {
315  c.m_network = NET_ONION;
316  } else {
317  c.m_network = NET_IPV6;
318  }
319  },
320  /* protected_peer_ids */ {0, 1, 6},
321  /* unprotected_peer_ids */ {2, 3, 4, 5},
322  random_context));
323 
324  // Combined test: expect having 1 localhost, 1 I2P and 1 onion peer out of 8
325  // to protect 1 I2P, 1 localhost, 0 onion and 2 other peers (4 total) sorted
326  // by uptime; stable sort breaks tie with array order of I2P then localhost.
328  8, [](NodeEvictionCandidate& c) {
329  c.nTimeConnected = c.id;
330  c.m_is_local = (c.id == 6);
331  if (c.id == 5) {
332  c.m_network = NET_I2P;
333  } else if (c.id == 4) {
334  c.m_network = NET_ONION;
335  } else {
336  c.m_network = NET_IPV6;
337  }
338  },
339  /* protected_peer_ids */ {0, 1, 5, 6},
340  /* unprotected_peer_ids */ {2, 3, 4, 7},
341  random_context));
342 
343  // Combined test: expect having 4 localhost, 2 I2P, and 2 onion peers out of
344  // 16 to protect 1 localhost, 2 I2P, and 1 onion (4/16 total), plus 4 others
345  // for 8 total, sorted by longest uptime.
347  16, [](NodeEvictionCandidate& c) {
348  c.nTimeConnected = c.id;
349  c.m_is_local = (c.id == 6 || c.id > 11);
350  if (c.id == 7 || c.id == 11) {
351  c.m_network = NET_I2P;
352  } else if (c.id == 9 || c.id == 10) {
353  c.m_network = NET_ONION;
354  } else {
355  c.m_network = NET_IPV4;
356  }
357  },
358  /* protected_peer_ids */ {0, 1, 2, 3, 6, 7, 9, 11},
359  /* unprotected_peer_ids */ {4, 5, 8, 10, 12, 13, 14, 15},
360  random_context));
361 
362  // Combined test: expect having 1 localhost, 8 I2P and 1 onion peer out of
363  // 24 to protect 1, 4, and 1 (6 total), plus 6 others for 12/24 total,
364  // sorted by longest uptime.
366  24, [](NodeEvictionCandidate& c) {
367  c.nTimeConnected = c.id;
368  c.m_is_local = (c.id == 12);
369  if (c.id > 14 && c.id < 23) { // 4 protected instead of usual 2
370  c.m_network = NET_I2P;
371  } else if (c.id == 23) {
372  c.m_network = NET_ONION;
373  } else {
374  c.m_network = NET_IPV6;
375  }
376  },
377  /* protected_peer_ids */ {0, 1, 2, 3, 4, 5, 12, 15, 16, 17, 18, 23},
378  /* unprotected_peer_ids */ {6, 7, 8, 9, 10, 11, 13, 14, 19, 20, 21, 22},
379  random_context));
380 
381  // Combined test: expect having 1 localhost, 3 I2P and 6 onion peers out of
382  // 24 to protect 1, 3, and 2 (6 total, I2P has fewer candidates and so gets the
383  // unused localhost slot), plus 6 others for 12/24 total, sorted by longest uptime.
385  24, [](NodeEvictionCandidate& c) {
386  c.nTimeConnected = c.id;
387  c.m_is_local = (c.id == 15);
388  if (c.id == 12 || c.id == 14 || c.id == 17) {
389  c.m_network = NET_I2P;
390  } else if (c.id > 17) { // 4 protected instead of usual 2
391  c.m_network = NET_ONION;
392  } else {
393  c.m_network = NET_IPV4;
394  }
395  },
396  /* protected_peer_ids */ {0, 1, 2, 3, 4, 5, 12, 14, 15, 17, 18, 19},
397  /* unprotected_peer_ids */ {6, 7, 8, 9, 10, 11, 13, 16, 20, 21, 22, 23},
398  random_context));
399 
400  // Combined test: expect having 1 localhost, 7 I2P and 4 onion peers out of
401  // 24 to protect 1 localhost, 2 I2P, and 3 onions (6 total), plus 6 others
402  // for 12/24 total, sorted by longest uptime.
404  24, [](NodeEvictionCandidate& c) {
405  c.nTimeConnected = c.id;
406  c.m_is_local = (c.id == 13);
407  if (c.id > 16) {
408  c.m_network = NET_I2P;
409  } else if (c.id == 12 || c.id == 14 || c.id == 15 || c.id == 16) {
410  c.m_network = NET_ONION;
411  } else {
412  c.m_network = NET_IPV6;
413  }
414  },
415  /* protected_peer_ids */ {0, 1, 2, 3, 4, 5, 12, 13, 14, 15, 17, 18},
416  /* unprotected_peer_ids */ {6, 7, 8, 9, 10, 11, 16, 19, 20, 21, 22, 23},
417  random_context));
418 
419  // Combined test: expect having 8 localhost, 4 I2P, and 3 onion peers out of
420  // 24 to protect 2 of each (6 total), plus 6 others for 12/24 total, sorted
421  // by longest uptime.
423  24, [](NodeEvictionCandidate& c) {
424  c.nTimeConnected = c.id;
425  c.m_is_local = (c.id > 15);
426  if (c.id > 10 && c.id < 15) {
427  c.m_network = NET_I2P;
428  } else if (c.id > 6 && c.id < 10) {
429  c.m_network = NET_ONION;
430  } else {
431  c.m_network = NET_IPV4;
432  }
433  },
434  /* protected_peer_ids */ {0, 1, 2, 3, 4, 5, 7, 8, 11, 12, 16, 17},
435  /* unprotected_peer_ids */ {6, 9, 10, 13, 14, 15, 18, 19, 20, 21, 22, 23},
436  random_context));
437 }
438 
439 // Returns true if any of the node ids in node_ids are selected for eviction.
440 bool IsEvicted(std::vector<NodeEvictionCandidate> candidates, const std::unordered_set<NodeId>& node_ids, FastRandomContext& random_context)
441 {
442  Shuffle(candidates.begin(), candidates.end(), random_context);
443  const std::optional<NodeId> evicted_node_id = SelectNodeToEvict(std::move(candidates));
444  if (!evicted_node_id) {
445  return false;
446  }
447  return node_ids.count(*evicted_node_id);
448 }
449 
450 // Create number_of_nodes random nodes, apply setup function candidate_setup_fn,
451 // apply eviction logic and then return true if any of the node ids in node_ids
452 // are selected for eviction.
453 bool IsEvicted(const int number_of_nodes, std::function<void(NodeEvictionCandidate&)> candidate_setup_fn, const std::unordered_set<NodeId>& node_ids, FastRandomContext& random_context)
454 {
455  std::vector<NodeEvictionCandidate> candidates = GetRandomNodeEvictionCandidates(number_of_nodes, random_context);
456  for (NodeEvictionCandidate& candidate : candidates) {
457  candidate_setup_fn(candidate);
458  }
459  return IsEvicted(candidates, node_ids, random_context);
460 }
461 
462 BOOST_AUTO_TEST_CASE(peer_eviction_test)
463 {
464  FastRandomContext random_context{true};
465 
466  for (int number_of_nodes = 0; number_of_nodes < 200; ++number_of_nodes) {
467  // Four nodes with the highest keyed netgroup values should be
468  // protected from eviction.
470  number_of_nodes, [number_of_nodes](NodeEvictionCandidate& candidate) {
471  candidate.nKeyedNetGroup = number_of_nodes - candidate.id;
472  },
473  {0, 1, 2, 3}, random_context));
474 
475  // Eight nodes with the lowest minimum ping time should be protected
476  // from eviction.
478  number_of_nodes, [](NodeEvictionCandidate& candidate) {
479  candidate.m_min_ping_time = std::chrono::microseconds{candidate.id};
480  },
481  {0, 1, 2, 3, 4, 5, 6, 7}, random_context));
482 
483  // Four nodes that most recently sent us novel transactions accepted
484  // into our mempool should be protected from eviction.
486  number_of_nodes, [number_of_nodes](NodeEvictionCandidate& candidate) {
487  candidate.nLastTXTime = number_of_nodes - candidate.id;
488  },
489  {0, 1, 2, 3}, random_context));
490 
491  // Up to eight non-tx-relay peers that most recently sent us novel
492  // blocks should be protected from eviction.
494  number_of_nodes, [number_of_nodes](NodeEvictionCandidate& candidate) {
495  candidate.nLastBlockTime = number_of_nodes - candidate.id;
496  if (candidate.id <= 7) {
497  candidate.fRelayTxes = false;
498  candidate.fRelevantServices = true;
499  }
500  },
501  {0, 1, 2, 3, 4, 5, 6, 7}, random_context));
502 
503  // Four peers that most recently sent us novel blocks should be
504  // protected from eviction.
506  number_of_nodes, [number_of_nodes](NodeEvictionCandidate& candidate) {
507  candidate.nLastBlockTime = number_of_nodes - candidate.id;
508  },
509  {0, 1, 2, 3}, random_context));
510 
511  // Combination of the previous two tests.
513  number_of_nodes, [number_of_nodes](NodeEvictionCandidate& candidate) {
514  candidate.nLastBlockTime = number_of_nodes - candidate.id;
515  if (candidate.id <= 7) {
516  candidate.fRelayTxes = false;
517  candidate.fRelevantServices = true;
518  }
519  },
520  {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, random_context));
521 
522  // Combination of all tests above.
524  number_of_nodes, [number_of_nodes](NodeEvictionCandidate& candidate) {
525  candidate.nKeyedNetGroup = number_of_nodes - candidate.id; // 4 protected
526  candidate.m_min_ping_time = std::chrono::microseconds{candidate.id}; // 8 protected
527  candidate.nLastTXTime = number_of_nodes - candidate.id; // 4 protected
528  candidate.nLastBlockTime = number_of_nodes - candidate.id; // 4 protected
529  },
530  {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}, random_context));
531 
532  // An eviction is expected given >= 29 random eviction candidates. The eviction logic protects at most
533  // four peers by net group, eight by lowest ping time, four by last time of novel tx, up to eight non-tx-relay
534  // peers by last novel block time, and four more peers by last novel block time.
535  if (number_of_nodes >= 29) {
536  BOOST_CHECK(SelectNodeToEvict(GetRandomNodeEvictionCandidates(number_of_nodes, random_context)));
537  }
538 
539  // No eviction is expected given <= 20 random eviction candidates. The eviction logic protects at least
540  // four peers by net group, eight by lowest ping time, four by last time of novel tx and four peers by last
541  // novel block time.
542  if (number_of_nodes <= 20) {
543  BOOST_CHECK(!SelectNodeToEvict(GetRandomNodeEvictionCandidates(number_of_nodes, random_context)));
544  }
545 
546  // Cases left to test:
547  // * "If any remaining peers are preferred for eviction consider only them. [...]"
548  // * "Identify the network group with the most connections and youngest member. [...]"
549  }
550 }
551 
NodeEvictionCandidate::m_network
Network m_network
Definition: net.h:1203
NodeId
int64_t NodeId
Definition: net.h:87
IsProtected
bool IsProtected(int num_peers, std::function< void(NodeEvictionCandidate &)> candidate_setup_fn, const std::unordered_set< NodeId > &protected_peer_ids, const std::unordered_set< NodeId > &unprotected_peer_ids, FastRandomContext &random_context)
Definition: net_peer_eviction_tests.cpp:24
NodeEvictionCandidate::m_min_ping_time
std::chrono::microseconds m_min_ping_time
Definition: net.h:1194
if
if(na.IsAddrV1Compatible())
Definition: deserialize.cpp:213
NET_IPV4
@ NET_IPV4
IPv4.
Definition: netaddress.h:50
setup_common.h
BOOST_FIXTURE_TEST_SUITE
#define BOOST_FIXTURE_TEST_SUITE(a, b)
Definition: object.cpp:14
BOOST_AUTO_TEST_SUITE_END
BOOST_AUTO_TEST_SUITE_END()
NodeEvictionCandidate::nKeyedNetGroup
uint64_t nKeyedNetGroup
Definition: net.h:1200
NET_I2P
@ NET_I2P
I2P.
Definition: netaddress.h:59
NodeEvictionCandidate
Definition: net.h:1190
SelectNodeToEvict
std::optional< NodeId > SelectNodeToEvict(std::vector< NodeEvictionCandidate > &&vEvictionCandidates)
Select an inbound peer to evict after filtering out (protecting) peers having distinct,...
Definition: net.cpp:965
NodeEvictionCandidate::id
NodeId id
Definition: net.h:1192
net.h
netaddress.h
Shuffle
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
Definition: random.h:231
BasicTestingSetup
Basic testing setup.
Definition: setup_common.h:76
NodeEvictionCandidate::m_is_local
bool m_is_local
Definition: net.h:1202
GetRandomNodeEvictionCandidates
std::vector< NodeEvictionCandidate > GetRandomNodeEvictionCandidates(int n_candidates, FastRandomContext &random_context)
Definition: net.cpp:44
NodeEvictionCandidate::nTimeConnected
int64_t nTimeConnected
Definition: net.h:1193
strprintf
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1164
IsEvicted
bool IsEvicted(std::vector< NodeEvictionCandidate > candidates, const std::unordered_set< NodeId > &node_ids, FastRandomContext &random_context)
Definition: net_peer_eviction_tests.cpp:440
NET_ONION
@ NET_ONION
TOR (v2 or v3)
Definition: netaddress.h:56
ProtectEvictionCandidatesByRatio
void ProtectEvictionCandidatesByRatio(std::vector< NodeEvictionCandidate > &eviction_candidates)
Protect desirable or disadvantaged inbound peers from eviction by ratio.
Definition: net.cpp:892
NET_IPV6
@ NET_IPV6
IPv6.
Definition: netaddress.h:53
BOOST_AUTO_TEST_CASE
BOOST_AUTO_TEST_CASE(peer_protection_test)
Definition: net_peer_eviction_tests.cpp:62
FastRandomContext
Fast randomness source.
Definition: random.h:119
BOOST_CHECK
#define BOOST_CHECK(expr)
Definition: object.cpp:17
BOOST_CHECK_EQUAL
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:18
NodeEvictionCandidate::nLastBlockTime
int64_t nLastBlockTime
Definition: net.h:1195
NodeEvictionCandidate::nLastTXTime
int64_t nLastTXTime
Definition: net.h:1196