Bitcoin Core  0.20.99
P2P Digital Currency
addrman.cpp
Go to the documentation of this file.
1 // Copyright (c) 2020-2020 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 <addrman.h>
6 #include <bench/bench.h>
7 #include <random.h>
8 #include <util/time.h>
9 
10 #include <vector>
11 
12 /* A "source" is a source address from which we have received a bunch of other addresses. */
13 
14 static constexpr size_t NUM_SOURCES = 64;
15 static constexpr size_t NUM_ADDRESSES_PER_SOURCE = 256;
16 
17 static std::vector<CAddress> g_sources;
18 static std::vector<std::vector<CAddress>> g_addresses;
19 
20 static void CreateAddresses()
21 {
22  if (g_sources.size() > 0) { // already created
23  return;
24  }
25 
26  FastRandomContext rng(uint256(std::vector<unsigned char>(32, 123)));
27 
28  auto randAddr = [&rng]() {
29  in6_addr addr;
30  memcpy(&addr, rng.randbytes(sizeof(addr)).data(), sizeof(addr));
31 
32  uint16_t port;
33  memcpy(&port, rng.randbytes(sizeof(port)).data(), sizeof(port));
34  if (port == 0) {
35  port = 1;
36  }
37 
38  CAddress ret(CService(addr, port), NODE_NETWORK);
39 
40  ret.nTime = GetAdjustedTime();
41 
42  return ret;
43  };
44 
45  for (size_t source_i = 0; source_i < NUM_SOURCES; ++source_i) {
46  g_sources.emplace_back(randAddr());
47  g_addresses.emplace_back();
48  for (size_t addr_i = 0; addr_i < NUM_ADDRESSES_PER_SOURCE; ++addr_i) {
49  g_addresses[source_i].emplace_back(randAddr());
50  }
51  }
52 }
53 
54 static void AddAddressesToAddrMan(CAddrMan& addrman)
55 {
56  for (size_t source_i = 0; source_i < NUM_SOURCES; ++source_i) {
57  addrman.Add(g_addresses[source_i], g_sources[source_i]);
58  }
59 }
60 
61 static void FillAddrMan(CAddrMan& addrman)
62 {
64 
65  AddAddressesToAddrMan(addrman);
66 }
67 
68 /* Benchmarks */
69 
70 static void AddrManAdd(benchmark::State& state)
71 {
73 
74  CAddrMan addrman;
75 
76  while (state.KeepRunning()) {
77  AddAddressesToAddrMan(addrman);
78  addrman.Clear();
79  }
80 }
81 
82 static void AddrManSelect(benchmark::State& state)
83 {
84  CAddrMan addrman;
85 
86  FillAddrMan(addrman);
87 
88  while (state.KeepRunning()) {
89  const auto& address = addrman.Select();
90  assert(address.GetPort() > 0);
91  }
92 }
93 
94 static void AddrManGetAddr(benchmark::State& state)
95 {
96  CAddrMan addrman;
97 
98  FillAddrMan(addrman);
99 
100  while (state.KeepRunning()) {
101  const auto& addresses = addrman.GetAddr();
102  assert(addresses.size() > 0);
103  }
104 }
105 
106 static void AddrManGood(benchmark::State& state)
107 {
108  /* Create many CAddrMan objects - one to be modified at each loop iteration.
109  * This is necessary because the CAddrMan::Good() method modifies the
110  * object, affecting the timing of subsequent calls to the same method and
111  * we want to do the same amount of work in every loop iteration. */
112 
113  const uint64_t numLoops = state.m_num_iters * state.m_num_evals;
114 
115  std::vector<CAddrMan> addrmans(numLoops);
116  for (auto& addrman : addrmans) {
117  FillAddrMan(addrman);
118  }
119 
120  auto markSomeAsGood = [](CAddrMan& addrman) {
121  for (size_t source_i = 0; source_i < NUM_SOURCES; ++source_i) {
122  for (size_t addr_i = 0; addr_i < NUM_ADDRESSES_PER_SOURCE; ++addr_i) {
123  if (addr_i % 32 == 0) {
124  addrman.Good(g_addresses[source_i][addr_i]);
125  }
126  }
127  }
128  };
129 
130  uint64_t i = 0;
131  while (state.KeepRunning()) {
132  markSomeAsGood(addrmans.at(i));
133  ++i;
134  }
135 }
136 
138 BENCHMARK(AddrManSelect, 1000000);
static constexpr size_t NUM_SOURCES
Definition: addrman.cpp:14
const uint64_t m_num_iters
Definition: bench.h:58
CAddrInfo Select(bool newOnly=false)
Choose an address to connect to.
Definition: addrman.h:628
static constexpr size_t NUM_ADDRESSES_PER_SOURCE
Definition: addrman.cpp:15
bool KeepRunning()
Definition: bench.h:69
bool Add(const CAddress &addr, const CNetAddr &source, int64_t nTimePenalty=0)
Add a single address.
Definition: addrman.h:557
static std::vector< CAddress > g_sources
Definition: addrman.cpp:17
static void AddrManSelect(benchmark::State &state)
Definition: addrman.cpp:82
Stochastical (IP) address manager.
Definition: addrman.h:176
static void AddAddressesToAddrMan(CAddrMan &addrman)
Definition: addrman.cpp:54
std::vector< CAddress > GetAddr()
Return a bunch of addresses, selected at random.
Definition: addrman.h:641
static void AddrManGood(benchmark::State &state)
Definition: addrman.cpp:106
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:138
Fast randomness source.
Definition: random.h:119
static void AddrManGetAddr(benchmark::State &state)
Definition: addrman.cpp:94
static void FillAddrMan(CAddrMan &addrman)
Definition: addrman.cpp:61
A CService with information about it as peer.
Definition: protocol.h:329
const uint64_t m_num_evals
Definition: bench.h:59
BENCHMARK(AddrManAdd, 5)
256-bit opaque blob.
Definition: uint256.h:120
static void AddrManAdd(benchmark::State &state)
Definition: addrman.cpp:70
static std::vector< std::vector< CAddress > > g_addresses
Definition: addrman.cpp:18
void Clear()
Definition: addrman.h:502
void * memcpy(void *a, const void *b, size_t c)
int64_t GetAdjustedTime()
Definition: timedata.cpp:35
static void CreateAddresses()
Definition: addrman.cpp:20
uint32_t nTime
Definition: protocol.h:354
std::vector< unsigned char > randbytes(size_t len)
Generate random bytes.
Definition: random.cpp:621