PIVX Core  5.6.99
P2P Digital Currency
addrman.h
Go to the documentation of this file.
1 // Copyright (c) 2012 Pieter Wuille
2 // Copyright (c) 2012-2015 The Bitcoin developers
3 // Copyright (c) 2017-2021 The PIVX Core developers
4 // Distributed under the MIT software license, see the accompanying
5 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 
7 #ifndef PIVX_ADDRMAN_H
8 #define PIVX_ADDRMAN_H
9 
10 #if defined(HAVE_CONFIG_H)
11 #include "config/pivx-config.h"
12 #endif //HAVE_CONFIG_H
13 
14 #include "clientversion.h"
15 #include "netaddress.h"
16 #include "optional.h"
17 #include "protocol.h"
18 #include "random.h"
19 #include "sync.h"
20 #include "timedata.h"
21 #include "tinyformat.h"
22 #include "util/system.h"
23 
24 #include <fs.h>
25 #include <hash.h>
26 #include <iostream>
27 #include <map>
28 #include <set>
29 #include <stdint.h>
30 #include <streams.h>
31 #include <vector>
32 
36 class CAddrInfo : public CAddress
37 {
38 public:
40  int64_t nLastTry{0};
41 
43  int64_t nLastCountAttempt{0};
44 
45 private:
48 
50  int64_t nLastSuccess{0};
51 
53  int nAttempts{0};
54 
56  int nRefCount{0};
57 
59  bool fInTried{false};
60 
62  int nRandomPos{-1};
63 
64  friend class CAddrMan;
65 
66 public:
67 
69  {
70  READWRITEAS(CAddress, obj);
71  READWRITE(obj.source, obj.nLastSuccess, obj.nAttempts);
72  }
73 
74  CAddrInfo(const CAddress& addrIn, const CNetAddr& addrSource) : CAddress(addrIn), source(addrSource)
75  {
76  }
77 
79  {
80  }
81 
83  int GetTriedBucket(const uint256& nKey, const std::vector<bool>& asmap) const;
84 
86  int GetNewBucket(const uint256& nKey, const CNetAddr& src, const std::vector<bool>& asmap) const;
87 
89  int GetNewBucket(const uint256& nKey, const std::vector<bool>& asmap) const
90  {
91  return GetNewBucket(nKey, source, asmap);
92  }
93 
95  int GetBucketPosition(const uint256& nKey, bool fNew, int nBucket) const;
96 
98  bool IsTerrible(int64_t nNow = GetAdjustedTime()) const;
99 
101  double GetChance(int64_t nNow = GetAdjustedTime()) const;
102 };
103 
131 #define ADDRMAN_TRIED_BUCKET_COUNT_LOG2 8
132 
134 #define ADDRMAN_NEW_BUCKET_COUNT_LOG2 10
135 
137 #define ADDRMAN_BUCKET_SIZE_LOG2 6
138 
140 #define ADDRMAN_TRIED_BUCKETS_PER_GROUP 8
141 
143 #define ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP 64
144 
146 #define ADDRMAN_NEW_BUCKETS_PER_ADDRESS 8
147 
149 #define ADDRMAN_HORIZON_DAYS 30
150 
152 #define ADDRMAN_RETRIES 3
153 
155 #define ADDRMAN_MAX_FAILURES 10
156 
158 #define ADDRMAN_MIN_FAIL_DAYS 7
159 
161 #define ADDRMAN_REPLACEMENT_HOURS 4
162 
164 #define ADDRMAN_TRIED_BUCKET_COUNT (1 << ADDRMAN_TRIED_BUCKET_COUNT_LOG2)
165 #define ADDRMAN_NEW_BUCKET_COUNT (1 << ADDRMAN_NEW_BUCKET_COUNT_LOG2)
166 #define ADDRMAN_BUCKET_SIZE (1 << ADDRMAN_BUCKET_SIZE_LOG2)
167 
169 #define ADDRMAN_SET_TRIED_COLLISION_SIZE 10
170 
172 static const int64_t ADDRMAN_TEST_WINDOW = 40*60; // 40 minutes
173 
177 class CAddrMan
178 {
179 friend class CAddrManTest;
180 protected:
183 
184 private:
186  enum Format : uint8_t {
189  V2_ASMAP = 2,
190  V3_BIP155 = 3,
191  };
192 
198  static constexpr Format FILE_FORMAT = Format::V3_BIP155;
199 
205  static constexpr uint8_t INCOMPATIBILITY_BASE = 32;
206 
208  int nIdCount GUARDED_BY(cs);
209 
211  std::map<int, CAddrInfo> mapInfo GUARDED_BY(cs);
212 
214  std::map<CNetAddr, int> mapAddr GUARDED_BY(cs);
215 
217  std::vector<int> vRandom GUARDED_BY(cs);
218 
219  // number of "tried" entries
220  int nTried GUARDED_BY(cs);
221 
224 
226  int nNew GUARDED_BY(cs);
227 
230 
232  int64_t nLastGood GUARDED_BY(cs);
233 
235  std::set<int> m_tried_collisions;
236 
237 protected:
240 
243 
245  CAddrInfo* Find(const CNetAddr& addr, int *pnId = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs);
246 
249  CAddrInfo* Create(const CAddress& addr, const CNetAddr& addrSource, int* pnId = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs);
250 
252  void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2) EXCLUSIVE_LOCKS_REQUIRED(cs);
253 
255  void MakeTried(CAddrInfo& info, int nId) EXCLUSIVE_LOCKS_REQUIRED(cs);
256 
258  void Delete(int nId) EXCLUSIVE_LOCKS_REQUIRED(cs);
259 
261  void ClearNew(int nUBucket, int nUBucketPos) EXCLUSIVE_LOCKS_REQUIRED(cs);
262 
264  void Good_(const CService& addr, bool test_before_evict, int64_t time) EXCLUSIVE_LOCKS_REQUIRED(cs);
265 
267  bool Add_(const CAddress& addr, const CNetAddr& source, int64_t nTimePenalty) EXCLUSIVE_LOCKS_REQUIRED(cs);
268 
270  void Attempt_(const CService& addr, bool fCountFailure, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs);
271 
274 
277 
280 
281 #ifdef DEBUG_ADDRMAN
283  int Check_() EXCLUSIVE_LOCKS_REQUIRED(cs);
284 #endif
285 
294  void GetAddr_(std::vector<CAddress>& vAddr, size_t max_addresses, size_t max_pct, Optional<Network> network) EXCLUSIVE_LOCKS_REQUIRED(cs);
295 
297  void Connected_(const CService& addr, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs);
298 
300  void SetServices_(const CService& addr, ServiceFlags nServices) EXCLUSIVE_LOCKS_REQUIRED(cs);
301 
302 public:
303  // Compressed IP->ASN mapping, loaded from a file when a node starts.
304  // Should be always empty if no file was provided.
305  // This mapping is then used for bucketing nodes in Addrman.
306  //
307  // If asmap is provided, nodes will be bucketed by
308  // AS they belong to, in order to make impossible for a node
309  // to connect to several nodes hosted in a single AS.
310  // This is done in response to Erebus attack, but also to generally
311  // diversify the connections every node creates,
312  // especially useful when a large fraction of nodes
313  // operate under a couple of cloud providers.
314  //
315  // If a new asmap was provided, the existing records
316  // would be re-bucketed accordingly.
317  std::vector<bool> m_asmap;
318 
319  // Read asmap from provided binary file
320  static std::vector<bool> DecodeAsmap(fs::path path);
321 
322 
362  template <typename Stream>
363  void Serialize(Stream& s_) const
364  {
365  LOCK(cs);
366 
367  // Always serialize in the latest version (FILE_FORMAT).
368 
369  OverrideStream<Stream> s(&s_, s_.GetType(), s_.GetVersion() | ADDRV2_FORMAT);
370 
371  s << static_cast<uint8_t>(FILE_FORMAT);
372 
373  // Increment `lowest_compatible` if a newly introduced format is incompatible with
374  // the previous one.
375  static constexpr uint8_t lowest_compatible = Format::V3_BIP155;
376  s << static_cast<uint8_t>(INCOMPATIBILITY_BASE + lowest_compatible);
377 
378  s << nKey;
379  s << nNew;
380  s << nTried;
381 
382  int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30);
383  s << nUBuckets;
384  std::map<int, int> mapUnkIds;
385  int nIds = 0;
386  for (const auto& entry : mapInfo) {
387  mapUnkIds[entry.first] = nIds;
388  const CAddrInfo& info = entry.second;
389  if (info.nRefCount) {
390  assert(nIds != nNew); // this means nNew was wrong, oh ow
391  s << info;
392  nIds++;
393  }
394  }
395  nIds = 0;
396  for (const auto& entry : mapInfo) {
397  const CAddrInfo& info = entry.second;
398  if (info.fInTried) {
399  assert(nIds != nTried); // this means nTried was wrong, oh ow
400  s << info;
401  nIds++;
402  }
403  }
404  for (int bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) {
405  int nSize = 0;
406  for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
407  if (vvNew[bucket][i] != -1)
408  nSize++;
409  }
410  s << nSize;
411  for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
412  if (vvNew[bucket][i] != -1) {
413  int nIndex = mapUnkIds[vvNew[bucket][i]];
414  s << nIndex;
415  }
416  }
417  }
418  // Store asmap version after bucket entries so that it
419  // can be ignored by older clients for backward compatibility.
420  uint256 asmap_version;
421  if (m_asmap.size() != 0) {
422  asmap_version = SerializeHash(m_asmap);
423  }
424  s << asmap_version;
425  }
426 
427  template <typename Stream>
428  void Unserialize(Stream& s_)
429  {
430  LOCK(cs);
431 
432  Clear();
433 
434  Format format;
435  s_ >> Using<CustomUintFormatter<1>>(format);
436 
437  int stream_version = s_.GetVersion();
438  if (format >= Format::V3_BIP155) {
439  // Add ADDRV2_FORMAT to the version so that the CNetAddr and CAddress
440  // unserialize methods know that an address in addrv2 format is coming.
441  stream_version |= ADDRV2_FORMAT;
442  }
443 
444  OverrideStream<Stream> s(&s_, s_.GetType(), stream_version);
445 
446  uint8_t compat;
447  s >> compat;
448  const uint8_t lowest_compatible = compat - INCOMPATIBILITY_BASE;
449  if (lowest_compatible > FILE_FORMAT) {
450  throw std::ios_base::failure(strprintf(
451  "Unsupported format of addrman database: %u. It is compatible with formats >=%u, "
452  "but the maximum supported by this version of %s is %u.",
453  format, lowest_compatible, PACKAGE_NAME, static_cast<uint8_t>(FILE_FORMAT)));
454  }
455 
456  s >> nKey;
457  s >> nNew;
458  s >> nTried;
459  int nUBuckets = 0;
460  s >> nUBuckets;
461  if (format >= Format::V1_DETERMINISTIC) {
462  nUBuckets ^= (1 << 30);
463  }
464 
466  throw std::ios_base::failure("Corrupt CAddrMan serialization, nNew exceeds limit.");
467  }
468 
470  throw std::ios_base::failure("Corrupt CAddrMan serialization, nTried exceeds limit.");
471  }
472 
473  // Deserialize entries from the new table.
474  for (int n = 0; n < nNew; n++) {
475  CAddrInfo& info = mapInfo[n];
476  s >> info;
477  mapAddr[info] = n;
478  info.nRandomPos = vRandom.size();
479  vRandom.push_back(n);
480  }
481  nIdCount = nNew;
482 
483  // Deserialize entries from the tried table.
484  int nLost = 0;
485  for (int n = 0; n < nTried; n++) {
486  CAddrInfo info;
487  s >> info;
488  int nKBucket = info.GetTriedBucket(nKey, m_asmap);
489  int nKBucketPos = info.GetBucketPosition(nKey, false, nKBucket);
490  if (vvTried[nKBucket][nKBucketPos] == -1) {
491  info.nRandomPos = vRandom.size();
492  info.fInTried = true;
493  vRandom.push_back(nIdCount);
494  mapInfo[nIdCount] = info;
495  mapAddr[info] = nIdCount;
496  vvTried[nKBucket][nKBucketPos] = nIdCount;
497  nIdCount++;
498  } else {
499  nLost++;
500  }
501  }
502  nTried -= nLost;
503 
504  // Store positions in the new table buckets to apply later (if possible).
505  std::map<int, int> entryToBucket; // Represents which entry belonged to which bucket when serializing
506 
507  for (int bucket = 0; bucket < nUBuckets; bucket++) {
508  int nSize = 0;
509  s >> nSize;
510  for (int n = 0; n < nSize; n++) {
511  int nIndex = 0;
512  s >> nIndex;
513  if (nIndex >= 0 && nIndex < nNew) {
514  entryToBucket[nIndex] = bucket;
515  }
516  }
517  }
518 
519  uint256 supplied_asmap_version;
520  if (m_asmap.size() != 0) {
521  supplied_asmap_version = SerializeHash(m_asmap);
522  }
523  uint256 serialized_asmap_version;
524  if (format >= Format::V2_ASMAP) {
525  s >> serialized_asmap_version;
526  }
527 
528  for (int n = 0; n < nNew; n++) {
529  CAddrInfo &info = mapInfo[n];
530  int bucket = entryToBucket[n];
531  int nUBucketPos = info.GetBucketPosition(nKey, true, bucket);
532  if (format >= Format::V2_ASMAP && nUBuckets == ADDRMAN_NEW_BUCKET_COUNT && vvNew[bucket][nUBucketPos] == -1 &&
533  info.nRefCount < ADDRMAN_NEW_BUCKETS_PER_ADDRESS && serialized_asmap_version == supplied_asmap_version) {
534  // Bucketing has not changed, using existing bucket positions for the new table
535  vvNew[bucket][nUBucketPos] = n;
536  info.nRefCount++;
537  } else {
538  // In case the new table data cannot be used (format unknown, bucket count wrong or new asmap),
539  // try to give them a reference based on their primary source address.
540  LogPrint(BCLog::ADDRMAN, "Bucketing method was updated, re-bucketing addrman entries from disk\n");
541  bucket = info.GetNewBucket(nKey, m_asmap);
542  nUBucketPos = info.GetBucketPosition(nKey, true, bucket);
543  if (vvNew[bucket][nUBucketPos] == -1) {
544  vvNew[bucket][nUBucketPos] = n;
545  info.nRefCount++;
546  }
547  }
548  }
549 
550  // Prune new entries with refcount 0 (as a result of collisions).
551  int nLostUnk = 0;
552  for (std::map<int, CAddrInfo>::const_iterator it = mapInfo.begin(); it != mapInfo.end();) {
553  if (it->second.fInTried == false && it->second.nRefCount == 0) {
554  std::map<int, CAddrInfo>::const_iterator itCopy = it++;
555  Delete(itCopy->first);
556  nLostUnk++;
557  } else {
558  it++;
559  }
560  }
561  if (nLost + nLostUnk > 0) {
562  LogPrint(BCLog::ADDRMAN, "addrman lost %i new and %i tried addresses due to collisions\n", nLostUnk, nLost);
563  }
564 
565  Check();
566  }
567 
568  void Clear()
569  {
570  LOCK(cs);
571  std::vector<int>().swap(vRandom);
573  for (size_t bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) {
574  for (size_t entry = 0; entry < ADDRMAN_BUCKET_SIZE; entry++) {
575  vvNew[bucket][entry] = -1;
576  }
577  }
578  for (size_t bucket = 0; bucket < ADDRMAN_TRIED_BUCKET_COUNT; bucket++) {
579  for (size_t entry = 0; entry < ADDRMAN_BUCKET_SIZE; entry++) {
580  vvTried[bucket][entry] = -1;
581  }
582  }
583 
584  nIdCount = 0;
585  nTried = 0;
586  nNew = 0;
587  nLastGood = 1; //Initially at 1 so that "never" is strictly worse.
588  mapInfo.clear();
589  mapAddr.clear();
590  }
591 
593  {
594  Clear();
595  }
596 
598  {
599  nKey.SetNull();
600  }
601 
603  size_t size() const
604  {
605  LOCK(cs); // TODO: Cache this in an atomic to avoid this overhead
606  return vRandom.size();
607  }
608 
610  void Check()
611  {
612 #ifdef DEBUG_ADDRMAN
613  {
614  LOCK(cs);
615  int err;
616  if ((err = Check_()))
617  LogPrintf("ADDRMAN CONSISTENCY CHECK FAILED!!! err=%i\n", err);
618  }
619 #endif
620  }
621 
623  bool Add(const CAddress& addr, const CNetAddr& source, int64_t nTimePenalty = 0)
624  {
625  LOCK(cs);
626  bool fRet = false;
627  Check();
628  fRet |= Add_(addr, source, nTimePenalty);
629  Check();
630  if (fRet) {
631  LogPrint(BCLog::ADDRMAN, "Added %s from %s: %i tried, %i new\n", addr.ToStringIPPort(), source.ToString(), nTried, nNew);
632  }
633  return fRet;
634  }
635 
637  bool Add(const std::vector<CAddress>& vAddr, const CNetAddr& source, int64_t nTimePenalty = 0)
638  {
639  LOCK(cs);
640  int nAdd = 0;
641  Check();
642  for (std::vector<CAddress>::const_iterator it = vAddr.begin(); it != vAddr.end(); it++)
643  nAdd += Add_(*it, source, nTimePenalty) ? 1 : 0;
644  Check();
645  if (nAdd) {
646  LogPrint(BCLog::ADDRMAN, "Added %i addresses from %s: %i tried, %i new\n", nAdd, source.ToString(), nTried, nNew);
647  }
648  return nAdd > 0;
649  }
650 
652  void Good(const CService& addr, bool test_before_evict = true, int64_t nTime = GetAdjustedTime())
653  {
654  LOCK(cs);
655  Check();
656  Good_(addr, test_before_evict, nTime);
657  Check();
658  }
659 
661  void Attempt(const CService& addr, bool fCountFailure, int64_t nTime = GetAdjustedTime())
662  {
663  LOCK(cs);
664  Check();
665  Attempt_(addr, fCountFailure, nTime);
666  Check();
667  }
668 
671  {
672  LOCK(cs);
673  Check();
675  Check();
676  }
677 
680  {
681  CAddrInfo ret;
682  {
683  LOCK(cs);
684  Check();
685  ret = SelectTriedCollision_();
686  Check();
687  }
688  return ret;
689  }
690 
695  CAddrInfo Select(bool newOnly = false)
696  {
697  CAddrInfo addrRet;
698  {
699  LOCK(cs);
700  Check();
701  addrRet = Select_(newOnly);
702  Check();
703  }
704  return addrRet;
705  }
706 
714  std::vector<CAddress> GetAddr(size_t max_addresses, size_t max_pct, Optional<Network> network)
715  {
716  Check();
717  std::vector<CAddress> vAddr;
718  {
719  LOCK(cs);
720  GetAddr_(vAddr, max_addresses, max_pct, network);
721  }
722  Check();
723  return vAddr;
724  }
725 
727  void Connected(const CService& addr, int64_t nTime = GetAdjustedTime())
728  {
729  LOCK(cs);
730  Check();
731  Connected_(addr, nTime);
732  Check();
733  }
734 
735  void SetServices(const CService& addr, ServiceFlags nServices)
736  {
737  LOCK(cs);
738  Check();
739  SetServices_(addr, nServices);
740  Check();
741  }
742 
743 };
744 
745 #endif // PIVX_ADDRMAN_H
#define ADDRMAN_NEW_BUCKETS_PER_ADDRESS
in how many buckets for entries with new addresses a single address may occur
Definition: addrman.h:146
#define ADDRMAN_BUCKET_SIZE
Definition: addrman.h:166
#define ADDRMAN_NEW_BUCKET_COUNT
Definition: addrman.h:165
#define ADDRMAN_TRIED_BUCKET_COUNT
Convenience.
Definition: addrman.h:164
Extended statistics about a CAddress.
Definition: addrman.h:37
CAddrInfo(const CAddress &addrIn, const CNetAddr &addrSource)
Definition: addrman.h:74
int GetTriedBucket(const uint256 &nKey, const std::vector< bool > &asmap) const
Calculate in which "tried" bucket this entry belongs.
Definition: addrman.cpp:17
int nAttempts
connection attempts since last successful attempt
Definition: addrman.h:53
int64_t nLastSuccess
last successful connection by us
Definition: addrman.h:50
int GetBucketPosition(const uint256 &nKey, bool fNew, int nBucket) const
Calculate in which position of a bucket to store this entry.
Definition: addrman.cpp:38
int64_t nLastCountAttempt
last counted attempt (memory only)
Definition: addrman.h:43
int64_t nLastTry
last try whatsoever by us (memory only)
Definition: addrman.h:40
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:44
int nRandomPos
position in vRandom
Definition: addrman.h:62
bool fInTried
in tried set? (memory only)
Definition: addrman.h:59
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:89
SERIALIZE_METHODS(CAddrInfo, obj)
Definition: addrman.h:68
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:27
int nRefCount
reference count in new sets (memory only)
Definition: addrman.h:56
CNetAddr source
where knowledge about this address first came from
Definition: addrman.h:47
CAddrInfo()
Definition: addrman.h:78
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:64
Stochastical (IP) address manager.
Definition: addrman.h:178
bool Add(const CAddress &addr, const CNetAddr &source, int64_t nTimePenalty=0)
Add a single address.
Definition: addrman.h:623
int64_t nLastGood GUARDED_BY(cs)
last time Good was called (memory only)
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:205
void Unserialize(Stream &s_)
Definition: addrman.h:428
void Serialize(Stream &s_) const
Serialized format.
Definition: addrman.h:363
void Delete(int nId) EXCLUSIVE_LOCKS_REQUIRED(cs)
Delete an entry. It must not be in tried, and have refcount 0.
Definition: addrman.cpp:124
std::vector< int > vRandom GUARDED_BY(cs)
randomly-ordered vector of all nIds
void Check()
Consistency check.
Definition: addrman.h:610
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:258
Format
Serialization versions.
Definition: addrman.h:186
@ V1_DETERMINISTIC
for pre-asmap files
Definition: addrman.h:188
@ V0_HISTORICAL
historic format, before commit e6b343d88
Definition: addrman.h:187
@ V3_BIP155
same as V2_ASMAP plus addresses are in BIP155 format
Definition: addrman.h:190
@ V2_ASMAP
for files including asmap version
Definition: addrman.h:189
int vvTried[ADDRMAN_TRIED_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE] GUARDED_BY(cs)
list of "tried" buckets
FastRandomContext insecure_rand
Source of random numbers for randomization in inner loops.
Definition: addrman.h:242
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:92
size_t size() const
Return the number of (unique) addresses in all tables.
Definition: addrman.h:603
int vvNew[ADDRMAN_NEW_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE] GUARDED_BY(cs)
list of "new" buckets
void Attempt(const CService &addr, bool fCountFailure, int64_t nTime=GetAdjustedTime())
Mark an entry as connection attempted to.
Definition: addrman.h:661
int nIdCount GUARDED_BY(cs)
last used nId
CAddrInfo SelectTriedCollision_() EXCLUSIVE_LOCKS_REQUIRED(cs)
Return a random to-be-evicted tried table address.
Definition: addrman.cpp:606
void Clear()
Definition: addrman.h:568
void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2) EXCLUSIVE_LOCKS_REQUIRED(cs)
Swap two elements in vRandom.
Definition: addrman.cpp:104
std::set< int > m_tried_collisions
Holds addrs inserted into tried table that collide with existing entries. Test-before-evict disciplin...
Definition: addrman.h:235
CAddrInfo Select(bool newOnly=false)
Choose an address to connect to.
Definition: addrman.h:695
RecursiveMutex cs
critical section to protect the inner data structures
Definition: addrman.h:182
void ResolveCollisions()
See if any to-be-evicted tried table entries have been tested and if so resolve the collisions.
Definition: addrman.h:670
CAddrInfo SelectTriedCollision()
Randomly select an address in tried that another address is attempting to evict.
Definition: addrman.h:679
CAddrInfo * Find(const CNetAddr &addr, int *pnId=nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs)
Find an entry.
Definition: addrman.cpp:79
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:138
void Connected(const CService &addr, int64_t nTime=GetAdjustedTime())
Mark an entry as currently-connected-to.
Definition: addrman.h:727
void GetAddr_(std::vector< CAddress > &vAddr, size_t max_addresses, size_t max_pct, Optional< Network > network) EXCLUSIVE_LOCKS_REQUIRED(cs)
Return all or many randomly selected addresses, optionally by network.
Definition: addrman.cpp:477
std::map< CNetAddr, int > mapAddr GUARDED_BY(cs)
find an nId based on its network address
int nNew GUARDED_BY(cs)
number of (unique) "new" entries
void Attempt_(const CService &addr, bool fCountFailure, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs)
Mark an entry as attempted to connect.
Definition: addrman.cpp:331
int nTried GUARDED_BY(cs)
bool Add(const std::vector< CAddress > &vAddr, const CNetAddr &source, int64_t nTimePenalty=0)
Add multiple addresses.
Definition: addrman.h:637
static constexpr Format FILE_FORMAT
The maximum format this software knows it can unserialize.
Definition: addrman.h:198
std::map< int, CAddrInfo > mapInfo GUARDED_BY(cs)
table with information about all nIds
void SetServices(const CService &addr, ServiceFlags nServices)
Definition: addrman.h:735
std::vector< bool > m_asmap
Definition: addrman.h:317
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:204
static std::vector< bool > DecodeAsmap(fs::path path)
Definition: addrman.cpp:633
void Good(const CService &addr, bool test_before_evict=true, int64_t nTime=GetAdjustedTime())
Mark an entry as accessible.
Definition: addrman.h:652
void SetServices_(const CService &addr, ServiceFlags nServices) EXCLUSIVE_LOCKS_REQUIRED(cs)
Update an entry's service bits.
Definition: addrman.cpp:529
CAddrMan()
Definition: addrman.h:592
uint256 nKey
secret key to randomize bucket select with
Definition: addrman.h:239
void Connected_(const CService &addr, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs)
Mark an entry as currently-connected-to.
Definition: addrman.cpp:509
~CAddrMan()
Definition: addrman.h:597
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:353
std::vector< CAddress > GetAddr(size_t max_addresses, size_t max_pct, Optional< Network > network)
Return all or many randomly selected addresses, optionally by network.
Definition: addrman.h:714
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:153
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
A CService with information about it as peer.
Definition: protocol.h:338
Network address.
Definition: netaddress.h:120
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:484
std::string ToStringIPPort() const
Definition: netaddress.cpp:945
Fast randomness source.
Definition: random.h:107
uint256 rand256() noexcept
generate a random uint256.
Definition: random.cpp:621
void SetNull()
Definition: uint256.h:44
256-bit opaque blob.
Definition: uint256.h:138
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:289
@ LOCK
Definition: lockunlock.h:16
#define LogPrint(category,...)
Definition: logging.h:163
@ ADDRMAN
Definition: logging.h:50
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:958
boost::optional< T > Optional
Substitute for C++17 std::optional.
Definition: optional.h:12
#define PACKAGE_NAME
Definition: pivx-config.h:366
ServiceFlags
nServices flags
Definition: protocol.h:312
const char * source
Definition: rpcconsole.cpp:52
#define READWRITEAS(type, obj)
Definition: serialize.h:184
#define READWRITE(...)
Definition: serialize.h:183
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:50
int64_t GetAdjustedTime()
Definition: timedata.cpp:36
#define strprintf
Definition: tinyformat.h:1056