10#include <boost/test/unit_test.hpp> 
   15#include <unordered_set> 
   26                 const std::unordered_set<
NodeId>& protected_peer_ids,
 
   27                 const std::unordered_set<
NodeId>& unprotected_peer_ids,
 
   32        candidate_setup_fn(candidate);
 
   34    Shuffle(candidates.begin(), candidates.end(), random_context);
 
   36    const size_t size{candidates.size()};
 
   37    const size_t expected{size - size / 2}; 
 
   41    size_t unprotected_count{0};
 
   43        if (protected_peer_ids.count(candidate.id)) {
 
   45            BOOST_TEST_MESSAGE(
strprintf(
"expected candidate to be protected: %d", candidate.id));
 
   48        if (unprotected_peer_ids.count(candidate.id)) {
 
   54    const bool is_protected{unprotected_count == unprotected_peer_ids.size()};
 
   56        BOOST_TEST_MESSAGE(
strprintf(
"unprotected: expected %d, actual %d",
 
   57                                     unprotected_peer_ids.size(), unprotected_count));
 
  112         {4, 5, 6, 7, 10, 11},
 
  135         {3, 4, 5, 6, 10, 11},
 
  212         {3, 4, 5, 8, 10, 11},
 
  235         {0, 1, 2, 3, 6, 8, 9, 10},
 
  236         {4, 5, 7, 11, 12, 13, 14, 15},
 
  248         {0, 1, 2, 3, 10, 11, 12, 13},
 
  249         {4, 5, 6, 7, 8, 9, 14, 15},
 
  261         {0, 1, 2, 3, 7, 8, 9, 15},
 
  262         {5, 6, 10, 11, 12, 13, 14},
 
  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;
 
  277                c.m_network = NET_IPV4;
 
  294                c.m_network = NET_I2P;
 
  295            } 
else if (c.
id == 2) {
 
  296                c.m_network = NET_ONION;
 
  298                c.m_network = NET_IPV6;
 
  313                c.m_network = NET_I2P;
 
  314            } 
else if (c.
id == 5) {
 
  315                c.m_network = NET_ONION;
 
  317                c.m_network = NET_IPV6;
 
  332                c.m_network = NET_I2P;
 
  333            } 
else if (c.
id == 4) {
 
  334                c.m_network = NET_ONION;
 
  336                c.m_network = NET_IPV6;
 
  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;
 
  355                c.m_network = NET_IPV4;
 
  358         {0, 1, 2, 3, 6, 7, 9, 11},
 
  359         {4, 5, 8, 10, 12, 13, 14, 15},
 
  369            if (c.
id > 14 && c.
id < 23) { 
 
  370                c.m_network = NET_I2P;
 
  371            } 
else if (c.
id == 23) {
 
  372                c.m_network = NET_ONION;
 
  374                c.m_network = NET_IPV6;
 
  377         {0, 1, 2, 3, 4, 5, 12, 15, 16, 17, 18, 23},
 
  378         {6, 7, 8, 9, 10, 11, 13, 14, 19, 20, 21, 22},
 
  388            if (c.
id == 12 || c.
id == 14 || c.
id == 17) {
 
  389                c.m_network = NET_I2P;
 
  390            } 
else if (c.
id > 17) { 
 
  391                c.m_network = NET_ONION;
 
  393                c.m_network = NET_IPV4;
 
  396         {0, 1, 2, 3, 4, 5, 12, 14, 15, 17, 18, 19},
 
  397         {6, 7, 8, 9, 10, 11, 13, 16, 20, 21, 22, 23},
 
  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;
 
  412                c.m_network = NET_IPV6;
 
  415         {0, 1, 2, 3, 4, 5, 12, 13, 14, 15, 17, 18},
 
  416         {6, 7, 8, 9, 10, 11, 16, 19, 20, 21, 22, 23},
 
  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;
 
  431                c.m_network = NET_IPV4;
 
  434         {0, 1, 2, 3, 4, 5, 7, 8, 11, 12, 16, 17},
 
  435         {6, 9, 10, 13, 14, 15, 18, 19, 20, 21, 22, 23},
 
  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) {
 
  447    return node_ids.count(*evicted_node_id);
 
  457        candidate_setup_fn(candidate);
 
  459    return IsEvicted(candidates, node_ids, random_context);
 
  466    for (
int number_of_nodes = 0; number_of_nodes < 200; ++number_of_nodes) {
 
  473                        {0, 1, 2, 3}, random_context));
 
  481                        {0, 1, 2, 3, 4, 5, 6, 7}, random_context));
 
  489                        {0, 1, 2, 3}, random_context));
 
  496                            if (candidate.
id <= 7) {
 
  497                                candidate.fRelayTxes = false;
 
  498                                candidate.fRelevantServices = true;
 
  501                        {0, 1, 2, 3, 4, 5, 6, 7}, random_context));
 
  509                        {0, 1, 2, 3}, random_context));
 
  515                            if (candidate.
id <= 7) {
 
  516                                candidate.fRelayTxes = false;
 
  517                                candidate.fRelevantServices = true;
 
  520                        {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, random_context));
 
  530                        {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}, random_context));
 
  535        if (number_of_nodes >= 29) {
 
  542        if (number_of_nodes <= 20) {
 
BOOST_AUTO_TEST_SUITE_END()
if(na.IsAddrV1Compatible())
void ProtectEvictionCandidatesByRatio(std::vector< NodeEvictionCandidate > &eviction_candidates)
Protect desirable or disadvantaged inbound peers from eviction by ratio.
std::optional< NodeId > SelectNodeToEvict(std::vector< NodeEvictionCandidate > &&vEvictionCandidates)
Select an inbound peer to evict after filtering out (protecting) peers having distinct,...
bool IsEvicted(std::vector< NodeEvictionCandidate > candidates, const std::unordered_set< NodeId > &node_ids, FastRandomContext &random_context)
BOOST_AUTO_TEST_CASE(peer_protection_test)
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)
@ NET_ONION
TOR (v2 or v3)
#define BOOST_FIXTURE_TEST_SUITE(a, b)
#define BOOST_CHECK_EQUAL(v1, v2)
#define BOOST_CHECK(expr)
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
std::chrono::microseconds m_min_ping_time
std::vector< NodeEvictionCandidate > GetRandomNodeEvictionCandidates(int n_candidates, FastRandomContext &random_context)