Bitcoin Core  22.99.0
P2P Digital Currency
addrman.cpp
Go to the documentation of this file.
1 // Copyright (c) 2020-2021 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/check.h>
9 #include <util/time.h>
10 
11 #include <optional>
12 #include <vector>
13 
14 /* A "source" is a source address from which we have received a bunch of other addresses. */
15 
16 static constexpr size_t NUM_SOURCES = 64;
17 static constexpr size_t NUM_ADDRESSES_PER_SOURCE = 256;
18 
19 static const std::vector<bool> EMPTY_ASMAP;
20 static constexpr uint32_t ADDRMAN_CONSISTENCY_CHECK_RATIO{0};
21 
22 static std::vector<CAddress> g_sources;
23 static std::vector<std::vector<CAddress>> g_addresses;
24 
25 static void CreateAddresses()
26 {
27  if (g_sources.size() > 0) { // already created
28  return;
29  }
30 
31  FastRandomContext rng(uint256(std::vector<unsigned char>(32, 123)));
32 
33  auto randAddr = [&rng]() {
34  in6_addr addr;
35  memcpy(&addr, rng.randbytes(sizeof(addr)).data(), sizeof(addr));
36 
37  uint16_t port;
38  memcpy(&port, rng.randbytes(sizeof(port)).data(), sizeof(port));
39  if (port == 0) {
40  port = 1;
41  }
42 
43  CAddress ret(CService(addr, port), NODE_NETWORK);
44 
45  ret.nTime = GetAdjustedTime();
46 
47  return ret;
48  };
49 
50  for (size_t source_i = 0; source_i < NUM_SOURCES; ++source_i) {
51  g_sources.emplace_back(randAddr());
52  g_addresses.emplace_back();
53  for (size_t addr_i = 0; addr_i < NUM_ADDRESSES_PER_SOURCE; ++addr_i) {
54  g_addresses[source_i].emplace_back(randAddr());
55  }
56  }
57 }
58 
59 static void AddAddressesToAddrMan(AddrMan& addrman)
60 {
61  for (size_t source_i = 0; source_i < NUM_SOURCES; ++source_i) {
62  addrman.Add(g_addresses[source_i], g_sources[source_i]);
63  }
64 }
65 
66 static void FillAddrMan(AddrMan& addrman)
67 {
69 
70  AddAddressesToAddrMan(addrman);
71 }
72 
73 /* Benchmarks */
74 
75 static void AddrManAdd(benchmark::Bench& bench)
76 {
78 
79  bench.run([&] {
80  AddrMan addrman{EMPTY_ASMAP, /*deterministic=*/false, ADDRMAN_CONSISTENCY_CHECK_RATIO};
81  AddAddressesToAddrMan(addrman);
82  });
83 }
84 
85 static void AddrManSelect(benchmark::Bench& bench)
86 {
87  AddrMan addrman{EMPTY_ASMAP, /*deterministic=*/false, ADDRMAN_CONSISTENCY_CHECK_RATIO};
88 
89  FillAddrMan(addrman);
90 
91  bench.run([&] {
92  const auto& address = addrman.Select();
93  assert(address.first.GetPort() > 0);
94  });
95 }
96 
97 static void AddrManGetAddr(benchmark::Bench& bench)
98 {
99  AddrMan addrman{EMPTY_ASMAP, /*deterministic=*/false, ADDRMAN_CONSISTENCY_CHECK_RATIO};
100 
101  FillAddrMan(addrman);
102 
103  bench.run([&] {
104  const auto& addresses = addrman.GetAddr(/* max_addresses */ 2500, /* max_pct */ 23, /* network */ std::nullopt);
105  assert(addresses.size() > 0);
106  });
107 }
108 
110 {
111  auto markSomeAsGood = [](AddrMan& addrman) {
112  for (size_t source_i = 0; source_i < NUM_SOURCES; ++source_i) {
113  for (size_t addr_i = 0; addr_i < NUM_ADDRESSES_PER_SOURCE; ++addr_i) {
114  addrman.Good(g_addresses[source_i][addr_i]);
115  }
116  }
117  };
118 
119  CreateAddresses();
120 
121  bench.run([&] {
122  // To make the benchmark independent of the number of evaluations, we always prepare a new addrman.
123  // This is necessary because AddrMan::Good() method modifies the object, affecting the timing of subsequent calls
124  // to the same method and we want to do the same amount of work in every loop iteration.
125  //
126  // This has some overhead (exactly the result of AddrManAdd benchmark), but that overhead is constant so improvements in
127  // AddrMan::Good() will still be noticeable.
128  AddrMan addrman{EMPTY_ASMAP, /*deterministic=*/false, ADDRMAN_CONSISTENCY_CHECK_RATIO};
129  AddAddressesToAddrMan(addrman);
130 
131  markSomeAsGood(addrman);
132  });
133 }
134 
CService
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:528
assert
assert(!tx.IsCoinBase())
check.h
NUM_SOURCES
static constexpr size_t NUM_SOURCES
Definition: addrman.cpp:16
AddrMan
Stochastic address manager.
Definition: addrman.h:79
AddrManAdd
static void AddrManAdd(benchmark::Bench &bench)
Definition: addrman.cpp:75
FastRandomContext::randbytes
std::vector< unsigned char > randbytes(size_t len)
Generate random bytes.
Definition: random.cpp:623
ankerl::nanobench::Bench
Main entry point to nanobench's benchmarking facility.
Definition: nanobench.h:616
NODE_NETWORK
@ NODE_NETWORK
Definition: protocol.h:277
g_sources
static std::vector< CAddress > g_sources
Definition: addrman.cpp:22
CAddress::nTime
uint32_t nTime
Always included in serialization.
Definition: protocol.h:440
NUM_ADDRESSES_PER_SOURCE
static constexpr size_t NUM_ADDRESSES_PER_SOURCE
Definition: addrman.cpp:17
random.h
AddrMan::Add
bool Add(const std::vector< CAddress > &vAddr, const CNetAddr &source, int64_t nTimePenalty=0)
Attempt to add one or more addresses to addrman's new table.
Definition: addrman.cpp:1187
EMPTY_ASMAP
static const std::vector< bool > EMPTY_ASMAP
Definition: addrman.cpp:19
ankerl::nanobench::Bench::run
Bench & run(char const *benchmarkName, Op &&op)
Repeatedly calls op() based on the configuration, and performs measurements.
Definition: nanobench.h:1183
time.h
uint256
256-bit opaque blob.
Definition: uint256.h:126
bench.h
g_addresses
static std::vector< std::vector< CAddress > > g_addresses
Definition: addrman.cpp:23
AddrManGetAddr
static void AddrManGetAddr(benchmark::Bench &bench)
Definition: addrman.cpp:97
BENCHMARK
BENCHMARK(AddrManAdd)
GetAdjustedTime
int64_t GetAdjustedTime()
Definition: timedata.cpp:35
CAddress
A CService with information about it as peer.
Definition: protocol.h:358
AddrManAddThenGood
static void AddrManAddThenGood(benchmark::Bench &bench)
Definition: addrman.cpp:109
FillAddrMan
static void FillAddrMan(AddrMan &addrman)
Definition: addrman.cpp:66
AddAddressesToAddrMan
static void AddAddressesToAddrMan(AddrMan &addrman)
Definition: addrman.cpp:59
ADDRMAN_CONSISTENCY_CHECK_RATIO
static constexpr uint32_t ADDRMAN_CONSISTENCY_CHECK_RATIO
Definition: addrman.cpp:20
addrman.h
CreateAddresses
static void CreateAddresses()
Definition: addrman.cpp:25
AddrManSelect
static void AddrManSelect(benchmark::Bench &bench)
Definition: addrman.cpp:85
FastRandomContext
Fast randomness source.
Definition: random.h:131