21 std::vector<unsigned char> vchSourceGroupKey = src.
GetGroup();
38 if (
nTime > nNow + 10 * 60)
56 int64_t nSinceLastTry = std::max<int64_t>(nNow -
nLastTry, 0);
59 if (nSinceLastTry < 60 * 10)
63 fChance *= pow(0.66, std::min(
nAttempts, 8));
70 std::map<CNetAddr, int>::iterator it =
mapAddr.find(addr);
75 std::map<int, CAddrInfo>::iterator it2 =
mapInfo.find((*it).second);
77 return &(*it2).second;
95 if (nRndPos1 == nRndPos2)
103 assert(
mapInfo.count(nId1) == 1);
104 assert(
mapInfo.count(nId2) == 1);
106 mapInfo[nId1].nRandomPos = nRndPos2;
107 mapInfo[nId2].nRandomPos = nRndPos1;
115 assert(
mapInfo.count(nId) != 0);
130 if (
vvNew[nUBucket][nUBucketPos] != -1) {
131 int nIdDelete =
vvNew[nUBucket][nUBucketPos];
135 vvNew[nUBucket][nUBucketPos] = -1;
147 if (
vvNew[bucket][pos] == nId) {
148 vvNew[bucket][pos] = -1;
161 if (
vvTried[nKBucket][nKBucketPos] != -1) {
163 int nIdEvict =
vvTried[nKBucket][nKBucketPos];
164 assert(
mapInfo.count(nIdEvict) == 1);
169 vvTried[nKBucket][nKBucketPos] = -1;
176 assert(
vvNew[nUBucket][nUBucketPos] == -1);
180 vvNew[nUBucket][nUBucketPos] = nIdEvict;
183 assert(
vvTried[nKBucket][nKBucketPos] == -1);
185 vvTried[nKBucket][nKBucketPos] = nId;
225 if (
vvNew[nB][nBpos] == nId) {
259 int64_t nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
260 if (addr.
nTime && (!pinfo->
nTime || pinfo->
nTime < addr.
nTime - nUpdateInterval - nTimePenalty))
261 pinfo->
nTime = std::max((int64_t)0, addr.
nTime - nTimePenalty);
280 for (
int n = 0; n < pinfo->
nRefCount; n++)
282 if (nFactor > 1 && (
RandomInt(nFactor) != 0))
286 pinfo->
nTime = std::max((int64_t)0, (int64_t)pinfo->
nTime - nTimePenalty);
293 if (
vvNew[nUBucket][nUBucketPos] != nId) {
294 bool fInsert =
vvNew[nUBucket][nUBucketPos] == -1;
305 vvNew[nUBucket][nUBucketPos] = nId;
342 if (newOnly &&
nNew == 0)
349 double fChanceFactor = 1.0;
353 while (
vvTried[nKBucket][nKBucketPos] == -1) {
357 int nId =
vvTried[nKBucket][nKBucketPos];
358 assert(
mapInfo.count(nId) == 1);
362 fChanceFactor *= 1.2;
366 double fChanceFactor = 1.0;
370 while (
vvNew[nUBucket][nUBucketPos] == -1) {
374 int nId =
vvNew[nUBucket][nUBucketPos];
375 assert(
mapInfo.count(nId) == 1);
379 fChanceFactor *= 1.2;
385 int CAddrMan::Check_()
387 std::set<int> setTried;
388 std::map<int, int> mapNew;
393 for (std::map<int, CAddrInfo>::iterator it =
mapInfo.begin(); it !=
mapInfo.end(); it++) {
419 if (setTried.size() !=
nTried)
421 if (mapNew.size() !=
nNew)
427 if (!setTried.count(
vvTried[n][i]))
440 if (
vvNew[n][i] != -1) {
441 if (!mapNew.count(
vvNew[n][i]))
445 if (--mapNew[
vvNew[n][i]] == 0)
446 mapNew.erase(
vvNew[n][i]);
469 for (
unsigned int n = 0; n <
vRandom.size(); n++) {
470 if (vAddr.size() >= nNodes)
498 int64_t nUpdateInterval = 20 * 60;
499 if (nTime - info.
nTime > nUpdateInterval)
#define ADDRMAN_GETADDR_MAX_PCT
the maximum percentage of nodes to return in a getaddr call
#define ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP
over how many buckets entries with new addresses originating from a single group are spread
#define ADDRMAN_NEW_BUCKETS_PER_ADDRESS
in how many buckets for entries with new addresses a single address may occur
#define ADDRMAN_MAX_FAILURES
how many successive failures are allowed ...
#define ADDRMAN_BUCKET_SIZE
maximum allowed number of entries in buckets for new and tried addresses
#define ADDRMAN_NEW_BUCKET_COUNT
total number of buckets for new addresses
#define ADDRMAN_RETRIES
after how many failed attempts we give up on a new node
#define ADDRMAN_MIN_FAIL_DAYS
... in at least this many days
#define ADDRMAN_HORIZON_DAYS
how old addresses can maximally be
#define ADDRMAN_TRIED_BUCKETS_PER_GROUP
over how many buckets entries with tried addresses from a single group (/16 for IPv4) are spread
#define ADDRMAN_TRIED_BUCKET_COUNT
Stochastic address manager.
#define ADDRMAN_GETADDR_MAX
the maximum number of nodes to return in a getaddr call
Extended statistics about a CAddress.
int GetTriedBucket(const uint256 &nKey) const
Calculate in which "tried" bucket this entry belongs.
int nAttempts
connection attempts since last successful attempt
int64_t nLastSuccess
last successful connection by us
int GetBucketPosition(const uint256 &nKey, bool fNew, int nBucket) const
Calculate in which position of a bucket to store this entry.
int64_t nLastCountAttempt
last counted attempt (memory only)
int64_t nLastTry
last try whatsoever by us (memory only)
bool IsTerrible(int64_t nNow=GetAdjustedTime()) const
Determine whether the statistics about this entry are bad enough so that it can just be deleted.
int nRandomPos
position in vRandom
bool fInTried
in tried set? (memory only)
int nRefCount
reference count in new sets (memory only)
int GetNewBucket(const uint256 &nKey, const CNetAddr &src) const
Calculate in which "new" bucket this entry belongs, given a certain source.
double GetChance(int64_t nNow=GetAdjustedTime()) const
Calculate the relative chance this entry should be given when selecting nodes to connect to.
int64_t nLastGood
last time Good was called (memory only)
std::map< int, CAddrInfo > mapInfo
table with information about all nIds
void Connected_(const CService &addr, int64_t nTime)
Mark an entry as currently-connected-to.
FastRandomContext insecure_rand
Source of random numbers for randomization in inner loops.
size_t size() const
Return the number of (unique) addresses in all tables.
CAddrInfo Select_(bool newOnly)
Select an address to connect to, if newOnly is set to true, only the new table is selected from.
void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2)
Swap two elements in vRandom.
void Good_(const CService &addr, int64_t nTime)
Mark an entry "good", possibly moving it from "new" to "tried".
int vvTried[ADDRMAN_TRIED_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE]
list of "tried" buckets
int nNew
number of (unique) "new" entries
virtual int RandomInt(int nMax)
Wraps GetRandInt to allow tests to override RandomInt and make it determinismistic.
std::map< CNetAddr, int > mapAddr
find an nId based on its network address
int nIdCount
last used nId
void MakeTried(CAddrInfo &info, int nId)
Move an entry from the "new" table(s) to the "tried" table.
void Attempt_(const CService &addr, bool fCountFailure, int64_t nTime)
Mark an entry as attempted to connect.
bool Add_(const CAddress &addr, const CNetAddr &source, int64_t nTimePenalty)
Add an entry to the "new" table.
CAddrInfo * Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId=NULL)
find an entry, creating it if necessary.
void ClearNew(int nUBucket, int nUBucketPos)
Clear a position in a "new" table. This is the only place where entries are actually deleted.
CAddrInfo * Find(const CNetAddr &addr, int *pnId=NULL)
Find an entry.
uint256 nKey
secret key to randomize bucket select with
void Delete(int nId)
Delete an entry. It must not be in tried, and have refcount 0.
std::vector< int > vRandom
randomly-ordered vector of all nIds
int vvNew[ADDRMAN_NEW_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE]
list of "new" buckets
void SetServices_(const CService &addr, ServiceFlags nServices)
Update an entry's service bits.
void GetAddr_(std::vector< CAddress > &vAddr)
Select several addresses at once.
A CService with information about it as peer.
A writer stream (for serialization) that computes a 256-bit hash.
IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96))
std::vector< unsigned char > GetGroup() const
A combination of a network address (CNetAddr) and a (TCP) port.
std::string ToString() const
std::vector< unsigned char > GetKey() const
ServiceFlags
nServices flags
int64_t GetAdjustedTime()
#define LogPrint(category,...)