Bitcoin Core  21.99.0
P2P Digital Currency
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 
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 
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 
295  void Connected_(const CService& addr, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs);
296 
298  void SetServices_(const CService &addr, ServiceFlags nServices) EXCLUSIVE_LOCKS_REQUIRED(cs);
299 
300 public:
301  // Compressed IP->ASN mapping, loaded from a file when a node starts.
302  // Should be always empty if no file was provided.
303  // This mapping is then used for bucketing nodes in Addrman.
304  //
305  // If asmap is provided, nodes will be bucketed by
306  // AS they belong to, in order to make impossible for a node
307  // to connect to several nodes hosted in a single AS.
308  // This is done in response to Erebus attack, but also to generally
309  // diversify the connections every node creates,
310  // especially useful when a large fraction of nodes
311  // operate under a couple of cloud providers.
312  //
313  // If a new asmap was provided, the existing records
314  // would be re-bucketed accordingly.
315  std::vector<bool> m_asmap;
316 
317  // Read asmap from provided binary file
318  static std::vector<bool> DecodeAsmap(fs::path path);
319 
320 
358  template <typename Stream>
359  void Serialize(Stream& s_) const
360  {
361  LOCK(cs);
362 
363  // Always serialize in the latest version (FILE_FORMAT).
364 
365  OverrideStream<Stream> s(&s_, s_.GetType(), s_.GetVersion() | ADDRV2_FORMAT);
366 
367  s << static_cast<uint8_t>(FILE_FORMAT);
368 
369  // Increment `lowest_compatible` iff a newly introduced format is incompatible with
370  // the previous one.
371  static constexpr uint8_t lowest_compatible = Format::V3_BIP155;
372  s << static_cast<uint8_t>(INCOMPATIBILITY_BASE + lowest_compatible);
373 
374  s << nKey;
375  s << nNew;
376  s << nTried;
377 
378  int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30);
379  s << nUBuckets;
380  std::map<int, int> mapUnkIds;
381  int nIds = 0;
382  for (const auto& entry : mapInfo) {
383  mapUnkIds[entry.first] = nIds;
384  const CAddrInfo &info = entry.second;
385  if (info.nRefCount) {
386  assert(nIds != nNew); // this means nNew was wrong, oh ow
387  s << info;
388  nIds++;
389  }
390  }
391  nIds = 0;
392  for (const auto& entry : mapInfo) {
393  const CAddrInfo &info = entry.second;
394  if (info.fInTried) {
395  assert(nIds != nTried); // this means nTried was wrong, oh ow
396  s << info;
397  nIds++;
398  }
399  }
400  for (int bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) {
401  int nSize = 0;
402  for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
403  if (vvNew[bucket][i] != -1)
404  nSize++;
405  }
406  s << nSize;
407  for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
408  if (vvNew[bucket][i] != -1) {
409  int nIndex = mapUnkIds[vvNew[bucket][i]];
410  s << nIndex;
411  }
412  }
413  }
414  // Store asmap checksum after bucket entries so that it
415  // can be ignored by older clients for backward compatibility.
416  uint256 asmap_checksum;
417  if (m_asmap.size() != 0) {
418  asmap_checksum = SerializeHash(m_asmap);
419  }
420  s << asmap_checksum;
421  }
422 
423  template <typename Stream>
424  void Unserialize(Stream& s_)
425  {
426  LOCK(cs);
427 
428  Clear();
429 
430  Format format;
431  s_ >> Using<CustomUintFormatter<1>>(format);
432 
433  int stream_version = s_.GetVersion();
434  if (format >= Format::V3_BIP155) {
435  // Add ADDRV2_FORMAT to the version so that the CNetAddr and CAddress
436  // unserialize methods know that an address in addrv2 format is coming.
437  stream_version |= ADDRV2_FORMAT;
438  }
439 
440  OverrideStream<Stream> s(&s_, s_.GetType(), stream_version);
441 
442  uint8_t compat;
443  s >> compat;
444  const uint8_t lowest_compatible = compat - INCOMPATIBILITY_BASE;
445  if (lowest_compatible > FILE_FORMAT) {
446  throw std::ios_base::failure(strprintf(
447  "Unsupported format of addrman database: %u. It is compatible with formats >=%u, "
448  "but the maximum supported by this version of %s is %u.",
449  format, lowest_compatible, PACKAGE_NAME, static_cast<uint8_t>(FILE_FORMAT)));
450  }
451 
452  s >> nKey;
453  s >> nNew;
454  s >> nTried;
455  int nUBuckets = 0;
456  s >> nUBuckets;
457  if (format >= Format::V1_DETERMINISTIC) {
458  nUBuckets ^= (1 << 30);
459  }
460 
462  throw std::ios_base::failure("Corrupt CAddrMan serialization, nNew exceeds limit.");
463  }
464 
466  throw std::ios_base::failure("Corrupt CAddrMan serialization, nTried exceeds limit.");
467  }
468 
469  // Deserialize entries from the new table.
470  for (int n = 0; n < nNew; n++) {
471  CAddrInfo &info = mapInfo[n];
472  s >> info;
473  mapAddr[info] = n;
474  info.nRandomPos = vRandom.size();
475  vRandom.push_back(n);
476  }
477  nIdCount = nNew;
478 
479  // Deserialize entries from the tried table.
480  int nLost = 0;
481  for (int n = 0; n < nTried; n++) {
482  CAddrInfo info;
483  s >> info;
484  int nKBucket = info.GetTriedBucket(nKey, m_asmap);
485  int nKBucketPos = info.GetBucketPosition(nKey, false, nKBucket);
486  if (vvTried[nKBucket][nKBucketPos] == -1) {
487  info.nRandomPos = vRandom.size();
488  info.fInTried = true;
489  vRandom.push_back(nIdCount);
490  mapInfo[nIdCount] = info;
491  mapAddr[info] = nIdCount;
492  vvTried[nKBucket][nKBucketPos] = nIdCount;
493  nIdCount++;
494  } else {
495  nLost++;
496  }
497  }
498  nTried -= nLost;
499 
500  // Store positions in the new table buckets to apply later (if possible).
501  // An entry may appear in up to ADDRMAN_NEW_BUCKETS_PER_ADDRESS buckets,
502  // so we store all bucket-entry_index pairs to iterate through later.
503  std::vector<std::pair<int, int>> bucket_entries;
504 
505  for (int bucket = 0; bucket < nUBuckets; ++bucket) {
506  int num_entries{0};
507  s >> num_entries;
508  for (int n = 0; n < num_entries; ++n) {
509  int entry_index{0};
510  s >> entry_index;
511  if (entry_index >= 0 && entry_index < nNew) {
512  bucket_entries.emplace_back(bucket, entry_index);
513  }
514  }
515  }
516 
517  // If the bucket count and asmap checksum haven't changed, then attempt
518  // to restore the entries to the buckets/positions they were in before
519  // serialization.
520  uint256 supplied_asmap_checksum;
521  if (m_asmap.size() != 0) {
522  supplied_asmap_checksum = SerializeHash(m_asmap);
523  }
524  uint256 serialized_asmap_checksum;
525  if (format >= Format::V2_ASMAP) {
526  s >> serialized_asmap_checksum;
527  }
528  const bool restore_bucketing{nUBuckets == ADDRMAN_NEW_BUCKET_COUNT &&
529  serialized_asmap_checksum == supplied_asmap_checksum};
530 
531  if (!restore_bucketing) {
532  LogPrint(BCLog::ADDRMAN, "Bucketing method was updated, re-bucketing addrman entries from disk\n");
533  }
534 
535  for (auto bucket_entry : bucket_entries) {
536  int bucket{bucket_entry.first};
537  const int entry_index{bucket_entry.second};
538  CAddrInfo& info = mapInfo[entry_index];
539 
540  // The entry shouldn't appear in more than
541  // ADDRMAN_NEW_BUCKETS_PER_ADDRESS. If it has already, just skip
542  // this bucket_entry.
543  if (info.nRefCount >= ADDRMAN_NEW_BUCKETS_PER_ADDRESS) continue;
544 
545  int bucket_position = info.GetBucketPosition(nKey, true, bucket);
546  if (restore_bucketing && vvNew[bucket][bucket_position] == -1) {
547  // Bucketing has not changed, using existing bucket positions for the new table
548  vvNew[bucket][bucket_position] = entry_index;
549  ++info.nRefCount;
550  } else {
551  // In case the new table data cannot be used (bucket count wrong or new asmap),
552  // try to give them a reference based on their primary source address.
553  bucket = info.GetNewBucket(nKey, m_asmap);
554  bucket_position = info.GetBucketPosition(nKey, true, bucket);
555  if (vvNew[bucket][bucket_position] == -1) {
556  vvNew[bucket][bucket_position] = entry_index;
557  ++info.nRefCount;
558  }
559  }
560  }
561 
562  // Prune new entries with refcount 0 (as a result of collisions).
563  int nLostUnk = 0;
564  for (std::map<int, CAddrInfo>::const_iterator it = mapInfo.begin(); it != mapInfo.end(); ) {
565  if (it->second.fInTried == false && it->second.nRefCount == 0) {
566  std::map<int, CAddrInfo>::const_iterator itCopy = it++;
567  Delete(itCopy->first);
568  nLostUnk++;
569  } else {
570  it++;
571  }
572  }
573  if (nLost + nLostUnk > 0) {
574  LogPrint(BCLog::ADDRMAN, "addrman lost %i new and %i tried addresses due to collisions\n", nLostUnk, nLost);
575  }
576 
577  Check();
578  }
579 
580  void Clear()
581  {
582  LOCK(cs);
583  std::vector<int>().swap(vRandom);
585  for (size_t bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) {
586  for (size_t entry = 0; entry < ADDRMAN_BUCKET_SIZE; entry++) {
587  vvNew[bucket][entry] = -1;
588  }
589  }
590  for (size_t bucket = 0; bucket < ADDRMAN_TRIED_BUCKET_COUNT; bucket++) {
591  for (size_t entry = 0; entry < ADDRMAN_BUCKET_SIZE; entry++) {
592  vvTried[bucket][entry] = -1;
593  }
594  }
595 
596  nIdCount = 0;
597  nTried = 0;
598  nNew = 0;
599  nLastGood = 1; //Initially at 1 so that "never" is strictly worse.
600  mapInfo.clear();
601  mapAddr.clear();
602  }
603 
605  {
606  Clear();
607  }
608 
610  {
611  nKey.SetNull();
612  }
613 
615  size_t size() const
616  {
617  LOCK(cs); // TODO: Cache this in an atomic to avoid this overhead
618  return vRandom.size();
619  }
620 
622  void Check()
623  {
624 #ifdef DEBUG_ADDRMAN
625  {
626  LOCK(cs);
627  int err;
628  if ((err=Check_()))
629  LogPrintf("ADDRMAN CONSISTENCY CHECK FAILED!!! err=%i\n", err);
630  }
631 #endif
632  }
633 
635  bool Add(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty = 0)
636  {
637  LOCK(cs);
638  bool fRet = false;
639  Check();
640  fRet |= Add_(addr, source, nTimePenalty);
641  Check();
642  if (fRet) {
643  LogPrint(BCLog::ADDRMAN, "Added %s from %s: %i tried, %i new\n", addr.ToStringIPPort(), source.ToString(), nTried, nNew);
644  }
645  return fRet;
646  }
647 
649  bool Add(const std::vector<CAddress> &vAddr, const CNetAddr& source, int64_t nTimePenalty = 0)
650  {
651  LOCK(cs);
652  int nAdd = 0;
653  Check();
654  for (std::vector<CAddress>::const_iterator it = vAddr.begin(); it != vAddr.end(); it++)
655  nAdd += Add_(*it, source, nTimePenalty) ? 1 : 0;
656  Check();
657  if (nAdd) {
658  LogPrint(BCLog::ADDRMAN, "Added %i addresses from %s: %i tried, %i new\n", nAdd, source.ToString(), nTried, nNew);
659  }
660  return nAdd > 0;
661  }
662 
664  void Good(const CService &addr, bool test_before_evict = true, int64_t nTime = GetAdjustedTime())
665  {
666  LOCK(cs);
667  Check();
668  Good_(addr, test_before_evict, nTime);
669  Check();
670  }
671 
673  void Attempt(const CService &addr, bool fCountFailure, int64_t nTime = GetAdjustedTime())
674  {
675  LOCK(cs);
676  Check();
677  Attempt_(addr, fCountFailure, nTime);
678  Check();
679  }
680 
683  {
684  LOCK(cs);
685  Check();
687  Check();
688  }
689 
692  {
693  CAddrInfo ret;
694  {
695  LOCK(cs);
696  Check();
697  ret = SelectTriedCollision_();
698  Check();
699  }
700  return ret;
701  }
702 
706  CAddrInfo Select(bool newOnly = false)
707  {
708  CAddrInfo addrRet;
709  {
710  LOCK(cs);
711  Check();
712  addrRet = Select_(newOnly);
713  Check();
714  }
715  return addrRet;
716  }
717 
719  std::vector<CAddress> GetAddr(size_t max_addresses, size_t max_pct)
720  {
721  Check();
722  std::vector<CAddress> vAddr;
723  {
724  LOCK(cs);
725  GetAddr_(vAddr, max_addresses, max_pct);
726  }
727  Check();
728  return vAddr;
729  }
730 
732  void Connected(const CService &addr, int64_t nTime = GetAdjustedTime())
733  {
734  LOCK(cs);
735  Check();
736  Connected_(addr, nTime);
737  Check();
738  }
739 
740  void SetServices(const CService &addr, ServiceFlags nServices)
741  {
742  LOCK(cs);
743  Check();
744  SetServices_(addr, nServices);
745  Check();
746  }
747 
748 };
749 
750 #endif // BITCOIN_ADDRMAN_H
CAddrMan::Create
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:89
ADDRV2_FORMAT
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
CAddrMan::~CAddrMan
~CAddrMan()
Definition: addrman.h:609
CService
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:551
CAddrMan::nKey
uint256 nKey
secret key to randomize bucket select with
Definition: addrman.h:234
CAddrInfo::GetNewBucket
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:24
CAddrMan::Good_
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:198
SerializeHash
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
FastRandomContext::rand256
uint256 rand256() noexcept
generate a random uint256.
Definition: random.cpp:615
CAddrInfo::CAddrInfo
CAddrInfo()
Definition: addrman.h:73
tinyformat::format
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
CAddrInfo::source
CNetAddr source
where knowledge about this address first came from
Definition: addrman.h:42
ADDRMAN_TEST_WINDOW
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
CAddrMan::Add_
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:264
CAddrMan::m_tried_collisions
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
CAddrMan::SwapRandom
void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2) EXCLUSIVE_LOCKS_REQUIRED(cs)
Swap two elements in vRandom.
Definition: addrman.cpp:101
fs.h
streams.h
ADDRMAN_NEW_BUCKETS_PER_ADDRESS
#define ADDRMAN_NEW_BUCKETS_PER_ADDRESS
in how many buckets for entries with new addresses a single address may occur
Definition: addrman.h:141
CAddrMan::Delete
void Delete(int nId) EXCLUSIVE_LOCKS_REQUIRED(cs)
Delete an entry. It must not be in tried, and have refcount 0.
Definition: addrman.cpp:121
CAddrMan::V1_DETERMINISTIC
@ V1_DETERMINISTIC
for pre-asmap files
Definition: addrman.h:183
sync.h
CAddrMan::Add
bool Add(const CAddress &addr, const CNetAddr &source, int64_t nTimePenalty=0)
Add a single address.
Definition: addrman.h:635
timedata.h
CNetAddr
Network address.
Definition: netaddress.h:119
source
const char * source
Definition: rpcconsole.cpp:57
CAddrMan::Serialize
void Serialize(Stream &s_) const
Serialized format.
Definition: addrman.h:359
CAddrInfo::nLastSuccess
int64_t nLastSuccess
last successful connection by us
Definition: addrman.h:45
CAddrMan::INCOMPATIBILITY_BASE
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
base_blob::SetNull
void SetNull()
Definition: uint256.h:39
CAddrMan::CAddrManTest
friend class CAddrManTest
Definition: addrman.h:174
CAddrInfo::GetChance
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:61
CAddrMan::Select
CAddrInfo Select(bool newOnly=false)
Choose an address to connect to.
Definition: addrman.h:706
CAddrMan::ResolveCollisions_
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:547
AnnotatedMixin< std::recursive_mutex >
clientversion.h
CAddrInfo::SERIALIZE_METHODS
SERIALIZE_METHODS(CAddrInfo, obj)
Definition: addrman.h:63
ServiceFlags
ServiceFlags
nServices flags
Definition: protocol.h:269
CAddrInfo::IsTerrible
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:41
CAddrMan::Attempt_
void Attempt_(const CService &addr, bool fCountFailure, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs)
Mark an entry as attempted to connect.
Definition: addrman.cpp:337
bitcoin-config.h
READWRITEAS
#define READWRITEAS(type, obj)
Definition: serialize.h:176
CService::ToStringIPPort
std::string ToStringIPPort() const
Definition: netaddress.cpp:1019
CAddrMan::SetServices_
void SetServices_(const CService &addr, ServiceFlags nServices) EXCLUSIVE_LOCKS_REQUIRED(cs)
Update an entry's service bits.
Definition: addrman.cpp:529
tinyformat.h
CAddrMan::cs
RecursiveMutex cs
critical section to protect the inner data structures
Definition: addrman.h:177
CAddrInfo
Extended statistics about a CAddress.
Definition: addrman.h:31
CAddrInfo::nLastCountAttempt
int64_t nLastCountAttempt
last counted attempt (memory only)
Definition: addrman.h:38
protocol.h
random.h
CAddrMan::GUARDED_BY
int nIdCount GUARDED_BY(cs)
last used nId
CAddrMan::SelectTriedCollision_
CAddrInfo SelectTriedCollision_() EXCLUSIVE_LOCKS_REQUIRED(cs)
Return a random to-be-evicted tried table address.
Definition: addrman.cpp:606
ADDRMAN_BUCKET_SIZE
#define ADDRMAN_BUCKET_SIZE
Definition: addrman.h:161
PACKAGE_NAME
#define PACKAGE_NAME
Definition: bitcoin-config.h:364
ADDRMAN_TRIED_BUCKET_COUNT
#define ADDRMAN_TRIED_BUCKET_COUNT
Convenience.
Definition: addrman.h:159
netaddress.h
CAddrMan::ClearNew
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:135
CAddrInfo::CAddrInfo
CAddrInfo(const CAddress &addrIn, const CNetAddr &addrSource)
Definition: addrman.h:69
CAddrInfo::nRefCount
int nRefCount
reference count in new sets (memory only)
Definition: addrman.h:51
LogPrintf
#define LogPrintf(...)
Definition: logging.h:183
CAddrMan::insecure_rand
FastRandomContext insecure_rand
Source of random numbers for randomization in inner loops.
Definition: addrman.h:237
CAddrInfo::nRandomPos
int nRandomPos
position in vRandom
Definition: addrman.h:57
CAddrMan::FILE_FORMAT
static constexpr Format FILE_FORMAT
The maximum format this software knows it can unserialize.
Definition: addrman.h:193
CAddrInfo::nLastTry
int64_t nLastTry
last try whatsoever by us (memory only)
Definition: addrman.h:35
CAddrInfo::GetBucketPosition
int GetBucketPosition(const uint256 &nKey, bool fNew, int nBucket) const
Calculate in which position of a bucket to store this entry.
Definition: addrman.cpp:35
uint256
256-bit opaque blob.
Definition: uint256.h:124
READWRITE
#define READWRITE(...)
Definition: serialize.h:175
CAddrMan::Format
Format
Serialization versions.
Definition: addrman.h:181
LogPrint
#define LogPrint(category,...)
Definition: logging.h:187
CAddrMan::Unserialize
void Unserialize(Stream &s_)
Definition: addrman.h:424
ADDRMAN_NEW_BUCKET_COUNT
#define ADDRMAN_NEW_BUCKET_COUNT
Definition: addrman.h:160
CAddrMan::MakeTried
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:150
CAddrInfo::GetTriedBucket
int GetTriedBucket(const uint256 &nKey, const std::vector< bool > &asmap) const
Calculate in which "tried" bucket this entry belongs.
Definition: addrman.cpp:14
OverrideStream
Definition: streams.h:26
CAddrMan::Connected_
void Connected_(const CService &addr, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs)
We have successfully connected to this peer.
Definition: addrman.cpp:509
system.h
CAddrMan::Select_
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:359
CAddrMan::Check
void Check()
Consistency check.
Definition: addrman.h:622
strprintf
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1164
CAddrMan
Stochastical (IP) address manager.
Definition: addrman.h:172
CAddrMan::m_asmap
std::vector< bool > m_asmap
Definition: addrman.h:315
GetAdjustedTime
int64_t GetAdjustedTime()
Definition: timedata.cpp:34
CAddrMan::V2_ASMAP
@ V2_ASMAP
for files including asmap version
Definition: addrman.h:184
CAddress
A CService with information about it as peer.
Definition: protocol.h:356
CAddrInfo::nAttempts
int nAttempts
connection attempts since last successful attempt
Definition: addrman.h:48
CAddrMan::V0_HISTORICAL
@ V0_HISTORICAL
historic format, before commit e6b343d88
Definition: addrman.h:182
CAddrMan::SelectTriedCollision
CAddrInfo SelectTriedCollision()
Randomly select an address in tried that another address is attempting to evict.
Definition: addrman.h:691
EXCLUSIVE_LOCKS_REQUIRED
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:49
LOCK
#define LOCK(cs)
Definition: sync.h:232
CAddrMan::Connected
void Connected(const CService &addr, int64_t nTime=GetAdjustedTime())
Outer function for Connected_()
Definition: addrman.h:732
CAddrMan::Clear
void Clear()
Definition: addrman.h:580
CAddrMan::CAddrMan
CAddrMan()
Definition: addrman.h:604
CAddrMan::Good
void Good(const CService &addr, bool test_before_evict=true, int64_t nTime=GetAdjustedTime())
Mark an entry as accessible.
Definition: addrman.h:664
hash.h
CAddrMan::SetServices
void SetServices(const CService &addr, ServiceFlags nServices)
Definition: addrman.h:740
BCLog::ADDRMAN
@ ADDRMAN
Definition: logging.h:47
CAddrMan::Find
CAddrInfo * Find(const CNetAddr &addr, int *pnId=nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs)
Find an entry.
Definition: addrman.cpp:76
CAddrInfo::fInTried
bool fInTried
in tried set? (memory only)
Definition: addrman.h:54
CAddrMan::size
size_t size() const
Return the number of (unique) addresses in all tables.
Definition: addrman.h:615
CAddrMan::GetAddr
std::vector< CAddress > GetAddr(size_t max_addresses, size_t max_pct)
Return a bunch of addresses, selected at random.
Definition: addrman.h:719
CAddrMan::V3_BIP155
@ V3_BIP155
same as V2_ASMAP plus addresses are in BIP155 format
Definition: addrman.h:185
CAddrMan::DecodeAsmap
static std::vector< bool > DecodeAsmap(fs::path path)
Definition: addrman.cpp:633
CAddrMan::Add
bool Add(const std::vector< CAddress > &vAddr, const CNetAddr &source, int64_t nTimePenalty=0)
Add multiple addresses.
Definition: addrman.h:649
assert
assert(std::addressof(::ChainstateActive().CoinsTip())==std::addressof(coins_cache))
CAddrMan::Attempt
void Attempt(const CService &addr, bool fCountFailure, int64_t nTime=GetAdjustedTime())
Mark an entry as connection attempted to.
Definition: addrman.h:673
CAddrMan::GetAddr_
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:484
CAddrMan::ResolveCollisions
void ResolveCollisions()
See if any to-be-evicted tried table entries have been tested and if so resolve the collisions.
Definition: addrman.h:682
FastRandomContext
Fast randomness source.
Definition: random.h:119
it
auto it
Definition: validation.cpp:397
CAddrInfo::GetNewBucket
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