Bitcoin Core  22.0.0
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 <optional>
11 #include <vector>
12 
13 /* A "source" is a source address from which we have received a bunch of other addresses. */
14 
15 static constexpr size_t NUM_SOURCES = 64;
16 static constexpr size_t NUM_ADDRESSES_PER_SOURCE = 256;
17 
18 static std::vector<CAddress> g_sources;
19 static std::vector<std::vector<CAddress>> g_addresses;
20 
21 static void CreateAddresses()
22 {
23  if (g_sources.size() > 0) { // already created
24  return;
25  }
26 
27  FastRandomContext rng(uint256(std::vector<unsigned char>(32, 123)));
28 
29  auto randAddr = [&rng]() {
30  in6_addr addr;
31  memcpy(&addr, rng.randbytes(sizeof(addr)).data(), sizeof(addr));
32 
33  uint16_t port;
34  memcpy(&port, rng.randbytes(sizeof(port)).data(), sizeof(port));
35  if (port == 0) {
36  port = 1;
37  }
38 
39  CAddress ret(CService(addr, port), NODE_NETWORK);
40 
41  ret.nTime = GetAdjustedTime();
42 
43  return ret;
44  };
45 
46  for (size_t source_i = 0; source_i < NUM_SOURCES; ++source_i) {
47  g_sources.emplace_back(randAddr());
48  g_addresses.emplace_back();
49  for (size_t addr_i = 0; addr_i < NUM_ADDRESSES_PER_SOURCE; ++addr_i) {
50  g_addresses[source_i].emplace_back(randAddr());
51  }
52  }
53 }
54 
55 static void AddAddressesToAddrMan(CAddrMan& addrman)
56 {
57  for (size_t source_i = 0; source_i < NUM_SOURCES; ++source_i) {
58  addrman.Add(g_addresses[source_i], g_sources[source_i]);
59  }
60 }
61 
62 static void FillAddrMan(CAddrMan& addrman)
63 {
65 
66  AddAddressesToAddrMan(addrman);
67 }
68 
69 /* Benchmarks */
70 
71 static void AddrManAdd(benchmark::Bench& bench)
72 {
74 
75  CAddrMan addrman;
76 
77  bench.run([&] {
78  AddAddressesToAddrMan(addrman);
79  addrman.Clear();
80  });
81 }
82 
83 static void AddrManSelect(benchmark::Bench& bench)
84 {
85  CAddrMan addrman;
86 
87  FillAddrMan(addrman);
88 
89  bench.run([&] {
90  const auto& address = addrman.Select();
91  assert(address.GetPort() > 0);
92  });
93 }
94 
95 static void AddrManGetAddr(benchmark::Bench& bench)
96 {
97  CAddrMan addrman;
98 
99  FillAddrMan(addrman);
100 
101  bench.run([&] {
102  const auto& addresses = addrman.GetAddr(/* max_addresses */ 2500, /* max_pct */ 23, /* network */ std::nullopt);
103  assert(addresses.size() > 0);
104  });
105 }
106 
107 static void AddrManGood(benchmark::Bench& bench)
108 {
109  /* Create many CAddrMan objects - one to be modified at each loop iteration.
110  * This is necessary because the CAddrMan::Good() method modifies the
111  * object, affecting the timing of subsequent calls to the same method and
112  * we want to do the same amount of work in every loop iteration. */
113 
114  bench.epochs(5).epochIterations(1);
115 
116  std::vector<CAddrMan> addrmans(bench.epochs() * bench.epochIterations());
117  for (auto& addrman : addrmans) {
118  FillAddrMan(addrman);
119  }
120 
121  auto markSomeAsGood = [](CAddrMan& addrman) {
122  for (size_t source_i = 0; source_i < NUM_SOURCES; ++source_i) {
123  for (size_t addr_i = 0; addr_i < NUM_ADDRESSES_PER_SOURCE; ++addr_i) {
124  if (addr_i % 32 == 0) {
125  addrman.Good(g_addresses[source_i][addr_i]);
126  }
127  }
128  }
129  };
130 
131  uint64_t i = 0;
132  bench.run([&] {
133  markSomeAsGood(addrmans.at(i));
134  ++i;
135  });
136 }
137 
static constexpr size_t NUM_SOURCES
Definition: addrman.cpp:15
Bench & epochIterations(uint64_t numIters) noexcept
Sets exactly the number of iterations for each epoch.
static constexpr size_t NUM_ADDRESSES_PER_SOURCE
Definition: addrman.cpp:16
assert(!tx.IsCoinBase())
static void AddrManAdd(benchmark::Bench &bench)
Definition: addrman.cpp:71
void Clear() EXCLUSIVE_LOCKS_REQUIRED(!cs)
Definition: addrman.h:464
static std::vector< CAddress > g_sources
Definition: addrman.cpp:18
Stochastical (IP) address manager.
Definition: addrman.h:173
static void AddAddressesToAddrMan(CAddrMan &addrman)
Definition: addrman.cpp:55
std::vector< CAddress > GetAddr(size_t max_addresses, size_t max_pct, std::optional< Network > network) EXCLUSIVE_LOCKS_REQUIRED(!cs)
Return all or many randomly selected addresses, optionally by network.
Definition: addrman.h:599
CAddrInfo Select(bool newOnly=false) EXCLUSIVE_LOCKS_REQUIRED(!cs)
Choose an address to connect to.
Definition: addrman.h:582
Bench & run(char const *benchmarkName, Op &&op)
Repeatedly calls op() based on the configuration, and performs measurements.
Definition: nanobench.h:1181
bool Add(const CAddress &addr, const CNetAddr &source, int64_t nTimePenalty=0) EXCLUSIVE_LOCKS_REQUIRED(!cs)
Add a single address.
Definition: addrman.h:508
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:560
Fast randomness source.
Definition: random.h:119
static void FillAddrMan(CAddrMan &addrman)
Definition: addrman.cpp:62
A CService with information about it as peer.
Definition: protocol.h:358
256-bit opaque blob.
Definition: uint256.h:124
BENCHMARK(AddrManAdd)
static std::vector< std::vector< CAddress > > g_addresses
Definition: addrman.cpp:19
Bench & epochs(size_t numEpochs) noexcept
Controls number of epochs, the number of measurements to perform.
int64_t GetAdjustedTime()
Definition: timedata.cpp:34
static void AddrManGetAddr(benchmark::Bench &bench)
Definition: addrman.cpp:95
static void AddrManSelect(benchmark::Bench &bench)
Definition: addrman.cpp:83
Main entry point to nanobench&#39;s benchmarking facility.
Definition: nanobench.h:614
static void CreateAddresses()
Definition: addrman.cpp:21
uint32_t nTime
Always included in serialization, except in the network format on INIT_PROTO_VERSION.
Definition: protocol.h:449
static void AddrManGood(benchmark::Bench &bench)
Definition: addrman.cpp:107
std::vector< unsigned char > randbytes(size_t len)
Generate random bytes.
Definition: random.cpp:626