Bitcoin Core  0.19.99
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 <netaddress.h>
10 #include <protocol.h>
11 #include <random.h>
12 #include <sync.h>
13 #include <timedata.h>
14 #include <util/system.h>
15 #include <clientversion.h>
16 
17 #include <map>
18 #include <set>
19 #include <stdint.h>
20 #include <vector>
21 #include <iostream>
22 #include <streams.h>
23 #include <fs.h>
24 #include <hash.h>
25 
26 
30 class CAddrInfo : public CAddress
31 {
32 public:
34  int64_t nLastTry{0};
35 
37  int64_t nLastCountAttempt{0};
38 
39 private:
42 
44  int64_t nLastSuccess{0};
45 
47  int nAttempts{0};
48 
50  int nRefCount{0};
51 
53  bool fInTried{false};
54 
56  int nRandomPos{-1};
57 
58  friend class CAddrMan;
59 
60 public:
61 
63  {
64  READWRITEAS(CAddress, obj);
65  READWRITE(obj.source, obj.nLastSuccess, obj.nAttempts);
66  }
67 
68  CAddrInfo(const CAddress &addrIn, const CNetAddr &addrSource) : CAddress(addrIn), source(addrSource)
69  {
70  }
71 
72  CAddrInfo() : CAddress(), source()
73  {
74  }
75 
77  int GetTriedBucket(const uint256 &nKey, const std::vector<bool> &asmap) const;
78 
80  int GetNewBucket(const uint256 &nKey, const CNetAddr& src, const std::vector<bool> &asmap) const;
81 
83  int GetNewBucket(const uint256 &nKey, const std::vector<bool> &asmap) const
84  {
85  return GetNewBucket(nKey, source, asmap);
86  }
87 
89  int GetBucketPosition(const uint256 &nKey, bool fNew, int nBucket) const;
90 
92  bool IsTerrible(int64_t nNow = GetAdjustedTime()) const;
93 
95  double GetChance(int64_t nNow = GetAdjustedTime()) const;
96 };
97 
124 #define ADDRMAN_TRIED_BUCKET_COUNT_LOG2 8
126 
128 #define ADDRMAN_NEW_BUCKET_COUNT_LOG2 10
129 
131 #define ADDRMAN_BUCKET_SIZE_LOG2 6
132 
134 #define ADDRMAN_TRIED_BUCKETS_PER_GROUP 8
135 
137 #define ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP 64
138 
140 #define ADDRMAN_NEW_BUCKETS_PER_ADDRESS 8
141 
143 #define ADDRMAN_HORIZON_DAYS 30
144 
146 #define ADDRMAN_RETRIES 3
147 
149 #define ADDRMAN_MAX_FAILURES 10
150 
152 #define ADDRMAN_MIN_FAIL_DAYS 7
153 
155 #define ADDRMAN_REPLACEMENT_HOURS 4
156 
158 #define ADDRMAN_GETADDR_MAX_PCT 23
159 
161 #define ADDRMAN_GETADDR_MAX 2500
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  int nIdCount GUARDED_BY(cs);
187 
189  std::map<int, CAddrInfo> mapInfo GUARDED_BY(cs);
190 
192  std::map<CNetAddr, int> mapAddr GUARDED_BY(cs);
193 
195  std::vector<int> vRandom GUARDED_BY(cs);
196 
197  // number of "tried" entries
198  int nTried GUARDED_BY(cs);
199 
202 
204  int nNew GUARDED_BY(cs);
205 
208 
210  int64_t nLastGood GUARDED_BY(cs);
211 
213  std::set<int> m_tried_collisions;
214 
215 protected:
218 
221 
223  CAddrInfo* Find(const CNetAddr& addr, int *pnId = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs);
224 
227  CAddrInfo* Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs);
228 
230  void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2) EXCLUSIVE_LOCKS_REQUIRED(cs);
231 
233  void MakeTried(CAddrInfo& info, int nId) EXCLUSIVE_LOCKS_REQUIRED(cs);
234 
236  void Delete(int nId) EXCLUSIVE_LOCKS_REQUIRED(cs);
237 
239  void ClearNew(int nUBucket, int nUBucketPos) EXCLUSIVE_LOCKS_REQUIRED(cs);
240 
242  void Good_(const CService &addr, bool test_before_evict, int64_t time) EXCLUSIVE_LOCKS_REQUIRED(cs);
243 
245  bool Add_(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty) EXCLUSIVE_LOCKS_REQUIRED(cs);
246 
248  void Attempt_(const CService &addr, bool fCountFailure, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs);
249 
251  CAddrInfo Select_(bool newOnly) EXCLUSIVE_LOCKS_REQUIRED(cs);
252 
254  void ResolveCollisions_() EXCLUSIVE_LOCKS_REQUIRED(cs);
255 
257  CAddrInfo SelectTriedCollision_() EXCLUSIVE_LOCKS_REQUIRED(cs);
258 
259 #ifdef DEBUG_ADDRMAN
260  int Check_() EXCLUSIVE_LOCKS_REQUIRED(cs);
262 #endif
263 
265  void GetAddr_(std::vector<CAddress> &vAddr) EXCLUSIVE_LOCKS_REQUIRED(cs);
266 
268  void Connected_(const CService &addr, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs);
269 
271  void SetServices_(const CService &addr, ServiceFlags nServices) EXCLUSIVE_LOCKS_REQUIRED(cs);
272 
273 public:
274  // Compressed IP->ASN mapping, loaded from a file when a node starts.
275  // Should be always empty if no file was provided.
276  // This mapping is then used for bucketing nodes in Addrman.
277  //
278  // If asmap is provided, nodes will be bucketed by
279  // AS they belong to, in order to make impossible for a node
280  // to connect to several nodes hosted in a single AS.
281  // This is done in response to Erebus attack, but also to generally
282  // diversify the connections every node creates,
283  // especially useful when a large fraction of nodes
284  // operate under a couple of cloud providers.
285  //
286  // If a new asmap was provided, the existing records
287  // would be re-bucketed accordingly.
288  std::vector<bool> m_asmap;
289 
290  // Read asmap from provided binary file
291  static std::vector<bool> DecodeAsmap(fs::path path);
292 
293 
323  template<typename Stream>
324  void Serialize(Stream &s) const
325  {
326  LOCK(cs);
327 
328  unsigned char nVersion = 2;
329  s << nVersion;
330  s << ((unsigned char)32);
331  s << nKey;
332  s << nNew;
333  s << nTried;
334 
335  int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30);
336  s << nUBuckets;
337  std::map<int, int> mapUnkIds;
338  int nIds = 0;
339  for (const auto& entry : mapInfo) {
340  mapUnkIds[entry.first] = nIds;
341  const CAddrInfo &info = entry.second;
342  if (info.nRefCount) {
343  assert(nIds != nNew); // this means nNew was wrong, oh ow
344  s << info;
345  nIds++;
346  }
347  }
348  nIds = 0;
349  for (const auto& entry : mapInfo) {
350  const CAddrInfo &info = entry.second;
351  if (info.fInTried) {
352  assert(nIds != nTried); // this means nTried was wrong, oh ow
353  s << info;
354  nIds++;
355  }
356  }
357  for (int bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) {
358  int nSize = 0;
359  for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
360  if (vvNew[bucket][i] != -1)
361  nSize++;
362  }
363  s << nSize;
364  for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
365  if (vvNew[bucket][i] != -1) {
366  int nIndex = mapUnkIds[vvNew[bucket][i]];
367  s << nIndex;
368  }
369  }
370  }
371  // Store asmap version after bucket entries so that it
372  // can be ignored by older clients for backward compatibility.
373  uint256 asmap_version;
374  if (m_asmap.size() != 0) {
375  asmap_version = SerializeHash(m_asmap);
376  }
377  s << asmap_version;
378  }
379 
380  template<typename Stream>
381  void Unserialize(Stream& s)
382  {
383  LOCK(cs);
384 
385  Clear();
386  unsigned char nVersion;
387  s >> nVersion;
388  unsigned char nKeySize;
389  s >> nKeySize;
390  if (nKeySize != 32) throw std::ios_base::failure("Incorrect keysize in addrman deserialization");
391  s >> nKey;
392  s >> nNew;
393  s >> nTried;
394  int nUBuckets = 0;
395  s >> nUBuckets;
396  if (nVersion != 0) {
397  nUBuckets ^= (1 << 30);
398  }
399 
401  throw std::ios_base::failure("Corrupt CAddrMan serialization, nNew exceeds limit.");
402  }
403 
404  if (nTried > ADDRMAN_TRIED_BUCKET_COUNT * ADDRMAN_BUCKET_SIZE) {
405  throw std::ios_base::failure("Corrupt CAddrMan serialization, nTried exceeds limit.");
406  }
407 
408  // Deserialize entries from the new table.
409  for (int n = 0; n < nNew; n++) {
410  CAddrInfo &info = mapInfo[n];
411  s >> info;
412  mapAddr[info] = n;
413  info.nRandomPos = vRandom.size();
414  vRandom.push_back(n);
415  }
416  nIdCount = nNew;
417 
418  // Deserialize entries from the tried table.
419  int nLost = 0;
420  for (int n = 0; n < nTried; n++) {
421  CAddrInfo info;
422  s >> info;
423  int nKBucket = info.GetTriedBucket(nKey, m_asmap);
424  int nKBucketPos = info.GetBucketPosition(nKey, false, nKBucket);
425  if (vvTried[nKBucket][nKBucketPos] == -1) {
426  info.nRandomPos = vRandom.size();
427  info.fInTried = true;
428  vRandom.push_back(nIdCount);
429  mapInfo[nIdCount] = info;
430  mapAddr[info] = nIdCount;
431  vvTried[nKBucket][nKBucketPos] = nIdCount;
432  nIdCount++;
433  } else {
434  nLost++;
435  }
436  }
437  nTried -= nLost;
438 
439  // Store positions in the new table buckets to apply later (if possible).
440  std::map<int, int> entryToBucket; // Represents which entry belonged to which bucket when serializing
441 
442  for (int bucket = 0; bucket < nUBuckets; bucket++) {
443  int nSize = 0;
444  s >> nSize;
445  for (int n = 0; n < nSize; n++) {
446  int nIndex = 0;
447  s >> nIndex;
448  if (nIndex >= 0 && nIndex < nNew) {
449  entryToBucket[nIndex] = bucket;
450  }
451  }
452  }
453 
454  uint256 supplied_asmap_version;
455  if (m_asmap.size() != 0) {
456  supplied_asmap_version = SerializeHash(m_asmap);
457  }
458  uint256 serialized_asmap_version;
459  if (nVersion > 1) {
460  s >> serialized_asmap_version;
461  }
462 
463  for (int n = 0; n < nNew; n++) {
464  CAddrInfo &info = mapInfo[n];
465  int bucket = entryToBucket[n];
466  int nUBucketPos = info.GetBucketPosition(nKey, true, bucket);
467  if (nVersion == 2 && nUBuckets == ADDRMAN_NEW_BUCKET_COUNT && vvNew[bucket][nUBucketPos] == -1 &&
468  info.nRefCount < ADDRMAN_NEW_BUCKETS_PER_ADDRESS && serialized_asmap_version == supplied_asmap_version) {
469  // Bucketing has not changed, using existing bucket positions for the new table
470  vvNew[bucket][nUBucketPos] = n;
471  info.nRefCount++;
472  } else {
473  // In case the new table data cannot be used (nVersion unknown, bucket count wrong or new asmap),
474  // try to give them a reference based on their primary source address.
475  LogPrint(BCLog::ADDRMAN, "Bucketing method was updated, re-bucketing addrman entries from disk\n");
476  bucket = info.GetNewBucket(nKey, m_asmap);
477  nUBucketPos = info.GetBucketPosition(nKey, true, bucket);
478  if (vvNew[bucket][nUBucketPos] == -1) {
479  vvNew[bucket][nUBucketPos] = n;
480  info.nRefCount++;
481  }
482  }
483  }
484 
485  // Prune new entries with refcount 0 (as a result of collisions).
486  int nLostUnk = 0;
487  for (std::map<int, CAddrInfo>::const_iterator it = mapInfo.begin(); it != mapInfo.end(); ) {
488  if (it->second.fInTried == false && it->second.nRefCount == 0) {
489  std::map<int, CAddrInfo>::const_iterator itCopy = it++;
490  Delete(itCopy->first);
491  nLostUnk++;
492  } else {
493  it++;
494  }
495  }
496  if (nLost + nLostUnk > 0) {
497  LogPrint(BCLog::ADDRMAN, "addrman lost %i new and %i tried addresses due to collisions\n", nLostUnk, nLost);
498  }
499 
500  Check();
501  }
502 
503  void Clear()
504  {
505  LOCK(cs);
506  std::vector<int>().swap(vRandom);
507  nKey = insecure_rand.rand256();
508  for (size_t bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) {
509  for (size_t entry = 0; entry < ADDRMAN_BUCKET_SIZE; entry++) {
510  vvNew[bucket][entry] = -1;
511  }
512  }
513  for (size_t bucket = 0; bucket < ADDRMAN_TRIED_BUCKET_COUNT; bucket++) {
514  for (size_t entry = 0; entry < ADDRMAN_BUCKET_SIZE; entry++) {
515  vvTried[bucket][entry] = -1;
516  }
517  }
518 
519  nIdCount = 0;
520  nTried = 0;
521  nNew = 0;
522  nLastGood = 1; //Initially at 1 so that "never" is strictly worse.
523  mapInfo.clear();
524  mapAddr.clear();
525  }
526 
528  {
529  Clear();
530  }
531 
533  {
534  nKey.SetNull();
535  }
536 
538  size_t size() const
539  {
540  LOCK(cs); // TODO: Cache this in an atomic to avoid this overhead
541  return vRandom.size();
542  }
543 
545  void Check()
546  {
547 #ifdef DEBUG_ADDRMAN
548  {
549  LOCK(cs);
550  int err;
551  if ((err=Check_()))
552  LogPrintf("ADDRMAN CONSISTENCY CHECK FAILED!!! err=%i\n", err);
553  }
554 #endif
555  }
556 
558  bool Add(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty = 0)
559  {
560  LOCK(cs);
561  bool fRet = false;
562  Check();
563  fRet |= Add_(addr, source, nTimePenalty);
564  Check();
565  if (fRet) {
566  LogPrint(BCLog::ADDRMAN, "Added %s from %s: %i tried, %i new\n", addr.ToStringIPPort(), source.ToString(), nTried, nNew);
567  }
568  return fRet;
569  }
570 
572  bool Add(const std::vector<CAddress> &vAddr, const CNetAddr& source, int64_t nTimePenalty = 0)
573  {
574  LOCK(cs);
575  int nAdd = 0;
576  Check();
577  for (std::vector<CAddress>::const_iterator it = vAddr.begin(); it != vAddr.end(); it++)
578  nAdd += Add_(*it, source, nTimePenalty) ? 1 : 0;
579  Check();
580  if (nAdd) {
581  LogPrint(BCLog::ADDRMAN, "Added %i addresses from %s: %i tried, %i new\n", nAdd, source.ToString(), nTried, nNew);
582  }
583  return nAdd > 0;
584  }
585 
587  void Good(const CService &addr, bool test_before_evict = true, int64_t nTime = GetAdjustedTime())
588  {
589  LOCK(cs);
590  Check();
591  Good_(addr, test_before_evict, nTime);
592  Check();
593  }
594 
596  void Attempt(const CService &addr, bool fCountFailure, int64_t nTime = GetAdjustedTime())
597  {
598  LOCK(cs);
599  Check();
600  Attempt_(addr, fCountFailure, nTime);
601  Check();
602  }
603 
606  {
607  LOCK(cs);
608  Check();
609  ResolveCollisions_();
610  Check();
611  }
612 
615  {
616  CAddrInfo ret;
617  {
618  LOCK(cs);
619  Check();
620  ret = SelectTriedCollision_();
621  Check();
622  }
623  return ret;
624  }
625 
629  CAddrInfo Select(bool newOnly = false)
630  {
631  CAddrInfo addrRet;
632  {
633  LOCK(cs);
634  Check();
635  addrRet = Select_(newOnly);
636  Check();
637  }
638  return addrRet;
639  }
640 
642  std::vector<CAddress> GetAddr()
643  {
644  Check();
645  std::vector<CAddress> vAddr;
646  {
647  LOCK(cs);
648  GetAddr_(vAddr);
649  }
650  Check();
651  return vAddr;
652  }
653 
655  void Connected(const CService &addr, int64_t nTime = GetAdjustedTime())
656  {
657  LOCK(cs);
658  Check();
659  Connected_(addr, nTime);
660  Check();
661  }
662 
664  {
665  LOCK(cs);
666  Check();
667  SetServices_(addr, nServices);
668  Check();
669  }
670 
671 };
672 
673 #endif // BITCOIN_ADDRMAN_H
int nRefCount
reference count in new sets (memory only)
Definition: addrman.h:50
ServiceFlags
nServices flags
Definition: protocol.h:239
CAddrInfo Select(bool newOnly=false)
Choose an address to connect to.
Definition: addrman.h:629
void SetNull()
Definition: uint256.h:38
#define LogPrint(category,...)
Definition: logging.h:179
void Attempt(const CService &addr, bool fCountFailure, int64_t nTime=GetAdjustedTime())
Mark an entry as connection attempted to.
Definition: addrman.h:596
int GetTriedBucket(const uint256 &nKey, const std::vector< bool > &asmap) const
Calculate in which "tried" bucket this entry belongs.
Definition: addrman.cpp:12
~CAddrMan()
Definition: addrman.h:532
int nAttempts
connection attempts since last successful attempt
Definition: addrman.h:47
uint256 rand256() noexcept
generate a random uint256.
Definition: random.cpp:617
static void LogPrintf(const char *fmt, const Args &... args)
Definition: logging.h:163
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:172
std::set< int > m_tried_collisions
Holds addrs inserted into tried table that collide with existing entries. Test-before-evict disciplin...
Definition: addrman.h:213
std::string ToString() const
Definition: netaddress.cpp:352
int nRandomPos
position in vRandom
Definition: addrman.h:56
bool Add(const CAddress &addr, const CNetAddr &source, int64_t nTimePenalty=0)
Add a single address.
Definition: addrman.h:558
#define ADDRMAN_TRIED_BUCKET_COUNT
Convenience.
Definition: addrman.h:164
#define READWRITEAS(type, obj)
Definition: serialize.h:192
bool fInTried
in tried set? (memory only)
Definition: addrman.h:53
Stochastical (IP) address manager.
Definition: addrman.h:177
RecursiveMutex cs
critical section to protect the inner data structures
Definition: addrman.h:182
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:196
std::vector< CAddress > GetAddr()
Return a bunch of addresses, selected at random.
Definition: addrman.h:642
Extended statistics about a CAddress.
Definition: addrman.h:30
FastRandomContext insecure_rand
Source of random numbers for randomization in inner loops.
Definition: addrman.h:220
void Unserialize(Stream &s)
Definition: addrman.h:381
#define LOCK(cs)
Definition: sync.h:179
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:150
Fast randomness source.
Definition: random.h:106
void Check()
Consistency check.
Definition: addrman.h:545
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:83
A CService with information about it as peer.
Definition: protocol.h:318
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:166
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:72
IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96))
Definition: netaddress.h:31
size_t size() const
Return the number of (unique) addresses in all tables.
Definition: addrman.h:538
256-bit opaque blob.
Definition: uint256.h:120
unsigned int nTime
Definition: protocol.h:350
ServiceFlags nServices
Definition: protocol.h:347
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:51
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:62
void Clear()
Definition: addrman.h:503
CAddrMan()
Definition: addrman.h:527
CAddrInfo(const CAddress &addrIn, const CNetAddr &addrSource)
Definition: addrman.h:68
#define ADDRMAN_NEW_BUCKET_COUNT
Definition: addrman.h:165
int64_t GetAdjustedTime()
Definition: timedata.cpp:35
CAddrInfo SelectTriedCollision()
Randomly select an address in tried that another address is attempting to evict.
Definition: addrman.h:614
std::string ToStringIPPort() const
Definition: netaddress.cpp:736
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
int64_t nLastCountAttempt
last counted attempt (memory only)
Definition: addrman.h:37
void ResolveCollisions()
See if any to-be-evicted tried table entries have been tested and if so resolve the collisions...
Definition: addrman.h:605
#define GUARDED_BY(x)
Definition: threadsafety.h:38
std::vector< bool > m_asmap
Definition: addrman.h:288
bool Add(const std::vector< CAddress > &vAddr, const CNetAddr &source, int64_t nTimePenalty=0)
Add multiple addresses.
Definition: addrman.h:572
void Good(const CService &addr, bool test_before_evict=true, int64_t nTime=GetAdjustedTime())
Mark an entry as accessible.
Definition: addrman.h:587
void SetServices(const CService &addr, ServiceFlags nServices)
Definition: addrman.h:663
uint256 nKey
secret key to randomize bucket select with
Definition: addrman.h:217
void Serialize(Stream &s) const
serialized format:
Definition: addrman.h:324
#define READWRITE(...)
Definition: serialize.h:191
void Connected(const CService &addr, int64_t nTime=GetAdjustedTime())
Mark an entry as currently-connected-to.
Definition: addrman.h:655
auto it
Definition: validation.cpp:362
int64_t nLastSuccess
last successful connection by us
Definition: addrman.h:44
int64_t nLastTry
last try whatsoever by us (memory only)
Definition: addrman.h:34
#define ADDRMAN_NEW_BUCKETS_PER_ADDRESS
in how many buckets for entries with new addresses a single address may occur
Definition: addrman.h:140
CNetAddr source
where knowledge about this address first came from
Definition: addrman.h:41