Bitcoin
addrman.h
Go to the documentation of this file.
1 // Copyright (c) 2012 Pieter Wuille
2 // Copyright (c) 2012-2018 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #ifndef BITCOIN_ADDRMAN_H
7 #define BITCOIN_ADDRMAN_H
8 
9 #include <netaddress.h>
10 #include <protocol.h>
11 #include <random.h>
12 #include <sync.h>
13 #include <timedata.h>
14 #include <util/system.h>
15 
16 #include <map>
17 #include <set>
18 #include <stdint.h>
19 #include <vector>
20 
24 class CAddrInfo : public CAddress
25 {
26 public:
29 
32 
33 private:
36 
39 
41  int nAttempts{0};
42 
44  int nRefCount{0};
45 
47  bool fInTried{false};
48 
50  int nRandomPos{-1};
51 
52  friend class CAddrMan;
53 
54 public:
55 
57 
58  template <typename Stream, typename Operation>
59  inline void SerializationOp(Stream& s, Operation ser_action) {
60  READWRITEAS(CAddress, *this);
64  }
65 
66  CAddrInfo(const CAddress &addrIn, const CNetAddr &addrSource) : CAddress(addrIn), source(addrSource)
67  {
68  }
69 
71  {
72  }
73 
75  int GetTriedBucket(const uint256 &nKey) const;
76 
78  int GetNewBucket(const uint256 &nKey, const CNetAddr& src) const;
79 
81  int GetNewBucket(const uint256 &nKey) const
82  {
83  return GetNewBucket(nKey, source);
84  }
85 
87  int GetBucketPosition(const uint256 &nKey, bool fNew, int nBucket) const;
88 
90  bool IsTerrible(int64_t nNow = GetAdjustedTime()) const;
91 
93  double GetChance(int64_t nNow = GetAdjustedTime()) const;
94 };
95 
122 #define ADDRMAN_TRIED_BUCKET_COUNT_LOG2 8
124 
126 #define ADDRMAN_NEW_BUCKET_COUNT_LOG2 10
127 
129 #define ADDRMAN_BUCKET_SIZE_LOG2 6
130 
132 #define ADDRMAN_TRIED_BUCKETS_PER_GROUP 8
133 
135 #define ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP 64
136 
138 #define ADDRMAN_NEW_BUCKETS_PER_ADDRESS 8
139 
141 #define ADDRMAN_HORIZON_DAYS 30
142 
144 #define ADDRMAN_RETRIES 3
145 
147 #define ADDRMAN_MAX_FAILURES 10
148 
150 #define ADDRMAN_MIN_FAIL_DAYS 7
151 
153 #define ADDRMAN_REPLACEMENT_HOURS 4
154 
156 #define ADDRMAN_GETADDR_MAX_PCT 23
157 
159 #define ADDRMAN_GETADDR_MAX 2500
160 
162 #define ADDRMAN_TRIED_BUCKET_COUNT (1 << ADDRMAN_TRIED_BUCKET_COUNT_LOG2)
163 #define ADDRMAN_NEW_BUCKET_COUNT (1 << ADDRMAN_NEW_BUCKET_COUNT_LOG2)
164 #define ADDRMAN_BUCKET_SIZE (1 << ADDRMAN_BUCKET_SIZE_LOG2)
165 
167 #define ADDRMAN_SET_TRIED_COLLISION_SIZE 10
168 
170 static const int64_t ADDRMAN_TEST_WINDOW = 40*60; // 40 minutes
171 
175 class CAddrMan
176 {
177 protected:
180 
181 private:
183  int nIdCount GUARDED_BY(cs);
184 
186  std::map<int, CAddrInfo> mapInfo GUARDED_BY(cs);
187 
189  std::map<CNetAddr, int> mapAddr GUARDED_BY(cs);
190 
192  std::vector<int> vRandom GUARDED_BY(cs);
193 
194  // number of "tried" entries
195  int nTried GUARDED_BY(cs);
196 
199 
201  int nNew GUARDED_BY(cs);
202 
205 
207  int64_t nLastGood GUARDED_BY(cs);
208 
210  std::set<int> m_tried_collisions;
211 
212 protected:
215 
218 
220  CAddrInfo* Find(const CNetAddr& addr, int *pnId = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs);
221 
224  CAddrInfo* Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs);
225 
227  void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2) EXCLUSIVE_LOCKS_REQUIRED(cs);
228 
230  void MakeTried(CAddrInfo& info, int nId) EXCLUSIVE_LOCKS_REQUIRED(cs);
231 
233  void Delete(int nId) EXCLUSIVE_LOCKS_REQUIRED(cs);
234 
236  void ClearNew(int nUBucket, int nUBucketPos) EXCLUSIVE_LOCKS_REQUIRED(cs);
237 
239  void Good_(const CService &addr, bool test_before_evict, int64_t time) EXCLUSIVE_LOCKS_REQUIRED(cs);
240 
242  bool Add_(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty) EXCLUSIVE_LOCKS_REQUIRED(cs);
243 
245  void Attempt_(const CService &addr, bool fCountFailure, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs);
246 
249 
252 
255 
256 #ifdef DEBUG_ADDRMAN
257  int Check_() EXCLUSIVE_LOCKS_REQUIRED(cs);
259 #endif
260 
262  void GetAddr_(std::vector<CAddress> &vAddr) EXCLUSIVE_LOCKS_REQUIRED(cs);
263 
265  void Connected_(const CService &addr, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs);
266 
268  void SetServices_(const CService &addr, ServiceFlags nServices) EXCLUSIVE_LOCKS_REQUIRED(cs);
269 
270 public:
300  template<typename Stream>
301  void Serialize(Stream &s) const
302  {
303  LOCK(cs);
304 
305  unsigned char nVersion = 1;
306  s << nVersion;
307  s << ((unsigned char)32);
308  s << nKey;
309  s << nNew;
310  s << nTried;
311 
312  int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30);
313  s << nUBuckets;
314  std::map<int, int> mapUnkIds;
315  int nIds = 0;
316  for (const auto& entry : mapInfo) {
317  mapUnkIds[entry.first] = nIds;
318  const CAddrInfo &info = entry.second;
319  if (info.nRefCount) {
320  assert(nIds != nNew); // this means nNew was wrong, oh ow
321  s << info;
322  nIds++;
323  }
324  }
325  nIds = 0;
326  for (const auto& entry : mapInfo) {
327  const CAddrInfo &info = entry.second;
328  if (info.fInTried) {
329  assert(nIds != nTried); // this means nTried was wrong, oh ow
330  s << info;
331  nIds++;
332  }
333  }
334  for (int bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) {
335  int nSize = 0;
336  for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
337  if (vvNew[bucket][i] != -1)
338  nSize++;
339  }
340  s << nSize;
341  for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
342  if (vvNew[bucket][i] != -1) {
343  int nIndex = mapUnkIds[vvNew[bucket][i]];
344  s << nIndex;
345  }
346  }
347  }
348  }
349 
350  template<typename Stream>
351  void Unserialize(Stream& s)
352  {
353  LOCK(cs);
354 
355  Clear();
356 
357  unsigned char nVersion;
358  s >> nVersion;
359  unsigned char nKeySize;
360  s >> nKeySize;
361  if (nKeySize != 32) throw std::ios_base::failure("Incorrect keysize in addrman deserialization");
362  s >> nKey;
363  s >> nNew;
364  s >> nTried;
365  int nUBuckets = 0;
366  s >> nUBuckets;
367  if (nVersion != 0) {
368  nUBuckets ^= (1 << 30);
369  }
370 
372  throw std::ios_base::failure("Corrupt CAddrMan serialization, nNew exceeds limit.");
373  }
374 
376  throw std::ios_base::failure("Corrupt CAddrMan serialization, nTried exceeds limit.");
377  }
378 
379  // Deserialize entries from the new table.
380  for (int n = 0; n < nNew; n++) {
381  CAddrInfo &info = mapInfo[n];
382  s >> info;
383  mapAddr[info] = n;
384  info.nRandomPos = vRandom.size();
385  vRandom.push_back(n);
386  if (nVersion != 1 || nUBuckets != ADDRMAN_NEW_BUCKET_COUNT) {
387  // In case the new table data cannot be used (nVersion unknown, or bucket count wrong),
388  // immediately try to give them a reference based on their primary source address.
389  int nUBucket = info.GetNewBucket(nKey);
390  int nUBucketPos = info.GetBucketPosition(nKey, true, nUBucket);
391  if (vvNew[nUBucket][nUBucketPos] == -1) {
392  vvNew[nUBucket][nUBucketPos] = n;
393  info.nRefCount++;
394  }
395  }
396  }
397  nIdCount = nNew;
398 
399  // Deserialize entries from the tried table.
400  int nLost = 0;
401  for (int n = 0; n < nTried; n++) {
402  CAddrInfo info;
403  s >> info;
404  int nKBucket = info.GetTriedBucket(nKey);
405  int nKBucketPos = info.GetBucketPosition(nKey, false, nKBucket);
406  if (vvTried[nKBucket][nKBucketPos] == -1) {
407  info.nRandomPos = vRandom.size();
408  info.fInTried = true;
409  vRandom.push_back(nIdCount);
410  mapInfo[nIdCount] = info;
411  mapAddr[info] = nIdCount;
412  vvTried[nKBucket][nKBucketPos] = nIdCount;
413  nIdCount++;
414  } else {
415  nLost++;
416  }
417  }
418  nTried -= nLost;
419 
420  // Deserialize positions in the new table (if possible).
421  for (int bucket = 0; bucket < nUBuckets; bucket++) {
422  int nSize = 0;
423  s >> nSize;
424  for (int n = 0; n < nSize; n++) {
425  int nIndex = 0;
426  s >> nIndex;
427  if (nIndex >= 0 && nIndex < nNew) {
428  CAddrInfo &info = mapInfo[nIndex];
429  int nUBucketPos = info.GetBucketPosition(nKey, true, bucket);
430  if (nVersion == 1 && nUBuckets == ADDRMAN_NEW_BUCKET_COUNT && vvNew[bucket][nUBucketPos] == -1 && info.nRefCount < ADDRMAN_NEW_BUCKETS_PER_ADDRESS) {
431  info.nRefCount++;
432  vvNew[bucket][nUBucketPos] = nIndex;
433  }
434  }
435  }
436  }
437 
438  // Prune new entries with refcount 0 (as a result of collisions).
439  int nLostUnk = 0;
440  for (std::map<int, CAddrInfo>::const_iterator it = mapInfo.begin(); it != mapInfo.end(); ) {
441  if (it->second.fInTried == false && it->second.nRefCount == 0) {
442  std::map<int, CAddrInfo>::const_iterator itCopy = it++;
443  Delete(itCopy->first);
444  nLostUnk++;
445  } else {
446  it++;
447  }
448  }
449  if (nLost + nLostUnk > 0) {
450  LogPrint(BCLog::ADDRMAN, "addrman lost %i new and %i tried addresses due to collisions\n", nLostUnk, nLost);
451  }
452 
453  Check();
454  }
455 
456  void Clear()
457  {
458  LOCK(cs);
459  std::vector<int>().swap(vRandom);
461  for (size_t bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) {
462  for (size_t entry = 0; entry < ADDRMAN_BUCKET_SIZE; entry++) {
463  vvNew[bucket][entry] = -1;
464  }
465  }
466  for (size_t bucket = 0; bucket < ADDRMAN_TRIED_BUCKET_COUNT; bucket++) {
467  for (size_t entry = 0; entry < ADDRMAN_BUCKET_SIZE; entry++) {
468  vvTried[bucket][entry] = -1;
469  }
470  }
471 
472  nIdCount = 0;
473  nTried = 0;
474  nNew = 0;
475  nLastGood = 1; //Initially at 1 so that "never" is strictly worse.
476  mapInfo.clear();
477  mapAddr.clear();
478  }
479 
481  {
482  Clear();
483  }
484 
486  {
487  nKey.SetNull();
488  }
489 
491  size_t size() const
492  {
493  LOCK(cs); // TODO: Cache this in an atomic to avoid this overhead
494  return vRandom.size();
495  }
496 
498  void Check()
499  {
500 #ifdef DEBUG_ADDRMAN
501  {
502  LOCK(cs);
503  int err;
504  if ((err=Check_()))
505  LogPrintf("ADDRMAN CONSISTENCY CHECK FAILED!!! err=%i\n", err);
506  }
507 #endif
508  }
509 
511  bool Add(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty = 0)
512  {
513  LOCK(cs);
514  bool fRet = false;
515  Check();
516  fRet |= Add_(addr, source, nTimePenalty);
517  Check();
518  if (fRet) {
519  LogPrint(BCLog::ADDRMAN, "Added %s from %s: %i tried, %i new\n", addr.ToStringIPPort(), source.ToString(), nTried, nNew);
520  }
521  return fRet;
522  }
523 
525  bool Add(const std::vector<CAddress> &vAddr, const CNetAddr& source, int64_t nTimePenalty = 0)
526  {
527  LOCK(cs);
528  int nAdd = 0;
529  Check();
530  for (std::vector<CAddress>::const_iterator it = vAddr.begin(); it != vAddr.end(); it++)
531  nAdd += Add_(*it, source, nTimePenalty) ? 1 : 0;
532  Check();
533  if (nAdd) {
534  LogPrint(BCLog::ADDRMAN, "Added %i addresses from %s: %i tried, %i new\n", nAdd, source.ToString(), nTried, nNew);
535  }
536  return nAdd > 0;
537  }
538 
540  void Good(const CService &addr, bool test_before_evict = true, int64_t nTime = GetAdjustedTime())
541  {
542  LOCK(cs);
543  Check();
544  Good_(addr, test_before_evict, nTime);
545  Check();
546  }
547 
549  void Attempt(const CService &addr, bool fCountFailure, int64_t nTime = GetAdjustedTime())
550  {
551  LOCK(cs);
552  Check();
553  Attempt_(addr, fCountFailure, nTime);
554  Check();
555  }
556 
559  {
560  LOCK(cs);
561  Check();
563  Check();
564  }
565 
568  {
569  CAddrInfo ret;
570  {
571  LOCK(cs);
572  Check();
573  ret = SelectTriedCollision_();
574  Check();
575  }
576  return ret;
577  }
578 
582  CAddrInfo Select(bool newOnly = false)
583  {
584  CAddrInfo addrRet;
585  {
586  LOCK(cs);
587  Check();
588  addrRet = Select_(newOnly);
589  Check();
590  }
591  return addrRet;
592  }
593 
595  std::vector<CAddress> GetAddr()
596  {
597  Check();
598  std::vector<CAddress> vAddr;
599  {
600  LOCK(cs);
601  GetAddr_(vAddr);
602  }
603  Check();
604  return vAddr;
605  }
606 
608  void Connected(const CService &addr, int64_t nTime = GetAdjustedTime())
609  {
610  LOCK(cs);
611  Check();
612  Connected_(addr, nTime);
613  Check();
614  }
615 
616  void SetServices(const CService &addr, ServiceFlags nServices)
617  {
618  LOCK(cs);
619  Check();
620  SetServices_(addr, nServices);
621  Check();
622  }
623 
624 };
625 
626 #endif // BITCOIN_ADDRMAN_H
std::vector< CAddress > GetAddr()
Return a bunch of addresses, selected at random.
Definition: addrman.h:595
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: thread_annotations.h:13
Definition: protocol.h:325
Definition: logging.h:45
ServiceFlags
Definition: protocol.h:247
void SetNull()
Definition: uint256.h:39
uint256 nKey
secret key to randomize bucket select with
Definition: addrman.h:214
CAddrInfo(const CAddress &addrIn, const CNetAddr &addrSource)
Definition: addrman.h:66
void Clear()
Definition: addrman.h:456
ADD_SERIALIZE_METHODS
Definition: addrman.h:56
Definition: netaddress.h:32
void SerializationOp(Stream &s, Operation ser_action)
Definition: addrman.h:59
void GetAddr_(std::vector< CAddress > &vAddr) EXCLUSIVE_LOCKS_REQUIRED(cs)
Select several addresses at once.
Definition: addrman.cpp:475
static void LogPrintf(const char *fmt, const Args &... args)
Definition: logging.h:144
size_t size() const
Return the number of (unique) addresses in all tables.
Definition: addrman.h:491
void Unserialize(Stream &s)
Definition: addrman.h:351
static const int64_t ADDRMAN_TEST_WINDOW
the maximum time we'll spend trying to resolve a tried table collision, in seconds
Definition: addrman.h:170
void Connected_(const CService &addr, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs)
Mark an entry as currently-connected-to.
Definition: addrman.cpp:496
int64_t nLastCountAttempt
last counted attempt (memory only)
Definition: addrman.h:31
FastRandomContext insecure_rand
Source of random numbers for randomization in inner loops.
Definition: addrman.h:217
void Good(const CService &addr, bool test_before_evict=true, int64_t nTime=GetAdjustedTime())
Mark an entry as accessible.
Definition: addrman.h:540
CAddrInfo SelectTriedCollision_() EXCLUSIVE_LOCKS_REQUIRED(cs)
Return a random to-be-evicted tried table address.
Definition: addrman.cpp:593
void Good_(const CService &addr, bool test_before_evict, int64_t time) EXCLUSIVE_LOCKS_REQUIRED(cs)
Mark an entry "good", possibly moving it from "new" to "tried".
Definition: addrman.cpp:189
#define ADDRMAN_TRIED_BUCKET_COUNT
Convenience.
Definition: addrman.h:162
#define READWRITEAS(type, obj)
Definition: serialize.h:185
bool Add(const CAddress &addr, const CNetAddr &source, int64_t nTimePenalty=0)
Add a single address.
Definition: addrman.h:511
int nRandomPos
position in vRandom
Definition: addrman.h:50
~CAddrMan()
Definition: addrman.h:485
void Attempt(const CService &addr, bool fCountFailure, int64_t nTime=GetAdjustedTime())
Mark an entry as connection attempted to.
Definition: addrman.h:549
CAddrInfo()
Definition: addrman.h:70
CAddrInfo * Find(const CNetAddr &addr, int *pnId=nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs)
Find an entry.
Definition: addrman.cpp:67
bool IsTerrible(int64_t nNow=GetAdjustedTime()) const
Determine whether the statistics about this entry are bad enough so that it can just be deleted.
Definition: addrman.cpp:32
int64_t nLastTry
last try whatsoever by us (memory only)
Definition: addrman.h:28
CAddrInfo Select(bool newOnly=false)
Definition: addrman.h:582
CAddrMan()
Definition: addrman.h:480
bool fInTried
in tried set? (memory only)
Definition: addrman.h:47
void ResolveCollisions_() EXCLUSIVE_LOCKS_REQUIRED(cs)
See if any to-be-evicted tried table entries have been tested and if so resolve the collisions.
Definition: addrman.cpp:534
void MakeTried(CAddrInfo &info, int nId) EXCLUSIVE_LOCKS_REQUIRED(cs)
Move an entry from the "new" table(s) to the "tried" table.
Definition: addrman.cpp:141
CCriticalSection cs
critical section to protect the inner data structures
Definition: addrman.h:179
const char * source
Definition: rpcconsole.cpp:53
CAddrInfo * Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId=nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: addrman.cpp:80
void ClearNew(int nUBucket, int nUBucketPos) EXCLUSIVE_LOCKS_REQUIRED(cs)
Clear a position in a "new" table. This is the only place where entries are actually deleted.
Definition: addrman.cpp:126
int GetBucketPosition(const uint256 &nKey, bool fNew, int nBucket) const
Calculate in which position of a bucket to store this entry.
Definition: addrman.cpp:26
#define LOCK(cs)
Definition: sync.h:182
std::string ToStringIPPort() const
Definition: netaddress.cpp:684
void ResolveCollisions()
See if any to-be-evicted tried table entries have been tested and if so resolve the collisions.
Definition: addrman.h:558
static void LogPrint(const BCLog::LogFlags &category, const Args &... args)
Definition: logging.h:159
void Serialize(Stream &s) const
Definition: addrman.h:301
uint256 rand256() noexcept
Definition: random.cpp:689
#define ADDRMAN_BUCKET_SIZE
Definition: addrman.h:164
int GetNewBucket(const uint256 &nKey, const CNetAddr &src) const
Calculate in which "new" bucket this entry belongs, given a certain source.
Definition: addrman.cpp:18
int GetNewBucket(const uint256 &nKey) const
Calculate in which "new" bucket this entry belongs, using its default source.
Definition: addrman.h:81
void SetServices(const CService &addr, ServiceFlags nServices)
Definition: addrman.h:616
CAddrInfo SelectTriedCollision()
Randomly select an address in tried that another address is attempting to evict.
Definition: addrman.h:567
void SetServices_(const CService &addr, ServiceFlags nServices) EXCLUSIVE_LOCKS_REQUIRED(cs)
Update an entry's service bits.
Definition: addrman.cpp:516
Definition: uint256.h:121
void Check()
Consistency check.
Definition: addrman.h:498
double GetChance(int64_t nNow=GetAdjustedTime()) const
Calculate the relative chance this entry should be given when selecting nodes to connect to.
Definition: addrman.cpp:52
void Connected(const CService &addr, int64_t nTime=GetAdjustedTime())
Mark an entry as currently-connected-to.
Definition: addrman.h:608
err
Definition: extract_strings_qt.py:62
void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2) EXCLUSIVE_LOCKS_REQUIRED(cs)
Swap two elements in vRandom.
Definition: addrman.cpp:92
bool Add_(const CAddress &addr, const CNetAddr &source, int64_t nTimePenalty) EXCLUSIVE_LOCKS_REQUIRED(cs)
Add an entry to the "new" table.
Definition: addrman.cpp:255
#define ADDRMAN_NEW_BUCKET_COUNT
Definition: addrman.h:163
int64_t GetAdjustedTime()
Definition: timedata.cpp:34
Definition: netaddress.h:140
std::set< int > m_tried_collisions
Holds addrs inserted into tried table that collide with existing entries. Test-before-evict disciplin...
Definition: addrman.h:210
Definition: random.h:98
int64_t nLastSuccess
last successful connection by us
Definition: addrman.h:38
signed long long int64_t
Definition: stdint.h:18
CAddrInfo Select_(bool newOnly) EXCLUSIVE_LOCKS_REQUIRED(cs)
Select an address to connect to, if newOnly is set to true, only the new table is selected from.
Definition: addrman.cpp:350
int nIdCount GUARDED_BY(cs)
last used nId
void Attempt_(const CService &addr, bool fCountFailure, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs)
Mark an entry as attempted to connect.
Definition: addrman.cpp:328
CNetAddr source
where knowledge about this address first came from
Definition: addrman.h:35
int nRefCount
reference count in new sets (memory only)
Definition: addrman.h:44
Definition: addrman.h:175
#define READWRITE(...)
Definition: serialize.h:184
auto it
Definition: validation.cpp:360
Definition: addrman.h:24
bool Add(const std::vector< CAddress > &vAddr, const CNetAddr &source, int64_t nTimePenalty=0)
Add multiple addresses.
Definition: addrman.h:525
int nAttempts
connection attempts since last successful attempt
Definition: addrman.h:41
void Delete(int nId) EXCLUSIVE_LOCKS_REQUIRED(cs)
Delete an entry. It must not be in tried, and have refcount 0.
Definition: addrman.cpp:112
#define ADDRMAN_NEW_BUCKETS_PER_ADDRESS
in how many buckets for entries with new addresses a single address may occur
Definition: addrman.h:138
int GetTriedBucket(const uint256 &nKey) const
Calculate in which "tried" bucket this entry belongs.
Definition: addrman.cpp:11