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