Bitcoin Core  0.21.1
P2P Digital Currency
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules
addrman.h
Go to the documentation of this file.
1 // Copyright (c) 2012 Pieter Wuille
2 // Copyright (c) 2012-2020 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 <clientversion.h>
10 #include <config/bitcoin-config.h>
11 #include <netaddress.h>
12 #include <protocol.h>
13 #include <random.h>
14 #include <sync.h>
15 #include <timedata.h>
16 #include <tinyformat.h>
17 #include <util/system.h>
18 
19 #include <fs.h>
20 #include <hash.h>
21 #include <iostream>
22 #include <map>
23 #include <set>
24 #include <stdint.h>
25 #include <streams.h>
26 #include <vector>
27 
31 class CAddrInfo : public CAddress
32 {
33 public:
35  int64_t nLastTry{0};
36 
38  int64_t nLastCountAttempt{0};
39 
40 private:
43 
45  int64_t nLastSuccess{0};
46 
48  int nAttempts{0};
49 
51  int nRefCount{0};
52 
54  bool fInTried{false};
55 
57  int nRandomPos{-1};
58 
59  friend class CAddrMan;
60 
61 public:
62 
64  {
65  READWRITEAS(CAddress, obj);
66  READWRITE(obj.source, obj.nLastSuccess, obj.nAttempts);
67  }
68 
69  CAddrInfo(const CAddress &addrIn, const CNetAddr &addrSource) : CAddress(addrIn), source(addrSource)
70  {
71  }
72 
73  CAddrInfo() : CAddress(), source()
74  {
75  }
76 
78  int GetTriedBucket(const uint256 &nKey, const std::vector<bool> &asmap) const;
79 
81  int GetNewBucket(const uint256 &nKey, const CNetAddr& src, const std::vector<bool> &asmap) const;
82 
84  int GetNewBucket(const uint256 &nKey, const std::vector<bool> &asmap) const
85  {
86  return GetNewBucket(nKey, source, asmap);
87  }
88 
90  int GetBucketPosition(const uint256 &nKey, bool fNew, int nBucket) const;
91 
93  bool IsTerrible(int64_t nNow = GetAdjustedTime()) const;
94 
96  double GetChance(int64_t nNow = GetAdjustedTime()) const;
97 };
98 
125 #define ADDRMAN_TRIED_BUCKET_COUNT_LOG2 8
127 
129 #define ADDRMAN_NEW_BUCKET_COUNT_LOG2 10
130 
132 #define ADDRMAN_BUCKET_SIZE_LOG2 6
133 
135 #define ADDRMAN_TRIED_BUCKETS_PER_GROUP 8
136 
138 #define ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP 64
139 
141 #define ADDRMAN_NEW_BUCKETS_PER_ADDRESS 8
142 
144 #define ADDRMAN_HORIZON_DAYS 30
145 
147 #define ADDRMAN_RETRIES 3
148 
150 #define ADDRMAN_MAX_FAILURES 10
151 
153 #define ADDRMAN_MIN_FAIL_DAYS 7
154 
156 #define ADDRMAN_REPLACEMENT_HOURS 4
157 
159 #define ADDRMAN_TRIED_BUCKET_COUNT (1 << ADDRMAN_TRIED_BUCKET_COUNT_LOG2)
160 #define ADDRMAN_NEW_BUCKET_COUNT (1 << ADDRMAN_NEW_BUCKET_COUNT_LOG2)
161 #define ADDRMAN_BUCKET_SIZE (1 << ADDRMAN_BUCKET_SIZE_LOG2)
162 
164 #define ADDRMAN_SET_TRIED_COLLISION_SIZE 10
165 
167 static const int64_t ADDRMAN_TEST_WINDOW = 40*60; // 40 minutes
168 
172 class CAddrMan
173 {
174 friend class CAddrManTest;
175 protected:
178 
179 private:
181  enum Format : uint8_t {
184  V2_ASMAP = 2,
185  V3_BIP155 = 3,
186  };
187 
193  static constexpr Format FILE_FORMAT = Format::V3_BIP155;
194 
200  static constexpr uint8_t INCOMPATIBILITY_BASE = 32;
201 
203  int nIdCount GUARDED_BY(cs);
204 
206  std::map<int, CAddrInfo> mapInfo GUARDED_BY(cs);
207 
209  std::map<CNetAddr, int> mapAddr GUARDED_BY(cs);
210 
212  std::vector<int> vRandom GUARDED_BY(cs);
213 
214  // number of "tried" entries
215  int nTried GUARDED_BY(cs);
216 
219 
221  int nNew GUARDED_BY(cs);
222 
225 
227  int64_t nLastGood GUARDED_BY(cs);
228 
230  std::set<int> m_tried_collisions;
231 
232 protected:
235 
238 
240  CAddrInfo* Find(const CNetAddr& addr, int *pnId = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs);
241 
244  CAddrInfo* Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs);
245 
247  void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2) EXCLUSIVE_LOCKS_REQUIRED(cs);
248 
250  void MakeTried(CAddrInfo& info, int nId) EXCLUSIVE_LOCKS_REQUIRED(cs);
251 
253  void Delete(int nId) EXCLUSIVE_LOCKS_REQUIRED(cs);
254 
256  void ClearNew(int nUBucket, int nUBucketPos) EXCLUSIVE_LOCKS_REQUIRED(cs);
257 
259  void Good_(const CService &addr, bool test_before_evict, int64_t time) EXCLUSIVE_LOCKS_REQUIRED(cs);
260 
262  bool Add_(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty) EXCLUSIVE_LOCKS_REQUIRED(cs);
263 
265  void Attempt_(const CService &addr, bool fCountFailure, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs);
266 
268  CAddrInfo Select_(bool newOnly) EXCLUSIVE_LOCKS_REQUIRED(cs);
269 
272 
275 
276 #ifdef DEBUG_ADDRMAN
277  int Check_() EXCLUSIVE_LOCKS_REQUIRED(cs);
279 #endif
280 
282  void GetAddr_(std::vector<CAddress> &vAddr, size_t max_addresses, size_t max_pct) EXCLUSIVE_LOCKS_REQUIRED(cs);
283 
285  void Connected_(const CService &addr, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs);
286 
288  void SetServices_(const CService &addr, ServiceFlags nServices) EXCLUSIVE_LOCKS_REQUIRED(cs);
289 
290 public:
291  // Compressed IP->ASN mapping, loaded from a file when a node starts.
292  // Should be always empty if no file was provided.
293  // This mapping is then used for bucketing nodes in Addrman.
294  //
295  // If asmap is provided, nodes will be bucketed by
296  // AS they belong to, in order to make impossible for a node
297  // to connect to several nodes hosted in a single AS.
298  // This is done in response to Erebus attack, but also to generally
299  // diversify the connections every node creates,
300  // especially useful when a large fraction of nodes
301  // operate under a couple of cloud providers.
302  //
303  // If a new asmap was provided, the existing records
304  // would be re-bucketed accordingly.
305  std::vector<bool> m_asmap;
306 
307  // Read asmap from provided binary file
308  static std::vector<bool> DecodeAsmap(fs::path path);
309 
310 
350  template <typename Stream>
351  void Serialize(Stream& s_) const
352  {
353  LOCK(cs);
354 
355  // Always serialize in the latest version (FILE_FORMAT).
356 
357  OverrideStream<Stream> s(&s_, s_.GetType(), s_.GetVersion() | ADDRV2_FORMAT);
358 
359  s << static_cast<uint8_t>(FILE_FORMAT);
360 
361  // Increment `lowest_compatible` iff a newly introduced format is incompatible with
362  // the previous one.
363  static constexpr uint8_t lowest_compatible = Format::V3_BIP155;
364  s << static_cast<uint8_t>(INCOMPATIBILITY_BASE + lowest_compatible);
365 
366  s << nKey;
367  s << nNew;
368  s << nTried;
369 
370  int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30);
371  s << nUBuckets;
372  std::map<int, int> mapUnkIds;
373  int nIds = 0;
374  for (const auto& entry : mapInfo) {
375  mapUnkIds[entry.first] = nIds;
376  const CAddrInfo &info = entry.second;
377  if (info.nRefCount) {
378  assert(nIds != nNew); // this means nNew was wrong, oh ow
379  s << info;
380  nIds++;
381  }
382  }
383  nIds = 0;
384  for (const auto& entry : mapInfo) {
385  const CAddrInfo &info = entry.second;
386  if (info.fInTried) {
387  assert(nIds != nTried); // this means nTried was wrong, oh ow
388  s << info;
389  nIds++;
390  }
391  }
392  for (int bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) {
393  int nSize = 0;
394  for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
395  if (vvNew[bucket][i] != -1)
396  nSize++;
397  }
398  s << nSize;
399  for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
400  if (vvNew[bucket][i] != -1) {
401  int nIndex = mapUnkIds[vvNew[bucket][i]];
402  s << nIndex;
403  }
404  }
405  }
406  // Store asmap version after bucket entries so that it
407  // can be ignored by older clients for backward compatibility.
408  uint256 asmap_version;
409  if (m_asmap.size() != 0) {
410  asmap_version = SerializeHash(m_asmap);
411  }
412  s << asmap_version;
413  }
414 
415  template <typename Stream>
416  void Unserialize(Stream& s_)
417  {
418  LOCK(cs);
419 
420  Clear();
421 
422  Format format;
423  s_ >> Using<CustomUintFormatter<1>>(format);
424 
425  int stream_version = s_.GetVersion();
426  if (format >= Format::V3_BIP155) {
427  // Add ADDRV2_FORMAT to the version so that the CNetAddr and CAddress
428  // unserialize methods know that an address in addrv2 format is coming.
429  stream_version |= ADDRV2_FORMAT;
430  }
431 
432  OverrideStream<Stream> s(&s_, s_.GetType(), stream_version);
433 
434  uint8_t compat;
435  s >> compat;
436  const uint8_t lowest_compatible = compat - INCOMPATIBILITY_BASE;
437  if (lowest_compatible > FILE_FORMAT) {
438  throw std::ios_base::failure(strprintf(
439  "Unsupported format of addrman database: %u. It is compatible with formats >=%u, "
440  "but the maximum supported by this version of %s is %u.",
441  format, lowest_compatible, PACKAGE_NAME, static_cast<uint8_t>(FILE_FORMAT)));
442  }
443 
444  s >> nKey;
445  s >> nNew;
446  s >> nTried;
447  int nUBuckets = 0;
448  s >> nUBuckets;
449  if (format >= Format::V1_DETERMINISTIC) {
450  nUBuckets ^= (1 << 30);
451  }
452 
454  throw std::ios_base::failure("Corrupt CAddrMan serialization, nNew exceeds limit.");
455  }
456 
457  if (nTried > ADDRMAN_TRIED_BUCKET_COUNT * ADDRMAN_BUCKET_SIZE) {
458  throw std::ios_base::failure("Corrupt CAddrMan serialization, nTried exceeds limit.");
459  }
460 
461  // Deserialize entries from the new table.
462  for (int n = 0; n < nNew; n++) {
463  CAddrInfo &info = mapInfo[n];
464  s >> info;
465  mapAddr[info] = n;
466  info.nRandomPos = vRandom.size();
467  vRandom.push_back(n);
468  }
469  nIdCount = nNew;
470 
471  // Deserialize entries from the tried table.
472  int nLost = 0;
473  for (int n = 0; n < nTried; n++) {
474  CAddrInfo info;
475  s >> info;
476  int nKBucket = info.GetTriedBucket(nKey, m_asmap);
477  int nKBucketPos = info.GetBucketPosition(nKey, false, nKBucket);
478  if (vvTried[nKBucket][nKBucketPos] == -1) {
479  info.nRandomPos = vRandom.size();
480  info.fInTried = true;
481  vRandom.push_back(nIdCount);
482  mapInfo[nIdCount] = info;
483  mapAddr[info] = nIdCount;
484  vvTried[nKBucket][nKBucketPos] = nIdCount;
485  nIdCount++;
486  } else {
487  nLost++;
488  }
489  }
490  nTried -= nLost;
491 
492  // Store positions in the new table buckets to apply later (if possible).
493  std::map<int, int> entryToBucket; // Represents which entry belonged to which bucket when serializing
494 
495  for (int bucket = 0; bucket < nUBuckets; bucket++) {
496  int nSize = 0;
497  s >> nSize;
498  for (int n = 0; n < nSize; n++) {
499  int nIndex = 0;
500  s >> nIndex;
501  if (nIndex >= 0 && nIndex < nNew) {
502  entryToBucket[nIndex] = bucket;
503  }
504  }
505  }
506 
507  uint256 supplied_asmap_version;
508  if (m_asmap.size() != 0) {
509  supplied_asmap_version = SerializeHash(m_asmap);
510  }
511  uint256 serialized_asmap_version;
512  if (format >= Format::V2_ASMAP) {
513  s >> serialized_asmap_version;
514  }
515 
516  for (int n = 0; n < nNew; n++) {
517  CAddrInfo &info = mapInfo[n];
518  int bucket = entryToBucket[n];
519  int nUBucketPos = info.GetBucketPosition(nKey, true, bucket);
520  if (format >= Format::V2_ASMAP && nUBuckets == ADDRMAN_NEW_BUCKET_COUNT && vvNew[bucket][nUBucketPos] == -1 &&
521  info.nRefCount < ADDRMAN_NEW_BUCKETS_PER_ADDRESS && serialized_asmap_version == supplied_asmap_version) {
522  // Bucketing has not changed, using existing bucket positions for the new table
523  vvNew[bucket][nUBucketPos] = n;
524  info.nRefCount++;
525  } else {
526  // In case the new table data cannot be used (format unknown, bucket count wrong or new asmap),
527  // try to give them a reference based on their primary source address.
528  LogPrint(BCLog::ADDRMAN, "Bucketing method was updated, re-bucketing addrman entries from disk\n");
529  bucket = info.GetNewBucket(nKey, m_asmap);
530  nUBucketPos = info.GetBucketPosition(nKey, true, bucket);
531  if (vvNew[bucket][nUBucketPos] == -1) {
532  vvNew[bucket][nUBucketPos] = n;
533  info.nRefCount++;
534  }
535  }
536  }
537 
538  // Prune new entries with refcount 0 (as a result of collisions).
539  int nLostUnk = 0;
540  for (std::map<int, CAddrInfo>::const_iterator it = mapInfo.begin(); it != mapInfo.end(); ) {
541  if (it->second.fInTried == false && it->second.nRefCount == 0) {
542  std::map<int, CAddrInfo>::const_iterator itCopy = it++;
543  Delete(itCopy->first);
544  nLostUnk++;
545  } else {
546  it++;
547  }
548  }
549  if (nLost + nLostUnk > 0) {
550  LogPrint(BCLog::ADDRMAN, "addrman lost %i new and %i tried addresses due to collisions\n", nLostUnk, nLost);
551  }
552 
553  Check();
554  }
555 
556  void Clear()
557  {
558  LOCK(cs);
559  std::vector<int>().swap(vRandom);
560  nKey = insecure_rand.rand256();
561  for (size_t bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) {
562  for (size_t entry = 0; entry < ADDRMAN_BUCKET_SIZE; entry++) {
563  vvNew[bucket][entry] = -1;
564  }
565  }
566  for (size_t bucket = 0; bucket < ADDRMAN_TRIED_BUCKET_COUNT; bucket++) {
567  for (size_t entry = 0; entry < ADDRMAN_BUCKET_SIZE; entry++) {
568  vvTried[bucket][entry] = -1;
569  }
570  }
571 
572  nIdCount = 0;
573  nTried = 0;
574  nNew = 0;
575  nLastGood = 1; //Initially at 1 so that "never" is strictly worse.
576  mapInfo.clear();
577  mapAddr.clear();
578  }
579 
581  {
582  Clear();
583  }
584 
586  {
587  nKey.SetNull();
588  }
589 
591  size_t size() const
592  {
593  LOCK(cs); // TODO: Cache this in an atomic to avoid this overhead
594  return vRandom.size();
595  }
596 
598  void Check()
599  {
600 #ifdef DEBUG_ADDRMAN
601  {
602  LOCK(cs);
603  int err;
604  if ((err=Check_()))
605  LogPrintf("ADDRMAN CONSISTENCY CHECK FAILED!!! err=%i\n", err);
606  }
607 #endif
608  }
609 
611  bool Add(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty = 0)
612  {
613  LOCK(cs);
614  bool fRet = false;
615  Check();
616  fRet |= Add_(addr, source, nTimePenalty);
617  Check();
618  if (fRet) {
619  LogPrint(BCLog::ADDRMAN, "Added %s from %s: %i tried, %i new\n", addr.ToStringIPPort(), source.ToString(), nTried, nNew);
620  }
621  return fRet;
622  }
623 
625  bool Add(const std::vector<CAddress> &vAddr, const CNetAddr& source, int64_t nTimePenalty = 0)
626  {
627  LOCK(cs);
628  int nAdd = 0;
629  Check();
630  for (std::vector<CAddress>::const_iterator it = vAddr.begin(); it != vAddr.end(); it++)
631  nAdd += Add_(*it, source, nTimePenalty) ? 1 : 0;
632  Check();
633  if (nAdd) {
634  LogPrint(BCLog::ADDRMAN, "Added %i addresses from %s: %i tried, %i new\n", nAdd, source.ToString(), nTried, nNew);
635  }
636  return nAdd > 0;
637  }
638 
640  void Good(const CService &addr, bool test_before_evict = true, int64_t nTime = GetAdjustedTime())
641  {
642  LOCK(cs);
643  Check();
644  Good_(addr, test_before_evict, nTime);
645  Check();
646  }
647 
649  void Attempt(const CService &addr, bool fCountFailure, int64_t nTime = GetAdjustedTime())
650  {
651  LOCK(cs);
652  Check();
653  Attempt_(addr, fCountFailure, nTime);
654  Check();
655  }
656 
659  {
660  LOCK(cs);
661  Check();
663  Check();
664  }
665 
668  {
669  CAddrInfo ret;
670  {
671  LOCK(cs);
672  Check();
673  ret = SelectTriedCollision_();
674  Check();
675  }
676  return ret;
677  }
678 
682  CAddrInfo Select(bool newOnly = false)
683  {
684  CAddrInfo addrRet;
685  {
686  LOCK(cs);
687  Check();
688  addrRet = Select_(newOnly);
689  Check();
690  }
691  return addrRet;
692  }
693 
695  std::vector<CAddress> GetAddr(size_t max_addresses, size_t max_pct)
696  {
697  Check();
698  std::vector<CAddress> vAddr;
699  {
700  LOCK(cs);
701  GetAddr_(vAddr, max_addresses, max_pct);
702  }
703  Check();
704  return vAddr;
705  }
706 
708  void Connected(const CService &addr, int64_t nTime = GetAdjustedTime())
709  {
710  LOCK(cs);
711  Check();
712  Connected_(addr, nTime);
713  Check();
714  }
715 
716  void SetServices(const CService &addr, ServiceFlags nServices)
717  {
718  LOCK(cs);
719  Check();
720  SetServices_(addr, nServices);
721  Check();
722  }
723 
724 };
725 
726 #endif // BITCOIN_ADDRMAN_H
int nRefCount
reference count in new sets (memory only)
Definition: addrman.h:51
for files including asmap version
Definition: addrman.h:184
friend class CAddrManTest
Definition: addrman.h:174
ServiceFlags
nServices flags
Definition: protocol.h:269
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:545
CAddrInfo Select(bool newOnly=false)
Choose an address to connect to.
Definition: addrman.h:682
void SetNull()
Definition: uint256.h:39
#define LogPrint(category,...)
Definition: logging.h:182
void Attempt(const CService &addr, bool fCountFailure, int64_t nTime=GetAdjustedTime())
Mark an entry as connection attempted to.
Definition: addrman.h:649
int GetBucketPosition(const uint256 &nKey, bool fNew, int nBucket) const
Calculate in which position of a bucket to store this entry.
Definition: addrman.cpp:33
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1164
static constexpr uint8_t INCOMPATIBILITY_BASE
The initial value of a field that is incremented every time an incompatible format change is made (su...
Definition: addrman.h:200
CAddrInfo * Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId=nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs)
find an entry, creating it if necessary.
Definition: addrman.cpp:87
static void LogPrintf(const char *fmt, const Args &...args)
Definition: logging.h:166
void SetServices_(const CService &addr, ServiceFlags nServices) EXCLUSIVE_LOCKS_REQUIRED(cs)
Update an entry's service bits.
Definition: addrman.cpp:527
~CAddrMan()
Definition: addrman.h:585
std::string ToStringIPPort() const
Definition: netaddress.cpp:972
int GetNewBucket(const uint256 &nKey, const CNetAddr &src, const std::vector< bool > &asmap) const
Calculate in which "new" bucket this entry belongs, given a certain source.
Definition: addrman.cpp:22
void Delete(int nId) EXCLUSIVE_LOCKS_REQUIRED(cs)
Delete an entry. It must not be in tried, and have refcount 0.
Definition: addrman.cpp:119
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:196
void Attempt_(const CService &addr, bool fCountFailure, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs)
Mark an entry as attempted to connect.
Definition: addrman.cpp:335
int nAttempts
connection attempts since last successful attempt
Definition: addrman.h:48
uint256 rand256() noexcept
generate a random uint256.
Definition: random.cpp:616
same as V2_ASMAP plus addresses are in BIP155 format
Definition: addrman.h:185
#define PACKAGE_NAME
void format(std::ostream &out, const char *fmt, const Args &...args)
Format list of arguments to the stream according to given format string.
Definition: tinyformat.h:1062
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:167
for pre-asmap files
Definition: addrman.h:183
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:262
int GetNewBucket(const uint256 &nKey, const std::vector< bool > &asmap) const
Calculate in which "new" bucket this entry belongs, using its default source.
Definition: addrman.h:84
std::set< int > m_tried_collisions
Holds addrs inserted into tried table that collide with existing entries. Test-before-evict disciplin...
Definition: addrman.h:230
int nIdCount GUARDED_BY(cs)
last used nId
void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2) EXCLUSIVE_LOCKS_REQUIRED(cs)
Swap two elements in vRandom.
Definition: addrman.cpp:99
int nRandomPos
position in vRandom
Definition: addrman.h:57
CAddrInfo SelectTriedCollision_() EXCLUSIVE_LOCKS_REQUIRED(cs)
Return a random to-be-evicted tried table address.
Definition: addrman.cpp:604
bool Add(const CAddress &addr, const CNetAddr &source, int64_t nTimePenalty=0)
Add a single address.
Definition: addrman.h:611
#define ADDRMAN_TRIED_BUCKET_COUNT
Convenience.
Definition: addrman.h:159
#define READWRITEAS(type, obj)
Definition: serialize.h:176
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:59
bool fInTried
in tried set? (memory only)
Definition: addrman.h:54
Stochastical (IP) address manager.
Definition: addrman.h:172
static constexpr Format FILE_FORMAT
The maximum format this software knows it can unserialize.
Definition: addrman.h:193
static constexpr int ADDRV2_FORMAT
A flag that is ORed into the protocol version to designate that addresses should be serialized in (un...
Definition: netaddress.h:32
RecursiveMutex cs
critical section to protect the inner data structures
Definition: addrman.h:177
uint256 SerializeHash(const T &obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION)
Compute the 256-bit hash of an object's serialization.
Definition: hash.h:192
size_t size() const
Return the number of (unique) addresses in all tables.
Definition: addrman.h:591
Extended statistics about a CAddress.
Definition: addrman.h:31
FastRandomContext insecure_rand
Source of random numbers for randomization in inner loops.
Definition: addrman.h:237
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:148
#define LOCK(cs)
Definition: sync.h:230
historic format, before commit e6b343d88
Definition: addrman.h:182
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:523
Fast randomness source.
Definition: random.h:119
void Check()
Consistency check.
Definition: addrman.h:598
void Unserialize(Stream &s_)
Definition: addrman.h:416
A CService with information about it as peer.
Definition: protocol.h:360
#define ADDRMAN_BUCKET_SIZE
Definition: addrman.h:161
Format
Serialization versions.
Definition: addrman.h:181
int GetTriedBucket(const uint256 &nKey, const std::vector< bool > &asmap) const
Calculate in which "tried" bucket this entry belongs.
Definition: addrman.cpp:12
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:133
void Serialize(Stream &s_) const
Serialized format.
Definition: addrman.h:351
CAddrInfo()
Definition: addrman.h:73
Network address.
Definition: netaddress.h:119
256-bit opaque blob.
Definition: uint256.h:124
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:49
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:357
SERIALIZE_METHODS(CAddrInfo, obj)
Definition: addrman.h:63
void Connected_(const CService &addr, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs)
Mark an entry as currently-connected-to.
Definition: addrman.cpp:507
void Clear()
Definition: addrman.h:556
CAddrMan()
Definition: addrman.h:580
CAddrInfo(const CAddress &addrIn, const CNetAddr &addrSource)
Definition: addrman.h:69
#define ADDRMAN_NEW_BUCKET_COUNT
Definition: addrman.h:160
int64_t GetAdjustedTime()
Definition: timedata.cpp:34
CAddrInfo SelectTriedCollision()
Randomly select an address in tried that another address is attempting to evict.
Definition: addrman.h:667
std::vector< CAddress > GetAddr(size_t max_addresses, size_t max_pct)
Return a bunch of addresses, selected at random.
Definition: addrman.h:695
int64_t nLastCountAttempt
last counted attempt (memory only)
Definition: addrman.h:38
void ResolveCollisions()
See if any to-be-evicted tried table entries have been tested and if so resolve the collisions...
Definition: addrman.h:658
static std::vector< bool > DecodeAsmap(fs::path path)
Definition: addrman.cpp:631
std::vector< bool > m_asmap
Definition: addrman.h:305
bool Add(const std::vector< CAddress > &vAddr, const CNetAddr &source, int64_t nTimePenalty=0)
Add multiple addresses.
Definition: addrman.h:625
void Good(const CService &addr, bool test_before_evict=true, int64_t nTime=GetAdjustedTime())
Mark an entry as accessible.
Definition: addrman.h:640
std::string ToString() const
Definition: netaddress.cpp:580
void SetServices(const CService &addr, ServiceFlags nServices)
Definition: addrman.h:716
uint256 nKey
secret key to randomize bucket select with
Definition: addrman.h:234
void GetAddr_(std::vector< CAddress > &vAddr, size_t max_addresses, size_t max_pct) EXCLUSIVE_LOCKS_REQUIRED(cs)
Select several addresses at once.
Definition: addrman.cpp:482
#define READWRITE(...)
Definition: serialize.h:175
void Connected(const CService &addr, int64_t nTime=GetAdjustedTime())
Mark an entry as currently-connected-to.
Definition: addrman.h:708
auto it
Definition: validation.cpp:381
int64_t nLastSuccess
last successful connection by us
Definition: addrman.h:45
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:39
int64_t nLastTry
last try whatsoever by us (memory only)
Definition: addrman.h:35
#define ADDRMAN_NEW_BUCKETS_PER_ADDRESS
in how many buckets for entries with new addresses a single address may occur
Definition: addrman.h:141
CNetAddr source
where knowledge about this address first came from
Definition: addrman.h:42
CAddrInfo * Find(const CNetAddr &addr, int *pnId=nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs)
Find an entry.
Definition: addrman.cpp:74