20 std::vector<unsigned char> vchSourceGroupKey = src.
GetGroup();
37 if (
nTime > nNow + 10 * 60)
56 int64_t nSinceLastSeen = nNow -
nTime;
57 int64_t nSinceLastTry = nNow -
nLastTry;
59 if (nSinceLastSeen < 0)
61 if (nSinceLastTry < 0)
65 if (nSinceLastTry < 60 * 10)
69 fChance *= pow(0.66, std::min(
nAttempts, 8));
76 std::map<CNetAddr, int>::iterator it =
mapAddr.find(addr);
81 std::map<int, CAddrInfo>::iterator it2 =
mapInfo.find((*it).second);
83 return &(*it2).second;
101 if (nRndPos1 == nRndPos2)
109 assert(
mapInfo.count(nId1) == 1);
110 assert(
mapInfo.count(nId2) == 1);
112 mapInfo[nId1].nRandomPos = nRndPos2;
113 mapInfo[nId2].nRandomPos = nRndPos1;
121 assert(
mapInfo.count(nId) != 0);
123 assert(!info.fInTried);
124 assert(info.nRefCount == 0);
136 if (
vvNew[nUBucket][nUBucketPos] != -1) {
137 int nIdDelete =
vvNew[nUBucket][nUBucketPos];
141 vvNew[nUBucket][nUBucketPos] = -1;
153 if (
vvNew[bucket][pos] == nId) {
154 vvNew[bucket][pos] = -1;
167 if (
vvTried[nKBucket][nKBucketPos] != -1) {
169 int nIdEvict =
vvTried[nKBucket][nKBucketPos];
170 assert(
mapInfo.count(nIdEvict) == 1);
174 infoOld.fInTried =
false;
175 vvTried[nKBucket][nKBucketPos] = -1;
179 int nUBucket = infoOld.GetNewBucket(
nKey);
180 int nUBucketPos = infoOld.GetBucketPosition(
nKey,
true, nUBucket);
182 assert(
vvNew[nUBucket][nUBucketPos] == -1);
185 infoOld.nRefCount = 1;
186 vvNew[nUBucket][nUBucketPos] = nIdEvict;
189 assert(
vvTried[nKBucket][nKBucketPos] == -1);
191 vvTried[nKBucket][nKBucketPos] = nId;
228 if (
vvNew[nB][nBpos] == nId) {
257 int64_t nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
258 if (addr.
nTime && (!pinfo->
nTime || pinfo->
nTime < addr.
nTime - nUpdateInterval - nTimePenalty))
259 pinfo->
nTime = std::max((int64_t)0, addr.
nTime - nTimePenalty);
280 if (nFactor > 1 && (
RandomInt(nFactor) != 0))
284 pinfo->
nTime = std::max((int64_t)0, (int64_t)pinfo->
nTime - nTimePenalty);
291 if (
vvNew[nUBucket][nUBucketPos] != nId) {
292 bool fInsert =
vvNew[nUBucket][nUBucketPos] == -1;
303 vvNew[nUBucket][nUBucketPos] = nId;
337 if (newOnly &&
nNew == 0)
344 double fChanceFactor = 1.0;
348 while (
vvTried[nKBucket][nKBucketPos] == -1) {
352 int nId =
vvTried[nKBucket][nKBucketPos];
353 assert(
mapInfo.count(nId) == 1);
355 if (
RandomInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30))
357 fChanceFactor *= 1.2;
361 double fChanceFactor = 1.0;
365 while (
vvNew[nUBucket][nUBucketPos] == -1) {
369 int nId =
vvNew[nUBucket][nUBucketPos];
370 assert(
mapInfo.count(nId) == 1);
372 if (
RandomInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30))
374 fChanceFactor *= 1.2;
380 int CAddrMan::Check_()
382 std::set<int> setTried;
383 std::map<int, int> mapNew;
388 for (std::map<int, CAddrInfo>::iterator it =
mapInfo.begin(); it !=
mapInfo.end(); it++) {
414 if (setTried.size() !=
nTried)
416 if (mapNew.size() !=
nNew)
436 if (!mapNew.count(
vvNew[
n][i]))
440 if (--mapNew[
vvNew[
n][i]] == 0)
441 mapNew.erase(
vvNew[
n][i]);
464 for (
unsigned int n = 0;
n <
vRandom.size();
n++) {
465 if (vAddr.size() >= nNodes)
473 if (!ai.IsTerrible())
493 int64_t nUpdateInterval = 20 * 60;
494 if (nTime - info.
nTime > nUpdateInterval)
int nNew
number of (unique) "new" entries
uint256 nKey
secret key to randomize bucket select with
std::vector< unsigned char > GetKey() const
CAddrInfo Select_(bool newOnly)
Select an address to connect to, if newOnly is set to true, only the new table is selected from...
#define ADDRMAN_TRIED_BUCKETS_PER_GROUP
over how many buckets entries with tried addresses from a single group (/16 for IPv4) are spread ...
int nIdCount
last used nId
void Connected_(const CService &addr, int64_t nTime)
Mark an entry as currently-connected-to.
#define ADDRMAN_MIN_FAIL_DAYS
... in at least this many days
size_t size() const
Return the number of (unique) addresses in all tables.
void Attempt_(const CService &addr, int64_t nTime)
Mark an entry as attempted to connect.
std::map< int, CAddrInfo > mapInfo
table with information about all nIds
void ClearNew(int nUBucket, int nUBucketPos)
Clear a position in a "new" table. This is the only place where entries are actually deleted...
std::string ToString(bool fUseGetnameinfo=true) const
void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2)
Swap two elements in vRandom.
std::vector< unsigned char > GetGroup() const
#define ADDRMAN_TRIED_BUCKET_COUNT
total number of buckets for tried addresses
static uint32_t insecure_rand(void)
int nRandomPos
position in vRandom
bool IsTerrible(int64_t nNow=GetAdjustedTime()) const
Determine whether the statistics about this entry are bad enough so that it can just be deleted...
int64_t nLastTry
last try whatsoever by us (memory only)
void Good_(const CService &addr, int64_t nTime)
Mark an entry "good", possibly moving it from "new" to "tried".
bool fInTried
in tried set? (memory only)
#define ADDRMAN_RETRIES
after how many failed attempts we give up on a new node
std::map< CNetAddr, int > mapAddr
find an nId based on its network address
static int LogPrint(const char *category, const char *format)
int GetBucketPosition(const uint256 &nKey, bool fNew, int nBucket) const
Calculate in which position of a bucket to store this entry.
bool Add_(const CAddress &addr, const CNetAddr &source, int64_t nTimePenalty)
Add an entry to the "new" table.
void SetServices_(const CService &addr, ServiceFlags nServices)
Update an entry's service bits.
std::vector< int > vRandom
randomly-ordered vector of all nIds
#define ADDRMAN_BUCKET_SIZE
maximum allowed number of entries in buckets for new and tried addresses
int GetNewBucket(const uint256 &nKey, const CNetAddr &src) const
Calculate in which "new" bucket this entry belongs, given a certain source.
CAddrInfo * Find(const CNetAddr &addr, int *pnId=NULL)
Find an entry.
void Delete(int nId)
Delete an entry. It must not be in tried, and have refcount 0.
int vvTried[ADDRMAN_TRIED_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE]
list of "tried" buckets
#define ADDRMAN_GETADDR_MAX
the maximum number of nodes to return in a getaddr call
double GetChance(int64_t nNow=GetAdjustedTime()) const
Calculate the relative chance this entry should be given when selecting nodes to connect to...
virtual int RandomInt(int nMax)
Wraps GetRandInt to allow tests to override RandomInt and make it determinismistic.
void MakeTried(CAddrInfo &info, int nId)
Move an entry from the "new" table(s) to the "tried" table.
void GetAddr_(std::vector< CAddress > &vAddr)
Select several addresses at once.
#define ADDRMAN_NEW_BUCKET_COUNT
total number of buckets for new addresses
int64_t GetAdjustedTime()
int64_t nLastSuccess
last successful connection by us
int nRefCount
reference count in new sets (memory only)
#define ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP
over how many buckets entries with new addresses originating from a single group are spread ...
#define ADDRMAN_HORIZON_DAYS
how old addresses can maximally be
#define ADDRMAN_MAX_FAILURES
how many successive failures are allowed ...
int nAttempts
connection attempts since last successful attempt
CAddrInfo * Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId=NULL)
#define ADDRMAN_GETADDR_MAX_PCT
the maximum percentage of nodes to return in a getaddr call
#define ADDRMAN_NEW_BUCKETS_PER_ADDRESS
in how many buckets for entries with new addresses a single address may occur
int vvNew[ADDRMAN_NEW_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE]
list of "new" buckets
int GetTriedBucket(const uint256 &nKey) const
Calculate in which "tried" bucket this entry belongs.