/ src / bench / peer_eviction.cpp
peer_eviction.cpp
  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  
 11  #include <chrono>
 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);