BSHA3  0.17.99
P2P Blockchain, based on Bitcoin
addrman.h
Go to the documentation of this file.
1 // Copyright (c) 2012 Pieter Wuille
2 // Copyright (c) 2012-2018 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.h>
15 
16 #include <map>
17 #include <set>
18 #include <stdint.h>
19 #include <vector>
20 
24 class CAddrInfo : public CAddress
25 {
26 
27 
28 public:
30  int64_t nLastTry;
31 
34 
35 private:
38 
40  int64_t nLastSuccess;
41 
43  int nAttempts;
44 
46  int nRefCount;
47 
49  bool fInTried;
50 
53 
54  friend class CAddrMan;
55 
56 public:
57 
59 
60  template <typename Stream, typename Operation>
61  inline void SerializationOp(Stream& s, Operation ser_action) {
62  READWRITEAS(CAddress, *this);
66  }
67 
68  void Init()
69  {
70  nLastSuccess = 0;
71  nLastTry = 0;
73  nAttempts = 0;
74  nRefCount = 0;
75  fInTried = false;
76  nRandomPos = -1;
77  }
78 
79  CAddrInfo(const CAddress &addrIn, const CNetAddr &addrSource) : CAddress(addrIn), source(addrSource)
80  {
81  Init();
82  }
83 
85  {
86  Init();
87  }
88 
90  int GetTriedBucket(const uint256 &nKey) const;
91 
93  int GetNewBucket(const uint256 &nKey, const CNetAddr& src) const;
94 
96  int GetNewBucket(const uint256 &nKey) const
97  {
98  return GetNewBucket(nKey, source);
99  }
100 
102  int GetBucketPosition(const uint256 &nKey, bool fNew, int nBucket) const;
103 
105  bool IsTerrible(int64_t nNow = GetAdjustedTime()) const;
106 
108  double GetChance(int64_t nNow = GetAdjustedTime()) const;
109 
110 };
111 
138 #define ADDRMAN_TRIED_BUCKET_COUNT_LOG2 8
140 
142 #define ADDRMAN_NEW_BUCKET_COUNT_LOG2 10
143 
145 #define ADDRMAN_BUCKET_SIZE_LOG2 6
146 
148 #define ADDRMAN_TRIED_BUCKETS_PER_GROUP 8
149 
151 #define ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP 64
152 
154 #define ADDRMAN_NEW_BUCKETS_PER_ADDRESS 8
155 
157 #define ADDRMAN_HORIZON_DAYS 30
158 
160 #define ADDRMAN_RETRIES 3
161 
163 #define ADDRMAN_MAX_FAILURES 10
164 
166 #define ADDRMAN_MIN_FAIL_DAYS 7
167 
169 #define ADDRMAN_REPLACEMENT_HOURS 4
170 
172 #define ADDRMAN_GETADDR_MAX_PCT 23
173 
175 #define ADDRMAN_GETADDR_MAX 2500
176 
178 #define ADDRMAN_TRIED_BUCKET_COUNT (1 << ADDRMAN_TRIED_BUCKET_COUNT_LOG2)
179 #define ADDRMAN_NEW_BUCKET_COUNT (1 << ADDRMAN_NEW_BUCKET_COUNT_LOG2)
180 #define ADDRMAN_BUCKET_SIZE (1 << ADDRMAN_BUCKET_SIZE_LOG2)
181 
183 #define ADDRMAN_SET_TRIED_COLLISION_SIZE 10
184 
188 class CAddrMan
189 {
190 protected:
193 
194 private:
196  int nIdCount GUARDED_BY(cs);
197 
199  std::map<int, CAddrInfo> mapInfo GUARDED_BY(cs);
200 
202  std::map<CNetAddr, int> mapAddr GUARDED_BY(cs);
203 
205  std::vector<int> vRandom GUARDED_BY(cs);
206 
207  // number of "tried" entries
208  int nTried GUARDED_BY(cs);
209 
212 
214  int nNew GUARDED_BY(cs);
215 
218 
220  int64_t nLastGood GUARDED_BY(cs);
221 
223  std::set<int> m_tried_collisions;
224 
225 protected:
228 
231 
233  CAddrInfo* Find(const CNetAddr& addr, int *pnId = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs);
234 
237  CAddrInfo* Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs);
238 
240  void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2) EXCLUSIVE_LOCKS_REQUIRED(cs);
241 
243  void MakeTried(CAddrInfo& info, int nId) EXCLUSIVE_LOCKS_REQUIRED(cs);
244 
246  void Delete(int nId) EXCLUSIVE_LOCKS_REQUIRED(cs);
247 
249  void ClearNew(int nUBucket, int nUBucketPos) EXCLUSIVE_LOCKS_REQUIRED(cs);
250 
252  void Good_(const CService &addr, bool test_before_evict, int64_t time) EXCLUSIVE_LOCKS_REQUIRED(cs);
253 
255  bool Add_(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty) EXCLUSIVE_LOCKS_REQUIRED(cs);
256 
258  void Attempt_(const CService &addr, bool fCountFailure, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs);
259 
262 
265 
268 
270  virtual int RandomInt(int nMax);
271 
272 #ifdef DEBUG_ADDRMAN
273  int Check_() EXCLUSIVE_LOCKS_REQUIRED(cs);
275 #endif
276 
278  void GetAddr_(std::vector<CAddress> &vAddr) EXCLUSIVE_LOCKS_REQUIRED(cs);
279 
281  void Connected_(const CService &addr, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs);
282 
284  void SetServices_(const CService &addr, ServiceFlags nServices) EXCLUSIVE_LOCKS_REQUIRED(cs);
285 
286 public:
316  template<typename Stream>
317  void Serialize(Stream &s) const
318  {
319  LOCK(cs);
320 
321  unsigned char nVersion = 1;
322  s << nVersion;
323  s << ((unsigned char)32);
324  s << nKey;
325  s << nNew;
326  s << nTried;
327 
328  int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30);
329  s << nUBuckets;
330  std::map<int, int> mapUnkIds;
331  int nIds = 0;
332  for (const auto& entry : mapInfo) {
333  mapUnkIds[entry.first] = nIds;
334  const CAddrInfo &info = entry.second;
335  if (info.nRefCount) {
336  assert(nIds != nNew); // this means nNew was wrong, oh ow
337  s << info;
338  nIds++;
339  }
340  }
341  nIds = 0;
342  for (const auto& entry : mapInfo) {
343  const CAddrInfo &info = entry.second;
344  if (info.fInTried) {
345  assert(nIds != nTried); // this means nTried was wrong, oh ow
346  s << info;
347  nIds++;
348  }
349  }
350  for (int bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) {
351  int nSize = 0;
352  for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
353  if (vvNew[bucket][i] != -1)
354  nSize++;
355  }
356  s << nSize;
357  for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
358  if (vvNew[bucket][i] != -1) {
359  int nIndex = mapUnkIds[vvNew[bucket][i]];
360  s << nIndex;
361  }
362  }
363  }
364  }
365 
366  template<typename Stream>
367  void Unserialize(Stream& s)
368  {
369  LOCK(cs);
370 
371  Clear();
372 
373  unsigned char nVersion;
374  s >> nVersion;
375  unsigned char nKeySize;
376  s >> nKeySize;
377  if (nKeySize != 32) throw std::ios_base::failure("Incorrect keysize in addrman deserialization");
378  s >> nKey;
379  s >> nNew;
380  s >> nTried;
381  int nUBuckets = 0;
382  s >> nUBuckets;
383  if (nVersion != 0) {
384  nUBuckets ^= (1 << 30);
385  }
386 
388  throw std::ios_base::failure("Corrupt CAddrMan serialization, nNew exceeds limit.");
389  }
390 
392  throw std::ios_base::failure("Corrupt CAddrMan serialization, nTried exceeds limit.");
393  }
394 
395  // Deserialize entries from the new table.
396  for (int n = 0; n < nNew; n++) {
397  CAddrInfo &info = mapInfo[n];
398  s >> info;
399  mapAddr[info] = n;
400  info.nRandomPos = vRandom.size();
401  vRandom.push_back(n);
402  if (nVersion != 1 || nUBuckets != ADDRMAN_NEW_BUCKET_COUNT) {
403  // In case the new table data cannot be used (nVersion unknown, or bucket count wrong),
404  // immediately try to give them a reference based on their primary source address.
405  int nUBucket = info.GetNewBucket(nKey);
406  int nUBucketPos = info.GetBucketPosition(nKey, true, nUBucket);
407  if (vvNew[nUBucket][nUBucketPos] == -1) {
408  vvNew[nUBucket][nUBucketPos] = n;
409  info.nRefCount++;
410  }
411  }
412  }
413  nIdCount = nNew;
414 
415  // Deserialize entries from the tried table.
416  int nLost = 0;
417  for (int n = 0; n < nTried; n++) {
418  CAddrInfo info;
419  s >> info;
420  int nKBucket = info.GetTriedBucket(nKey);
421  int nKBucketPos = info.GetBucketPosition(nKey, false, nKBucket);
422  if (vvTried[nKBucket][nKBucketPos] == -1) {
423  info.nRandomPos = vRandom.size();
424  info.fInTried = true;
425  vRandom.push_back(nIdCount);
426  mapInfo[nIdCount] = info;
427  mapAddr[info] = nIdCount;
428  vvTried[nKBucket][nKBucketPos] = nIdCount;
429  nIdCount++;
430  } else {
431  nLost++;
432  }
433  }
434  nTried -= nLost;
435 
436  // Deserialize positions in the new table (if possible).
437  for (int bucket = 0; bucket < nUBuckets; bucket++) {
438  int nSize = 0;
439  s >> nSize;
440  for (int n = 0; n < nSize; n++) {
441  int nIndex = 0;
442  s >> nIndex;
443  if (nIndex >= 0 && nIndex < nNew) {
444  CAddrInfo &info = mapInfo[nIndex];
445  int nUBucketPos = info.GetBucketPosition(nKey, true, bucket);
446  if (nVersion == 1 && nUBuckets == ADDRMAN_NEW_BUCKET_COUNT && vvNew[bucket][nUBucketPos] == -1 && info.nRefCount < ADDRMAN_NEW_BUCKETS_PER_ADDRESS) {
447  info.nRefCount++;
448  vvNew[bucket][nUBucketPos] = nIndex;
449  }
450  }
451  }
452  }
453 
454  // Prune new entries with refcount 0 (as a result of collisions).
455  int nLostUnk = 0;
456  for (std::map<int, CAddrInfo>::const_iterator it = mapInfo.begin(); it != mapInfo.end(); ) {
457  if (it->second.fInTried == false && it->second.nRefCount == 0) {
458  std::map<int, CAddrInfo>::const_iterator itCopy = it++;
459  Delete(itCopy->first);
460  nLostUnk++;
461  } else {
462  it++;
463  }
464  }
465  if (nLost + nLostUnk > 0) {
466  LogPrint(BCLog::ADDRMAN, "addrman lost %i new and %i tried addresses due to collisions\n", nLostUnk, nLost);
467  }
468 
469  Check();
470  }
471 
472  void Clear()
473  {
474  LOCK(cs);
475  std::vector<int>().swap(vRandom);
476  nKey = GetRandHash();
477  for (size_t bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) {
478  for (size_t entry = 0; entry < ADDRMAN_BUCKET_SIZE; entry++) {
479  vvNew[bucket][entry] = -1;
480  }
481  }
482  for (size_t bucket = 0; bucket < ADDRMAN_TRIED_BUCKET_COUNT; bucket++) {
483  for (size_t entry = 0; entry < ADDRMAN_BUCKET_SIZE; entry++) {
484  vvTried[bucket][entry] = -1;
485  }
486  }
487 
488  nIdCount = 0;
489  nTried = 0;
490  nNew = 0;
491  nLastGood = 1; //Initially at 1 so that "never" is strictly worse.
492  mapInfo.clear();
493  mapAddr.clear();
494  }
495 
497  {
498  Clear();
499  }
500 
502  {
503  nKey.SetNull();
504  }
505 
507  size_t size() const
508  {
509  LOCK(cs); // TODO: Cache this in an atomic to avoid this overhead
510  return vRandom.size();
511  }
512 
514  void Check()
515  {
516 #ifdef DEBUG_ADDRMAN
517  {
518  LOCK(cs);
519  int err;
520  if ((err=Check_()))
521  LogPrintf("ADDRMAN CONSISTENCY CHECK FAILED!!! err=%i\n", err);
522  }
523 #endif
524  }
525 
527  bool Add(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty = 0)
528  {
529  LOCK(cs);
530  bool fRet = false;
531  Check();
532  fRet |= Add_(addr, source, nTimePenalty);
533  Check();
534  if (fRet) {
535  LogPrint(BCLog::ADDRMAN, "Added %s from %s: %i tried, %i new\n", addr.ToStringIPPort(), source.ToString(), nTried, nNew);
536  }
537  return fRet;
538  }
539 
541  bool Add(const std::vector<CAddress> &vAddr, const CNetAddr& source, int64_t nTimePenalty = 0)
542  {
543  LOCK(cs);
544  int nAdd = 0;
545  Check();
546  for (std::vector<CAddress>::const_iterator it = vAddr.begin(); it != vAddr.end(); it++)
547  nAdd += Add_(*it, source, nTimePenalty) ? 1 : 0;
548  Check();
549  if (nAdd) {
550  LogPrint(BCLog::ADDRMAN, "Added %i addresses from %s: %i tried, %i new\n", nAdd, source.ToString(), nTried, nNew);
551  }
552  return nAdd > 0;
553  }
554 
556  void Good(const CService &addr, bool test_before_evict = true, int64_t nTime = GetAdjustedTime())
557  {
558  LOCK(cs);
559  Check();
560  Good_(addr, test_before_evict, nTime);
561  Check();
562  }
563 
565  void Attempt(const CService &addr, bool fCountFailure, int64_t nTime = GetAdjustedTime())
566  {
567  LOCK(cs);
568  Check();
569  Attempt_(addr, fCountFailure, nTime);
570  Check();
571  }
572 
575  {
576  LOCK(cs);
577  Check();
579  Check();
580  }
581 
584  {
585  CAddrInfo ret;
586  {
587  LOCK(cs);
588  Check();
590  Check();
591  }
592  return ret;
593  }
594 
598  CAddrInfo Select(bool newOnly = false)
599  {
600  CAddrInfo addrRet;
601  {
602  LOCK(cs);
603  Check();
604  addrRet = Select_(newOnly);
605  Check();
606  }
607  return addrRet;
608  }
609 
611  std::vector<CAddress> GetAddr()
612  {
613  Check();
614  std::vector<CAddress> vAddr;
615  {
616  LOCK(cs);
617  GetAddr_(vAddr);
618  }
619  Check();
620  return vAddr;
621  }
622 
624  void Connected(const CService &addr, int64_t nTime = GetAdjustedTime())
625  {
626  LOCK(cs);
627  Check();
628  Connected_(addr, nTime);
629  Check();
630  }
631 
632  void SetServices(const CService &addr, ServiceFlags nServices)
633  {
634  LOCK(cs);
635  Check();
636  SetServices_(addr, nServices);
637  Check();
638  }
639 
640 };
641 
642 #endif // BITCOIN_ADDRMAN_H
int nRefCount
reference count in new sets (memory only)
Definition: addrman.h:46
uint256 GetRandHash()
Definition: random.cpp:374
ServiceFlags
nServices flags
Definition: protocol.h:247
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:537
CAddrInfo Select(bool newOnly=false)
Choose an address to connect to.
Definition: addrman.h:598
void SetNull()
Definition: uint256.h:40
void Attempt(const CService &addr, bool fCountFailure, int64_t nTime=GetAdjustedTime())
Mark an entry as connection attempted to.
Definition: addrman.h:565
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:81
void SetServices_(const CService &addr, ServiceFlags nServices) EXCLUSIVE_LOCKS_REQUIRED(cs)
Update an entry&#39;s service bits.
Definition: addrman.cpp:515
UniValue ret(UniValue::VARR)
Definition: rpcwallet.cpp:1140
~CAddrMan()
Definition: addrman.h:501
void Delete(int nId) EXCLUSIVE_LOCKS_REQUIRED(cs)
Delete an entry. It must not be in tried, and have refcount 0.
Definition: addrman.cpp:113
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:190
void Attempt_(const CService &addr, bool fCountFailure, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs)
Mark an entry as attempted to connect.
Definition: addrman.cpp:327
int nAttempts
connection attempts since last successful attempt
Definition: addrman.h:43
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:254
std::set< int > m_tried_collisions
Holds addrs inserted into tried table that collide with existing entries. Test-before-evict disciplin...
Definition: addrman.h:223
int nIdCount GUARDED_BY(cs)
last used nId
virtual int RandomInt(int nMax)
Wraps GetRandInt to allow tests to override RandomInt and make it determinismistic.
Definition: addrman.cpp:533
void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2) EXCLUSIVE_LOCKS_REQUIRED(cs)
Swap two elements in vRandom.
Definition: addrman.cpp:93
int nRandomPos
position in vRandom
Definition: addrman.h:52
CAddrInfo SelectTriedCollision_() EXCLUSIVE_LOCKS_REQUIRED(cs)
Return a random to-be-evicted tried table address.
Definition: addrman.cpp:589
bool Add(const CAddress &addr, const CNetAddr &source, int64_t nTimePenalty=0)
Add a single address.
Definition: addrman.h:527
#define ADDRMAN_TRIED_BUCKET_COUNT
Convenience.
Definition: addrman.h:178
#define READWRITEAS(type, obj)
Definition: serialize.h:174
bool fInTried
in tried set? (memory only)
Definition: addrman.h:49
Stochastical (IP) address manager.
Definition: addrman.h:188
std::vector< CAddress > GetAddr()
Return a bunch of addresses, selected at random.
Definition: addrman.h:611
Extended statistics about a CAddress.
Definition: addrman.h:24
const char * source
Definition: rpcconsole.cpp:54
int GetNewBucket(const uint256 &nKey, const CNetAddr &src) const
Calculate in which "new" bucket this entry belongs, given a certain source.
Definition: addrman.cpp:19
int GetTriedBucket(const uint256 &nKey) const
Calculate in which "tried" bucket this entry belongs.
Definition: addrman.cpp:12
FastRandomContext insecure_rand
Source of random numbers for randomization in inner loops.
Definition: addrman.h:230
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:142
void Unserialize(Stream &s)
Definition: addrman.h:367
#define LOCK(cs)
Definition: sync.h:181
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:142
Fast randomness source.
Definition: random.h:45
void Check()
Consistency check.
Definition: addrman.h:514
A CService with information about it as peer.
Definition: protocol.h:328
ADD_SERIALIZE_METHODS
Definition: addrman.h:58
#define ADDRMAN_BUCKET_SIZE
Definition: addrman.h:180
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:33
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:127
CAddrInfo()
Definition: addrman.h:84
IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96))
Definition: netaddress.h:32
size_t size() const
Return the number of (unique) addresses in all tables.
Definition: addrman.h:507
256-bit opaque blob.
Definition: uint256.h:122
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:51
void Init()
Definition: addrman.h:68
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:349
int GetBucketPosition(const uint256 &nKey, bool fNew, int nBucket) const
Calculate in which position of a bucket to store this entry.
Definition: addrman.cpp:27
void Connected_(const CService &addr, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs)
Mark an entry as currently-connected-to.
Definition: addrman.cpp:495
void Clear()
Definition: addrman.h:472
CAddrMan()
Definition: addrman.h:496
CAddrInfo(const CAddress &addrIn, const CNetAddr &addrSource)
Definition: addrman.h:79
#define ADDRMAN_NEW_BUCKET_COUNT
Definition: addrman.h:179
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:583
std::string ToStringIPPort() const
Definition: netaddress.cpp:565
int GetNewBucket(const uint256 &nKey) const
Calculate in which "new" bucket this entry belongs, using its default source.
Definition: addrman.h:96
void SerializationOp(Stream &s, Operation ser_action)
Definition: addrman.h:61
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:53
int64_t nLastCountAttempt
last counted attempt (memory only)
Definition: addrman.h:33
void GetAddr_(std::vector< CAddress > &vAddr) EXCLUSIVE_LOCKS_REQUIRED(cs)
Select several addresses at once.
Definition: addrman.cpp:474
void ResolveCollisions()
See if any to-be-evicted tried table entries have been tested and if so resolve the collisions...
Definition: addrman.h:574
bool Add(const std::vector< CAddress > &vAddr, const CNetAddr &source, int64_t nTimePenalty=0)
Add multiple addresses.
Definition: addrman.h:541
void Good(const CService &addr, bool test_before_evict=true, int64_t nTime=GetAdjustedTime())
Mark an entry as accessible.
Definition: addrman.h:556
void SetServices(const CService &addr, ServiceFlags nServices)
Definition: addrman.h:632
uint256 nKey
secret key to randomize bucket select with
Definition: addrman.h:227
void Serialize(Stream &s) const
serialized format:
Definition: addrman.h:317
#define READWRITE(...)
Definition: serialize.h:173
void Connected(const CService &addr, int64_t nTime=GetAdjustedTime())
Mark an entry as currently-connected-to.
Definition: addrman.h:624
int64_t nLastSuccess
last successful connection by us
Definition: addrman.h:40
CCriticalSection cs
critical section to protect the inner data structures
Definition: addrman.h:192
int64_t nLastTry
last try whatsoever by us (memory only)
Definition: addrman.h:30
#define ADDRMAN_NEW_BUCKETS_PER_ADDRESS
in how many buckets for entries with new addresses a single address may occur
Definition: addrman.h:154
CNetAddr source
where knowledge about this address first came from
Definition: addrman.h:37
CAddrInfo * Find(const CNetAddr &addr, int *pnId=nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs)
Find an entry.
Definition: addrman.cpp:68