peer_eviction.cpp raw

   1  // Copyright (c) 2021-present 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 <bench/bench.h>
   6  #include <netaddress.h>
   7  #include <node/eviction.h>
   8  #include <random.h>
   9  #include <test/util/net.h>
  10  #include <util/time.h>
  11  
  12  #include <functional>
  13  #include <vector>
  14  
  15  static void EvictionProtectionCommon(
  16      benchmark::Bench& bench,
  17      int num_candidates,
  18      std::function<void(NodeEvictionCandidate&)> candidate_setup_fn)
  19  {
  20      using Candidates = std::vector<NodeEvictionCandidate>;
  21      FastRandomContext random_context{true};
  22  
  23      Candidates candidates{GetRandomNodeEvictionCandidates(num_candidates, random_context)};
  24      for (auto& c : candidates) {
  25          candidate_setup_fn(c);
  26      }
  27  
  28  
  29      bench.run([&] {
  30          // creating a copy has an overhead of about 3%, so it does not influence the benchmark results much.
  31          auto copy = candidates;
  32          ProtectEvictionCandidatesByRatio(copy);
  33      });
  34  }
  35  
  36  /* Benchmarks */
  37  
  38  static void EvictionProtection0Networks250Candidates(benchmark::Bench& bench)
  39  {
  40      EvictionProtectionCommon(
  41          bench,
  42          /*num_candidates=*/250,
  43          [](NodeEvictionCandidate& c) {
  44              c.m_connected = NodeSeconds{std::chrono::seconds{c.id}};
  45              c.m_network = NET_IPV4;
  46          });
  47  }
  48  
  49  static void EvictionProtection1Networks250Candidates(benchmark::Bench& bench)
  50  {
  51      EvictionProtectionCommon(
  52          bench,
  53          /*num_candidates=*/250,
  54          [](NodeEvictionCandidate& c) {
  55              c.m_connected = NodeSeconds{std::chrono::seconds{c.id}};
  56              c.m_is_local = false;
  57              if (c.id >= 130 && c.id < 240) { // 110 Tor
  58                  c.m_network = NET_ONION;
  59              } else {
  60                  c.m_network = NET_IPV4;
  61              }
  62          });
  63  }
  64  
  65  static void EvictionProtection2Networks250Candidates(benchmark::Bench& bench)
  66  {
  67      EvictionProtectionCommon(
  68          bench,
  69          /*num_candidates=*/250,
  70          [](NodeEvictionCandidate& c) {
  71              c.m_connected = NodeSeconds{std::chrono::seconds{c.id}};
  72              c.m_is_local = false;
  73              if (c.id >= 90 && c.id < 160) { // 70 Tor
  74                  c.m_network = NET_ONION;
  75              } else if (c.id >= 170 && c.id < 250) { // 80 I2P
  76                  c.m_network = NET_I2P;
  77              } else {
  78                  c.m_network = NET_IPV4;
  79              }
  80          });
  81  }
  82  
  83  static void EvictionProtection3Networks050Candidates(benchmark::Bench& bench)
  84  {
  85      EvictionProtectionCommon(
  86          bench,
  87          /*num_candidates=*/50,
  88          [](NodeEvictionCandidate& c) {
  89              c.m_connected = NodeSeconds{std::chrono::seconds{c.id}};
  90              c.m_is_local = (c.id == 28 || c.id == 47); //  2 localhost
  91              if (c.id >= 30 && c.id < 47) {             // 17 I2P
  92                  c.m_network = NET_I2P;
  93              } else if (c.id >= 24 && c.id < 28) { //  4 Tor
  94                  c.m_network = NET_ONION;
  95              } else {
  96                  c.m_network = NET_IPV4;
  97              }
  98          });
  99  }
 100  
 101  static void EvictionProtection3Networks100Candidates(benchmark::Bench& bench)
 102  {
 103      EvictionProtectionCommon(
 104          bench,
 105          /*num_candidates=*/100,
 106          [](NodeEvictionCandidate& c) {
 107              c.m_connected = NodeSeconds{std::chrono::seconds{c.id}};
 108              c.m_is_local = (c.id >= 55 && c.id < 60); //  5 localhost
 109              if (c.id >= 70 && c.id < 80) {            // 10 I2P
 110                  c.m_network = NET_I2P;
 111              } else if (c.id >= 80 && c.id < 96) { // 16 Tor
 112                  c.m_network = NET_ONION;
 113              } else {
 114                  c.m_network = NET_IPV4;
 115              }
 116          });
 117  }
 118  
 119  static void EvictionProtection3Networks250Candidates(benchmark::Bench& bench)
 120  {
 121      EvictionProtectionCommon(
 122          bench,
 123          /*num_candidates=*/250,
 124          [](NodeEvictionCandidate& c) {
 125              c.m_connected = NodeSeconds{std::chrono::seconds{c.id}};
 126              c.m_is_local = (c.id >= 140 && c.id < 160); // 20 localhost
 127              if (c.id >= 170 && c.id < 180) {            // 10 I2P
 128                  c.m_network = NET_I2P;
 129              } else if (c.id >= 190 && c.id < 240) { // 50 Tor
 130                  c.m_network = NET_ONION;
 131              } else {
 132                  c.m_network = NET_IPV4;
 133              }
 134          });
 135  }
 136  
 137  // Candidate numbers used for the benchmarks:
 138  // -  50 candidates simulates a possible use of -maxconnections
 139  // - 100 candidates approximates an average node with default settings
 140  // - 250 candidates is the number of peers reported by operators of busy nodes
 141  
 142  // No disadvantaged networks, with 250 eviction candidates.
 143  BENCHMARK(EvictionProtection0Networks250Candidates);
 144  
 145  // 1 disadvantaged network (Tor) with 250 eviction candidates.
 146  BENCHMARK(EvictionProtection1Networks250Candidates);
 147  
 148  // 2 disadvantaged networks (I2P, Tor) with 250 eviction candidates.
 149  BENCHMARK(EvictionProtection2Networks250Candidates);
 150  
 151  // 3 disadvantaged networks (I2P/localhost/Tor) with 50/100/250 eviction candidates.
 152  BENCHMARK(EvictionProtection3Networks050Candidates);
 153  BENCHMARK(EvictionProtection3Networks100Candidates);
 154  BENCHMARK(EvictionProtection3Networks250Candidates);
 155