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 
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 {
182  V0_HISTORICAL = 0,
183  V1_DETERMINISTIC = 1,
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 
271  void ResolveCollisions_() EXCLUSIVE_LOCKS_REQUIRED(cs);
272 
274  CAddrInfo SelectTriedCollision_() EXCLUSIVE_LOCKS_REQUIRED(cs);
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 
360  template <typename Stream>
361  void Serialize(Stream& s_) const
362  {
363  LOCK(cs);
364 
365  // Always serialize in the latest version (FILE_FORMAT).
366 
367  OverrideStream<Stream> s(&s_, s_.GetType(), s_.GetVersion() | ADDRV2_FORMAT);
368 
369  s << static_cast<uint8_t>(FILE_FORMAT);
370 
371  // Increment `lowest_compatible` iff a newly introduced format is incompatible with
372  // the previous one.
373  static constexpr uint8_t lowest_compatible = Format::V3_BIP155;
374  s << static_cast<uint8_t>(INCOMPATIBILITY_BASE + lowest_compatible);
375 
376  s << nKey;
377  s << nNew;
378  s << nTried;
379 
380  int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30);
381  s << nUBuckets;
382  std::map<int, int> mapUnkIds;
383  int nIds = 0;
384  for (const auto& entry : mapInfo) {
385  mapUnkIds[entry.first] = nIds;
386  const CAddrInfo &info = entry.second;
387  if (info.nRefCount) {
388  assert(nIds != nNew); // this means nNew was wrong, oh ow
389  s << info;
390  nIds++;
391  }
392  }
393  nIds = 0;
394  for (const auto& entry : mapInfo) {
395  const CAddrInfo &info = entry.second;
396  if (info.fInTried) {
397  assert(nIds != nTried); // this means nTried was wrong, oh ow
398  s << info;
399  nIds++;
400  }
401  }
402  for (int bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) {
403  int nSize = 0;
404  for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
405  if (vvNew[bucket][i] != -1)
406  nSize++;
407  }
408  s << nSize;
409  for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
410  if (vvNew[bucket][i] != -1) {
411  int nIndex = mapUnkIds[vvNew[bucket][i]];
412  s << nIndex;
413  }
414  }
415  }
416  // Store asmap version after bucket entries so that it
417  // can be ignored by older clients for backward compatibility.
418  uint256 asmap_version;
419  if (m_asmap.size() != 0) {
420  asmap_version = SerializeHash(m_asmap);
421  }
422  s << asmap_version;
423  }
424 
425  template <typename Stream>
426  void Unserialize(Stream& s_)
427  {
428  LOCK(cs);
429 
430  Clear();
431 
432  Format format;
433  s_ >> Using<CustomUintFormatter<1>>(format);
434 
435  int stream_version = s_.GetVersion();
436  if (format >= Format::V3_BIP155) {
437  // Add ADDRV2_FORMAT to the version so that the CNetAddr and CAddress
438  // unserialize methods know that an address in addrv2 format is coming.
439  stream_version |= ADDRV2_FORMAT;
440  }
441 
442  OverrideStream<Stream> s(&s_, s_.GetType(), stream_version);
443 
444  uint8_t compat;
445  s >> compat;
446  const uint8_t lowest_compatible = compat - INCOMPATIBILITY_BASE;
447  if (lowest_compatible > FILE_FORMAT) {
448  throw std::ios_base::failure(strprintf(
449  "Unsupported format of addrman database: %u. It is compatible with formats >=%u, "
450  "but the maximum supported by this version of %s is %u.",
451  format, lowest_compatible, PACKAGE_NAME, static_cast<uint8_t>(FILE_FORMAT)));
452  }
453 
454  s >> nKey;
455  s >> nNew;
456  s >> nTried;
457  int nUBuckets = 0;
458  s >> nUBuckets;
459  if (format >= Format::V1_DETERMINISTIC) {
460  nUBuckets ^= (1 << 30);
461  }
462 
464  throw std::ios_base::failure("Corrupt CAddrMan serialization, nNew exceeds limit.");
465  }
466 
467  if (nTried > ADDRMAN_TRIED_BUCKET_COUNT * ADDRMAN_BUCKET_SIZE) {
468  throw std::ios_base::failure("Corrupt CAddrMan serialization, nTried exceeds limit.");
469  }
470 
471  // Deserialize entries from the new table.
472  for (int n = 0; n < nNew; n++) {
473  CAddrInfo &info = mapInfo[n];
474  s >> info;
475  mapAddr[info] = n;
476  info.nRandomPos = vRandom.size();
477  vRandom.push_back(n);
478  }
479  nIdCount = nNew;
480 
481  // Deserialize entries from the tried table.
482  int nLost = 0;
483  for (int n = 0; n < nTried; n++) {
484  CAddrInfo info;
485  s >> info;
486  int nKBucket = info.GetTriedBucket(nKey, m_asmap);
487  int nKBucketPos = info.GetBucketPosition(nKey, false, nKBucket);
488  if (vvTried[nKBucket][nKBucketPos] == -1) {
489  info.nRandomPos = vRandom.size();
490  info.fInTried = true;
491  vRandom.push_back(nIdCount);
492  mapInfo[nIdCount] = info;
493  mapAddr[info] = nIdCount;
494  vvTried[nKBucket][nKBucketPos] = nIdCount;
495  nIdCount++;
496  } else {
497  nLost++;
498  }
499  }
500  nTried -= nLost;
501 
502  // Store positions in the new table buckets to apply later (if possible).
503  std::map<int, int> entryToBucket; // Represents which entry belonged to which bucket when serializing
504 
505  for (int bucket = 0; bucket < nUBuckets; bucket++) {
506  int nSize = 0;
507  s >> nSize;
508  for (int n = 0; n < nSize; n++) {
509  int nIndex = 0;
510  s >> nIndex;
511  if (nIndex >= 0 && nIndex < nNew) {
512  entryToBucket[nIndex] = bucket;
513  }
514  }
515  }
516 
517  uint256 supplied_asmap_version;
518  if (m_asmap.size() != 0) {
519  supplied_asmap_version = SerializeHash(m_asmap);
520  }
521  uint256 serialized_asmap_version;
522  if (format >= Format::V2_ASMAP) {
523  s >> serialized_asmap_version;
524  }
525 
526  for (int n = 0; n < nNew; n++) {
527  CAddrInfo &info = mapInfo[n];
528  int bucket = entryToBucket[n];
529  int nUBucketPos = info.GetBucketPosition(nKey, true, bucket);
530  if (format >= Format::V2_ASMAP && nUBuckets == ADDRMAN_NEW_BUCKET_COUNT && vvNew[bucket][nUBucketPos] == -1 &&
531  info.nRefCount < ADDRMAN_NEW_BUCKETS_PER_ADDRESS && serialized_asmap_version == supplied_asmap_version) {
532  // Bucketing has not changed, using existing bucket positions for the new table
533  vvNew[bucket][nUBucketPos] = n;
534  info.nRefCount++;
535  } else {
536  // In case the new table data cannot be used (format unknown, bucket count wrong or new asmap),
537  // try to give them a reference based on their primary source address.
538  LogPrint(BCLog::ADDRMAN, "Bucketing method was updated, re-bucketing addrman entries from disk\n");
539  bucket = info.GetNewBucket(nKey, m_asmap);
540  nUBucketPos = info.GetBucketPosition(nKey, true, bucket);
541  if (vvNew[bucket][nUBucketPos] == -1) {
542  vvNew[bucket][nUBucketPos] = n;
543  info.nRefCount++;
544  }
545  }
546  }
547 
548  // Prune new entries with refcount 0 (as a result of collisions).
549  int nLostUnk = 0;
550  for (std::map<int, CAddrInfo>::const_iterator it = mapInfo.begin(); it != mapInfo.end(); ) {
551  if (it->second.fInTried == false && it->second.nRefCount == 0) {
552  std::map<int, CAddrInfo>::const_iterator itCopy = it++;
553  Delete(itCopy->first);
554  nLostUnk++;
555  } else {
556  it++;
557  }
558  }
559  if (nLost + nLostUnk > 0) {
560  LogPrint(BCLog::ADDRMAN, "addrman lost %i new and %i tried addresses due to collisions\n", nLostUnk, nLost);
561  }
562 
563  Check();
564  }
565 
566  void Clear()
567  {
568  LOCK(cs);
569  std::vector<int>().swap(vRandom);
570  nKey = insecure_rand.rand256();
571  for (size_t bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) {
572  for (size_t entry = 0; entry < ADDRMAN_BUCKET_SIZE; entry++) {
573  vvNew[bucket][entry] = -1;
574  }
575  }
576  for (size_t bucket = 0; bucket < ADDRMAN_TRIED_BUCKET_COUNT; bucket++) {
577  for (size_t entry = 0; entry < ADDRMAN_BUCKET_SIZE; entry++) {
578  vvTried[bucket][entry] = -1;
579  }
580  }
581 
582  nIdCount = 0;
583  nTried = 0;
584  nNew = 0;
585  nLastGood = 1; //Initially at 1 so that "never" is strictly worse.
586  mapInfo.clear();
587  mapAddr.clear();
588  }
589 
591  {
592  Clear();
593  }
594 
596  {
597  nKey.SetNull();
598  }
599 
601  size_t size() const
602  {
603  LOCK(cs); // TODO: Cache this in an atomic to avoid this overhead
604  return vRandom.size();
605  }
606 
608  void Check()
609  {
610 #ifdef DEBUG_ADDRMAN
611  {
612  LOCK(cs);
613  int err;
614  if ((err=Check_()))
615  LogPrintf("ADDRMAN CONSISTENCY CHECK FAILED!!! err=%i\n", err);
616  }
617 #endif
618  }
619 
621  bool Add(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty = 0)
622  {
623  LOCK(cs);
624  bool fRet = false;
625  Check();
626  fRet |= Add_(addr, source, nTimePenalty);
627  Check();
628  if (fRet) {
629  LogPrint(BCLog::ADDRMAN, "Added %s from %s: %i tried, %i new\n", addr.ToStringIPPort(), source.ToString(), nTried, nNew);
630  }
631  return fRet;
632  }
633 
635  bool Add(const std::vector<CAddress> &vAddr, const CNetAddr& source, int64_t nTimePenalty = 0)
636  {
637  LOCK(cs);
638  int nAdd = 0;
639  Check();
640  for (std::vector<CAddress>::const_iterator it = vAddr.begin(); it != vAddr.end(); it++)
641  nAdd += Add_(*it, source, nTimePenalty) ? 1 : 0;
642  Check();
643  if (nAdd) {
644  LogPrint(BCLog::ADDRMAN, "Added %i addresses from %s: %i tried, %i new\n", nAdd, source.ToString(), nTried, nNew);
645  }
646  return nAdd > 0;
647  }
648 
650  void Good(const CService &addr, bool test_before_evict = true, int64_t nTime = GetAdjustedTime())
651  {
652  LOCK(cs);
653  Check();
654  Good_(addr, test_before_evict, nTime);
655  Check();
656  }
657 
659  void Attempt(const CService &addr, bool fCountFailure, int64_t nTime = GetAdjustedTime())
660  {
661  LOCK(cs);
662  Check();
663  Attempt_(addr, fCountFailure, nTime);
664  Check();
665  }
666 
669  {
670  LOCK(cs);
671  Check();
672  ResolveCollisions_();
673  Check();
674  }
675 
678  {
679  CAddrInfo ret;
680  {
681  LOCK(cs);
682  Check();
683  ret = SelectTriedCollision_();
684  Check();
685  }
686  return ret;
687  }
688 
692  CAddrInfo Select(bool newOnly = false)
693  {
694  CAddrInfo addrRet;
695  {
696  LOCK(cs);
697  Check();
698  addrRet = Select_(newOnly);
699  Check();
700  }
701  return addrRet;
702  }
703 
705  std::vector<CAddress> GetAddr(size_t max_addresses, size_t max_pct)
706  {
707  Check();
708  std::vector<CAddress> vAddr;
709  {
710  LOCK(cs);
711  GetAddr_(vAddr, max_addresses, max_pct);
712  }
713  Check();
714  return vAddr;
715  }
716 
718  void Connected(const CService &addr, int64_t nTime = GetAdjustedTime())
719  {
720  LOCK(cs);
721  Check();
722  Connected_(addr, nTime);
723  Check();
724  }
725 
727  {
728  LOCK(cs);
729  Check();
730  SetServices_(addr, nServices);
731  Check();
732  }
733 
734 };
735 
736 #endif // BITCOIN_ADDRMAN_H
int nRefCount
reference count in new sets (memory only)
Definition: addrman.h:51
std::deque< CInv >::iterator it
ServiceFlags
nServices flags
Definition: protocol.h:269
CAddrInfo Select(bool newOnly=false)
Choose an address to connect to.
Definition: addrman.h:692
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:659
int GetTriedBucket(const uint256 &nKey, const std::vector< bool > &asmap) const
Calculate in which "tried" bucket this entry belongs.
Definition: addrman.cpp:12
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1164
~CAddrMan()
Definition: addrman.h:595
int nAttempts
connection attempts since last successful attempt
Definition: addrman.h:48
uint256 rand256() noexcept
generate a random uint256.
Definition: random.cpp:616
void Serialize(Stream &s_) const
Serialized format.
Definition: addrman.h:361
static void LogPrintf(const char *fmt, const Args &... args)
Definition: logging.h:166
#define PACKAGE_NAME
static const int64_t ADDRMAN_TEST_WINDOW
the maximum time we&#39;ll spend trying to resolve a tried table collision, in seconds ...
Definition: addrman.h:167
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
std::string ToString() const
Definition: netaddress.cpp:580
int nRandomPos
position in vRandom
Definition: addrman.h:57
bool Add(const CAddress &addr, const CNetAddr &source, int64_t nTimePenalty=0)
Add a single address.
Definition: addrman.h:621
#define ADDRMAN_TRIED_BUCKET_COUNT
Convenience.
Definition: addrman.h:159
#define READWRITEAS(type, obj)
Definition: serialize.h:176
bool fInTried
in tried set? (memory only)
Definition: addrman.h:54
Stochastical (IP) address manager.
Definition: addrman.h:172
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&#39;s serialization.
Definition: hash.h:192
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
#define LOCK(cs)
Definition: sync.h:230
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:501
Fast randomness source.
Definition: random.h:119
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
void Check()
Consistency check.
Definition: addrman.h:608
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
void Unserialize(Stream &s_)
Definition: addrman.h:426
A CService with information about it as peer.
Definition: protocol.h:360
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
#define ADDRMAN_BUCKET_SIZE
Definition: addrman.h:161
Format
Serialization versions.
Definition: addrman.h:181
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
CAddrInfo()
Definition: addrman.h:73
Network address.
Definition: netaddress.h:119
size_t size() const
Return the number of (unique) addresses in all tables.
Definition: addrman.h:601
256-bit opaque blob.
Definition: uint256.h:124
ServiceFlags nServices
Definition: protocol.h:400
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:49
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
SERIALIZE_METHODS(CAddrInfo, obj)
Definition: addrman.h:63
void Clear()
Definition: addrman.h:566
CAddrMan()
Definition: addrman.h:590
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:677
std::string ToStringIPPort() const
Definition: netaddress.cpp:972
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
std::vector< CAddress > GetAddr(size_t max_addresses, size_t max_pct)
Return a bunch of addresses, selected at random.
Definition: addrman.h:705
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:668
#define GUARDED_BY(x)
Definition: threadsafety.h:38
std::vector< bool > m_asmap
Definition: addrman.h:315
bool Add(const std::vector< CAddress > &vAddr, const CNetAddr &source, int64_t nTimePenalty=0)
Add multiple addresses.
Definition: addrman.h:635
void Good(const CService &addr, bool test_before_evict=true, int64_t nTime=GetAdjustedTime())
Mark an entry as accessible.
Definition: addrman.h:650
void SetServices(const CService &addr, ServiceFlags nServices)
Definition: addrman.h:726
uint256 nKey
secret key to randomize bucket select with
Definition: addrman.h:234
#define READWRITE(...)
Definition: serialize.h:175
void Connected(const CService &addr, int64_t nTime=GetAdjustedTime())
Outer function for Connected_()
Definition: addrman.h:718
uint32_t nTime
Definition: protocol.h:398
int64_t nLastSuccess
last successful connection by us
Definition: addrman.h:45
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