Dash Core Source Documentation (0.16.0.1)

Find detailed information regarding the Dash Core source code.

addrman.cpp
Go to the documentation of this file.
1 // Copyright (c) 2012 Pieter Wuille
2 // Copyright (c) 2012-2015 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 #include <addrman.h>
7 
8 #include <hash.h>
9 #include <serialize.h>
10 #include <streams.h>
11 
12 int CAddrInfo::GetTriedBucket(const uint256& nKey) const
13 {
14  uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) << nKey << GetKey()).GetHash().GetCheapHash();
15  uint64_t hash2 = (CHashWriter(SER_GETHASH, 0) << nKey << GetGroup() << (hash1 % ADDRMAN_TRIED_BUCKETS_PER_GROUP)).GetHash().GetCheapHash();
16  return hash2 % ADDRMAN_TRIED_BUCKET_COUNT;
17 }
18 
19 int CAddrInfo::GetNewBucket(const uint256& nKey, const CNetAddr& src) const
20 {
21  std::vector<unsigned char> vchSourceGroupKey = src.GetGroup();
22  uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) << nKey << GetGroup() << vchSourceGroupKey).GetHash().GetCheapHash();
23  uint64_t hash2 = (CHashWriter(SER_GETHASH, 0) << nKey << vchSourceGroupKey << (hash1 % ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP)).GetHash().GetCheapHash();
24  return hash2 % ADDRMAN_NEW_BUCKET_COUNT;
25 }
26 
27 int CAddrInfo::GetBucketPosition(const uint256 &nKey, bool fNew, int nBucket) const
28 {
29  uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) << nKey << (fNew ? 'N' : 'K') << nBucket << GetKey()).GetHash().GetCheapHash();
30  return hash1 % ADDRMAN_BUCKET_SIZE;
31 }
32 
33 bool CAddrInfo::IsTerrible(int64_t nNow) const
34 {
35  if (nLastTry && nLastTry >= nNow - 60) // never remove things tried in the last minute
36  return false;
37 
38  if (nTime > nNow + 10 * 60) // came in a flying DeLorean
39  return true;
40 
41  if (nTime == 0 || nNow - nTime > ADDRMAN_HORIZON_DAYS * 24 * 60 * 60) // not seen in recent history
42  return true;
43 
44  if (nLastSuccess == 0 && nAttempts >= ADDRMAN_RETRIES) // tried N times and never a success
45  return true;
46 
47  if (nNow - nLastSuccess > ADDRMAN_MIN_FAIL_DAYS * 24 * 60 * 60 && nAttempts >= ADDRMAN_MAX_FAILURES) // N successive failures in the last week
48  return true;
49 
50  return false;
51 }
52 
53 double CAddrInfo::GetChance(int64_t nNow) const
54 {
55  double fChance = 1.0;
56  int64_t nSinceLastTry = std::max<int64_t>(nNow - nLastTry, 0);
57 
58  // deprioritize very recent attempts away
59  if (nSinceLastTry < 60 * 10)
60  fChance *= 0.01;
61 
62  // deprioritize 66% after each failed attempt, but at most 1/28th to avoid the search taking forever or overly penalizing outages.
63  fChance *= pow(0.66, std::min(nAttempts, 8));
64 
65  return fChance;
66 }
67 
68 CAddrInfo* CAddrMan::Find(const CService& addr, int* pnId)
69 {
70  CService addr2 = addr;
71  if (!discriminatePorts) {
72  addr2.SetPort(0);
73  }
74 
75  std::map<CService, int>::iterator it = mapAddr.find(addr2);
76  if (it == mapAddr.end())
77  return nullptr;
78  if (pnId)
79  *pnId = (*it).second;
80  std::map<int, CAddrInfo>::iterator it2 = mapInfo.find((*it).second);
81  if (it2 != mapInfo.end())
82  return &(*it2).second;
83  return nullptr;
84 }
85 
86 CAddrInfo* CAddrMan::Create(const CAddress& addr, const CNetAddr& addrSource, int* pnId)
87 {
88  CService addr2 = addr;
89  if (!discriminatePorts) {
90  addr2.SetPort(0);
91  }
92 
93  int nId = nIdCount++;
94  mapInfo[nId] = CAddrInfo(addr, addrSource);
95  mapAddr[addr2] = nId;
96  mapInfo[nId].nRandomPos = vRandom.size();
97  vRandom.push_back(nId);
98  if (pnId)
99  *pnId = nId;
100  return &mapInfo[nId];
101 }
102 
103 void CAddrMan::SwapRandom(unsigned int nRndPos1, unsigned int nRndPos2)
104 {
105  if (nRndPos1 == nRndPos2)
106  return;
107 
108  assert(nRndPos1 < vRandom.size() && nRndPos2 < vRandom.size());
109 
110  int nId1 = vRandom[nRndPos1];
111  int nId2 = vRandom[nRndPos2];
112 
113  assert(mapInfo.count(nId1) == 1);
114  assert(mapInfo.count(nId2) == 1);
115 
116  mapInfo[nId1].nRandomPos = nRndPos2;
117  mapInfo[nId2].nRandomPos = nRndPos1;
118 
119  vRandom[nRndPos1] = nId2;
120  vRandom[nRndPos2] = nId1;
121 }
122 
123 void CAddrMan::Delete(int nId)
124 {
125  assert(mapInfo.count(nId) != 0);
126  CAddrInfo& info = mapInfo[nId];
127  assert(!info.fInTried);
128  assert(info.nRefCount == 0);
129 
130  CService addr = info;
131  if (!discriminatePorts) {
132  addr.SetPort(0);
133  }
134 
135  SwapRandom(info.nRandomPos, vRandom.size() - 1);
136  vRandom.pop_back();
137  mapAddr.erase(addr);
138  mapInfo.erase(nId);
139  nNew--;
140 }
141 
142 void CAddrMan::ClearNew(int nUBucket, int nUBucketPos)
143 {
144  // if there is an entry in the specified bucket, delete it.
145  if (vvNew[nUBucket][nUBucketPos] != -1) {
146  int nIdDelete = vvNew[nUBucket][nUBucketPos];
147  CAddrInfo& infoDelete = mapInfo[nIdDelete];
148  assert(infoDelete.nRefCount > 0);
149  infoDelete.nRefCount--;
150  vvNew[nUBucket][nUBucketPos] = -1;
151  if (infoDelete.nRefCount == 0) {
152  Delete(nIdDelete);
153  }
154  }
155 }
156 
157 void CAddrMan::MakeTried(CAddrInfo& info, int nId)
158 {
159  // remove the entry from all new buckets
160  for (int bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) {
161  int pos = info.GetBucketPosition(nKey, true, bucket);
162  if (vvNew[bucket][pos] == nId) {
163  vvNew[bucket][pos] = -1;
164  info.nRefCount--;
165  }
166  }
167  nNew--;
168 
169  assert(info.nRefCount == 0);
170 
171  // which tried bucket to move the entry to
172  int nKBucket = info.GetTriedBucket(nKey);
173  int nKBucketPos = info.GetBucketPosition(nKey, false, nKBucket);
174 
175  // first make space to add it (the existing tried entry there is moved to new, deleting whatever is there).
176  if (vvTried[nKBucket][nKBucketPos] != -1) {
177  // find an item to evict
178  int nIdEvict = vvTried[nKBucket][nKBucketPos];
179  assert(mapInfo.count(nIdEvict) == 1);
180  CAddrInfo& infoOld = mapInfo[nIdEvict];
181 
182  // Remove the to-be-evicted item from the tried set.
183  infoOld.fInTried = false;
184  vvTried[nKBucket][nKBucketPos] = -1;
185  nTried--;
186 
187  // find which new bucket it belongs to
188  int nUBucket = infoOld.GetNewBucket(nKey);
189  int nUBucketPos = infoOld.GetBucketPosition(nKey, true, nUBucket);
190  ClearNew(nUBucket, nUBucketPos);
191  assert(vvNew[nUBucket][nUBucketPos] == -1);
192 
193  // Enter it into the new set again.
194  infoOld.nRefCount = 1;
195  vvNew[nUBucket][nUBucketPos] = nIdEvict;
196  nNew++;
197  }
198  assert(vvTried[nKBucket][nKBucketPos] == -1);
199 
200  vvTried[nKBucket][nKBucketPos] = nId;
201  nTried++;
202  info.fInTried = true;
203 }
204 
205 void CAddrMan::Good_(const CService& addr, int64_t nTime)
206 {
207  int nId;
208 
209  nLastGood = nTime;
210 
211  CAddrInfo* pinfo = Find(addr, &nId);
212 
213  // if not found, bail out
214  if (!pinfo)
215  return;
216 
217  CAddrInfo& info = *pinfo;
218 
219  // check whether we are talking about the exact same CService (including same port)
220  if (info != addr)
221  return;
222 
223  // update info
224  info.nLastSuccess = nTime;
225  info.nLastTry = nTime;
226  info.nAttempts = 0;
227  // nTime is not updated here, to avoid leaking information about
228  // currently-connected peers.
229 
230  // if it is already in the tried set, don't do anything else
231  if (info.fInTried)
232  return;
233 
234  // find a bucket it is in now
236  int nUBucket = -1;
237  for (unsigned int n = 0; n < ADDRMAN_NEW_BUCKET_COUNT; n++) {
238  int nB = (n + nRnd) % ADDRMAN_NEW_BUCKET_COUNT;
239  int nBpos = info.GetBucketPosition(nKey, true, nB);
240  if (vvNew[nB][nBpos] == nId) {
241  nUBucket = nB;
242  break;
243  }
244  }
245 
246  // if no bucket is found, something bad happened;
247  // TODO: maybe re-add the node, but for now, just bail out
248  if (nUBucket == -1)
249  return;
250 
251  if (fLogIPs) {
252  LogPrint(BCLog::ADDRMAN, "Moving %s to tried\n", addr.ToString());
253  }
254 
255  // move nId to the tried tables
256  MakeTried(info, nId);
257 }
258 
259 bool CAddrMan::Add_(const CAddress& addr, const CNetAddr& source, int64_t nTimePenalty)
260 {
261  if (!addr.IsRoutable())
262  return false;
263 
264  bool fNew = false;
265  int nId;
266  CAddrInfo* pinfo = Find(addr, &nId);
267 
268  // Do not set a penalty for a source's self-announcement
269  if (addr == source) {
270  nTimePenalty = 0;
271  }
272 
273  if (pinfo) {
274  // periodically update nTime
275  bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
276  int64_t nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
277  if (addr.nTime && (!pinfo->nTime || pinfo->nTime < addr.nTime - nUpdateInterval - nTimePenalty))
278  pinfo->nTime = std::max((int64_t)0, addr.nTime - nTimePenalty);
279 
280  // add services
281  pinfo->nServices = ServiceFlags(pinfo->nServices | addr.nServices);
282 
283  // do not update if no new information is present
284  if (!addr.nTime || (pinfo->nTime && addr.nTime <= pinfo->nTime))
285  return false;
286 
287  // do not update if the entry was already in the "tried" table
288  if (pinfo->fInTried)
289  return false;
290 
291  // do not update if the max reference count is reached
293  return false;
294 
295  // stochastic test: previous nRefCount == N: 2^N times harder to increase it
296  int nFactor = 1;
297  for (int n = 0; n < pinfo->nRefCount; n++)
298  nFactor *= 2;
299  if (nFactor > 1 && (RandomInt(nFactor) != 0))
300  return false;
301  } else {
302  pinfo = Create(addr, source, &nId);
303  pinfo->nTime = std::max((int64_t)0, (int64_t)pinfo->nTime - nTimePenalty);
304  nNew++;
305  fNew = true;
306  }
307 
308  int nUBucket = pinfo->GetNewBucket(nKey, source);
309  int nUBucketPos = pinfo->GetBucketPosition(nKey, true, nUBucket);
310  if (vvNew[nUBucket][nUBucketPos] != nId) {
311  bool fInsert = vvNew[nUBucket][nUBucketPos] == -1;
312  if (!fInsert) {
313  CAddrInfo& infoExisting = mapInfo[vvNew[nUBucket][nUBucketPos]];
314  if (infoExisting.IsTerrible() || (infoExisting.nRefCount > 1 && pinfo->nRefCount == 0)) {
315  // Overwrite the existing new table entry.
316  fInsert = true;
317  }
318  }
319  if (fInsert) {
320  ClearNew(nUBucket, nUBucketPos);
321  pinfo->nRefCount++;
322  vvNew[nUBucket][nUBucketPos] = nId;
323  } else {
324  if (pinfo->nRefCount == 0) {
325  Delete(nId);
326  }
327  }
328  }
329  return fNew;
330 }
331 
332 void CAddrMan::Attempt_(const CService& addr, bool fCountFailure, int64_t nTime)
333 {
334  CAddrInfo* pinfo = Find(addr);
335 
336  // if not found, bail out
337  if (!pinfo)
338  return;
339 
340  CAddrInfo& info = *pinfo;
341 
342  // check whether we are talking about the exact same CService (including same port)
343  if (info != addr)
344  return;
345 
346  // update info
347  info.nLastTry = nTime;
348  if (fCountFailure && info.nLastCountAttempt < nLastGood) {
349  info.nLastCountAttempt = nTime;
350  info.nAttempts++;
351  }
352 }
353 
355 {
356  if (size() == 0)
357  return CAddrInfo();
358 
359  if (newOnly && nNew == 0)
360  return CAddrInfo();
361 
362  // Use a 50% chance for choosing between tried and new table entries.
363  if (!newOnly &&
364  (nTried > 0 && (nNew == 0 || RandomInt(2) == 0))) {
365  // use a tried node
366  double fChanceFactor = 1.0;
367  while (1) {
368  int nKBucket = RandomInt(ADDRMAN_TRIED_BUCKET_COUNT);
369  int nKBucketPos = RandomInt(ADDRMAN_BUCKET_SIZE);
370  while (vvTried[nKBucket][nKBucketPos] == -1) {
372  nKBucketPos = (nKBucketPos + insecure_rand.randbits(ADDRMAN_BUCKET_SIZE_LOG2)) % ADDRMAN_BUCKET_SIZE;
373  }
374  int nId = vvTried[nKBucket][nKBucketPos];
375  assert(mapInfo.count(nId) == 1);
376  CAddrInfo& info = mapInfo[nId];
377  if (RandomInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30))
378  return info;
379  fChanceFactor *= 1.2;
380  }
381  } else {
382  // use a new node
383  double fChanceFactor = 1.0;
384  while (1) {
385  int nUBucket = RandomInt(ADDRMAN_NEW_BUCKET_COUNT);
386  int nUBucketPos = RandomInt(ADDRMAN_BUCKET_SIZE);
387  while (vvNew[nUBucket][nUBucketPos] == -1) {
389  nUBucketPos = (nUBucketPos + insecure_rand.randbits(ADDRMAN_BUCKET_SIZE_LOG2)) % ADDRMAN_BUCKET_SIZE;
390  }
391  int nId = vvNew[nUBucket][nUBucketPos];
392  assert(mapInfo.count(nId) == 1);
393  CAddrInfo& info = mapInfo[nId];
394  if (RandomInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30))
395  return info;
396  fChanceFactor *= 1.2;
397  }
398  }
399 }
400 
401 #ifdef DEBUG_ADDRMAN
402 int CAddrMan::Check_()
403 {
404  std::set<int> setTried;
405  std::map<int, int> mapNew;
406 
407  if (vRandom.size() != (size_t)(nTried + nNew))
408  return -7;
409 
410  for (const auto& entry : mapInfo) {
411  int n = entry.first;
412  const CAddrInfo& info = entry.second;
413  if (info.fInTried) {
414  if (!info.nLastSuccess)
415  return -1;
416  if (info.nRefCount)
417  return -2;
418  setTried.insert(n);
419  } else {
420  if (info.nRefCount < 0 || info.nRefCount > ADDRMAN_NEW_BUCKETS_PER_ADDRESS)
421  return -3;
422  if (!info.nRefCount)
423  return -4;
424  mapNew[n] = info.nRefCount;
425  }
426  if (mapAddr[info] != n)
427  return -5;
428  if (info.nRandomPos < 0 || (size_t)info.nRandomPos >= vRandom.size() || vRandom[info.nRandomPos] != n)
429  return -14;
430  if (info.nLastTry < 0)
431  return -6;
432  if (info.nLastSuccess < 0)
433  return -8;
434  }
435 
436  if (setTried.size() != (size_t)nTried)
437  return -9;
438  if (mapNew.size() != (size_t)nNew)
439  return -10;
440 
441  for (int n = 0; n < ADDRMAN_TRIED_BUCKET_COUNT; n++) {
442  for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
443  if (vvTried[n][i] != -1) {
444  if (!setTried.count(vvTried[n][i]))
445  return -11;
446  if (mapInfo[vvTried[n][i]].GetTriedBucket(nKey) != n)
447  return -17;
448  if (mapInfo[vvTried[n][i]].GetBucketPosition(nKey, false, n) != i)
449  return -18;
450  setTried.erase(vvTried[n][i]);
451  }
452  }
453  }
454 
455  for (int n = 0; n < ADDRMAN_NEW_BUCKET_COUNT; n++) {
456  for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
457  if (vvNew[n][i] != -1) {
458  if (!mapNew.count(vvNew[n][i]))
459  return -12;
460  if (mapInfo[vvNew[n][i]].GetBucketPosition(nKey, true, n) != i)
461  return -19;
462  if (--mapNew[vvNew[n][i]] == 0)
463  mapNew.erase(vvNew[n][i]);
464  }
465  }
466  }
467 
468  if (setTried.size())
469  return -13;
470  if (mapNew.size())
471  return -15;
472  if (nKey.IsNull())
473  return -16;
474 
475  return 0;
476 }
477 #endif
478 
479 void CAddrMan::GetAddr_(std::vector<CAddress>& vAddr)
480 {
481  unsigned int nNodes = ADDRMAN_GETADDR_MAX_PCT * vRandom.size() / 100;
482  if (nNodes > ADDRMAN_GETADDR_MAX)
483  nNodes = ADDRMAN_GETADDR_MAX;
484 
485  // gather a list of random nodes, skipping those of low quality
486  for (unsigned int n = 0; n < vRandom.size(); n++) {
487  if (vAddr.size() >= nNodes)
488  break;
489 
490  int nRndPos = RandomInt(vRandom.size() - n) + n;
491  SwapRandom(n, nRndPos);
492  assert(mapInfo.count(vRandom[n]) == 1);
493 
494  const CAddrInfo& ai = mapInfo[vRandom[n]];
495  if (!ai.IsTerrible())
496  vAddr.push_back(ai);
497  }
498 }
499 
500 void CAddrMan::Connected_(const CService& addr, int64_t nTime)
501 {
502  CAddrInfo* pinfo = Find(addr);
503 
504  // if not found, bail out
505  if (!pinfo)
506  return;
507 
508  CAddrInfo& info = *pinfo;
509 
510  // check whether we are talking about the exact same CService (including same port)
511  if (info != addr)
512  return;
513 
514  // update info
515  int64_t nUpdateInterval = 20 * 60;
516  if (nTime - info.nTime > nUpdateInterval)
517  info.nTime = nTime;
518 }
519 
520 void CAddrMan::SetServices_(const CService& addr, ServiceFlags nServices)
521 {
522  CAddrInfo* pinfo = Find(addr);
523 
524  // if not found, bail out
525  if (!pinfo)
526  return;
527 
528  CAddrInfo& info = *pinfo;
529 
530  // check whether we are talking about the exact same CService (including same port)
531  if (info != addr)
532  return;
533 
534  // update info
535  info.nServices = nServices;
536 }
537 
539 {
540  CAddrInfo* pinfo = Find(addr);
541 
542  // if not found, bail out
543  if (!pinfo)
544  return CAddrInfo();
545 
546  CAddrInfo& info = *pinfo;
547 
548  // check whether we are talking about the exact same CService (including same port)
549  if (info != addr)
550  return CAddrInfo();
551 
552  return *pinfo;
553 }
554 
555 int CAddrMan::RandomInt(int nMax){
556  return GetRandInt(nMax);
557 }
int nRefCount
reference count in new sets (memory only)
Definition: addrman.h:46
void Attempt_(const CService &addr, bool fCountFailure, int64_t nTime)
Mark an entry as attempted to connect.
Definition: addrman.cpp:332
uint64_t randbits(int bits)
Generate a random (bits)-bit integer.
Definition: random.h:92
ServiceFlags
nServices flags
Definition: protocol.h:280
std::string ToString(bool fUseGetnameinfo=true) const
Definition: netaddress.cpp:581
CAddrInfo * Find(const CService &addr, int *pnId=nullptr)
Find an entry.
Definition: addrman.cpp:68
int GetRandInt(int nMax)
Definition: random.cpp:379
#define ADDRMAN_TRIED_BUCKET_COUNT_LOG2
Stochastic address manager.
Definition: addrman.h:139
CAddrInfo Select_(bool newOnly)
Select an address to connect to, if newOnly is set to true, only the new table is selected from...
Definition: addrman.cpp:354
#define ADDRMAN_TRIED_BUCKETS_PER_GROUP
over how many buckets entries with tried addresses from a single group (/16 for IPv4) are spread ...
Definition: addrman.h:148
int vvNew[ADDRMAN_NEW_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE]
list of "new" buckets
Definition: addrman.h:210
void SetServices_(const CService &addr, ServiceFlags nServices)
Update an entry&#39;s service bits.
Definition: addrman.cpp:520
#define ADDRMAN_MIN_FAIL_DAYS
... in at least this many days
Definition: addrman.h:166
int64_t nLastGood
last time Good was called (memory only)
Definition: addrman.h:213
int nAttempts
connection attempts since last successful attempt
Definition: addrman.h:43
void SetPort(unsigned short portIn)
Definition: netaddress.cpp:586
#define ADDRMAN_NEW_BUCKET_COUNT_LOG2
total number of buckets for new addresses
Definition: addrman.h:142
virtual int RandomInt(int nMax)
Wraps GetRandInt to allow tests to override RandomInt and make it determinismistic.
Definition: addrman.cpp:555
int nRandomPos
position in vRandom
Definition: addrman.h:52
#define ADDRMAN_TRIED_BUCKET_COUNT
Convenience.
Definition: addrman.h:175
bool fInTried
in tried set? (memory only)
Definition: addrman.h:49
bool IsNull() const
Definition: uint256.h:33
std::vector< unsigned char > GetGroup() const
Definition: netaddress.cpp:319
Extended statistics about a CAddress.
Definition: addrman.h:24
std::vector< int > vRandom
randomly-ordered vector of all nIds
Definition: addrman.h:198
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
std::size_t size_t
Definition: bits.hpp:21
int GetTriedBucket(const uint256 &nKey) const
Calculate in which "tried" bucket this entry belongs.
Definition: addrman.cpp:12
#define ADDRMAN_BUCKET_SIZE_LOG2
maximum allowed number of entries in buckets for new and tried addresses
Definition: addrman.h:145
#define ADDRMAN_RETRIES
after how many failed attempts we give up on a new node
Definition: addrman.h:160
FastRandomContext insecure_rand
Source of random numbers for randomization in inner loops.
Definition: addrman.h:223
void MakeTried(CAddrInfo &info, int nId)
Move an entry from the "new" table(s) to the "tried" table.
Definition: addrman.cpp:157
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:143
A CService with information about it as peer.
Definition: protocol.h:358
int nTried
Definition: addrman.h:201
std::vector< unsigned char > GetKey() const
Definition: netaddress.cpp:557
void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2)
Swap two elements in vRandom.
Definition: addrman.cpp:103
CAddrInfo GetAddressInfo_(const CService &addr)
Get address info for address.
Definition: addrman.cpp:538
#define ADDRMAN_BUCKET_SIZE
Definition: addrman.h:177
CAddrInfo * Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId=nullptr)
find an entry, creating it if necessary.
Definition: addrman.cpp:86
bool discriminatePorts
Definition: addrman.h:216
int nIdCount
last used nId
Definition: addrman.h:189
bool IsRoutable() const
Definition: netaddress.cpp:230
uint64_t GetHash() const
Definition: netaddress.cpp:392
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
#define LogPrint(category,...)
Definition: util.h:214
IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96))
Definition: netaddress.h:33
bool fLogIPs
Definition: util.cpp:115
#define ADDRMAN_GETADDR_MAX
the maximum number of nodes to return in a getaddr call
Definition: addrman.h:172
void Good_(const CService &addr, int64_t nTime)
Mark an entry "good", possibly moving it from "new" to "tried".
Definition: addrman.cpp:205
size_t size() const
Return the number of (unique) addresses in all tables.
Definition: addrman.h:498
256-bit opaque blob.
Definition: uint256.h:123
unsigned int nTime
Definition: protocol.h:390
ServiceFlags nServices
Definition: protocol.h:387
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
#define ADDRMAN_NEW_BUCKET_COUNT
Definition: addrman.h:176
int64_t GetAdjustedTime()
Definition: timedata.cpp:35
bool Add_(const CAddress &addr, const CNetAddr &source, int64_t nTimePenalty)
Add an entry to the "new" table.
Definition: addrman.cpp:259
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
void Connected_(const CService &addr, int64_t nTime)
Mark an entry as currently-connected-to.
Definition: addrman.cpp:500
int64_t nLastCountAttempt
last counted attempt (memory only)
Definition: addrman.h:33
void GetAddr_(std::vector< CAddress > &vAddr)
Select several addresses at once.
Definition: addrman.cpp:479
A writer stream (for serialization) that computes a 256-bit hash.
Definition: hash.h:184
std::map< int, CAddrInfo > mapInfo
table with information about all nIds
Definition: addrman.h:192
int vvTried[ADDRMAN_TRIED_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE]
list of "tried" buckets
Definition: addrman.h:204
uint256 nKey
secret key to randomize bucket select with
Definition: addrman.h:220
void Delete(int nId)
Delete an entry. It must not be in tried, and have refcount 0.
Definition: addrman.cpp:123
#define ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP
over how many buckets entries with new addresses originating from a single group are spread ...
Definition: addrman.h:151
int nNew
number of (unique) "new" entries
Definition: addrman.h:207
#define ADDRMAN_HORIZON_DAYS
how old addresses can maximally be
Definition: addrman.h:157
#define ADDRMAN_MAX_FAILURES
how many successive failures are allowed ...
Definition: addrman.h:163
int64_t nLastSuccess
last successful connection by us
Definition: addrman.h:40
std::map< CService, int > mapAddr
find an nId based on its network address
Definition: addrman.h:195
void ClearNew(int nUBucket, int nUBucketPos)
Clear a position in a "new" table. This is the only place where entries are actually deleted...
Definition: addrman.cpp:142
#define ADDRMAN_GETADDR_MAX_PCT
the maximum percentage of nodes to return in a getaddr call
Definition: addrman.h:169
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
Released under the MIT license