7 #ifndef RAVEN_ADDRMAN_H 8 #define RAVEN_ADDRMAN_H 61 template <
typename Stream,
typename Operation>
73 nLastCountAttempt = 0;
139 #define ADDRMAN_TRIED_BUCKET_COUNT_LOG2 8 143 #define ADDRMAN_NEW_BUCKET_COUNT_LOG2 10 146 #define ADDRMAN_BUCKET_SIZE_LOG2 6 149 #define ADDRMAN_TRIED_BUCKETS_PER_GROUP 8 152 #define ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP 64 155 #define ADDRMAN_NEW_BUCKETS_PER_ADDRESS 8 158 #define ADDRMAN_HORIZON_DAYS 30 161 #define ADDRMAN_RETRIES 3 164 #define ADDRMAN_MAX_FAILURES 10 167 #define ADDRMAN_MIN_FAIL_DAYS 7 170 #define ADDRMAN_GETADDR_MAX_PCT 23 173 #define ADDRMAN_GETADDR_MAX 2500 176 #define ADDRMAN_TRIED_BUCKET_COUNT (1 << ADDRMAN_TRIED_BUCKET_COUNT_LOG2) 177 #define ADDRMAN_NEW_BUCKET_COUNT (1 << ADDRMAN_NEW_BUCKET_COUNT_LOG2) 178 #define ADDRMAN_BUCKET_SIZE (1 << ADDRMAN_BUCKET_SIZE_LOG2) 231 void SwapRandom(
unsigned int nRandomPos1,
unsigned int nRandomPos2);
234 void MakeTried(
CAddrInfo& info,
int nId);
237 void Delete(
int nId);
240 void ClearNew(
int nUBucket,
int nUBucketPos);
249 void Attempt_(
const CService &addr,
bool fCountFailure, int64_t
nTime);
255 virtual int RandomInt(
int nMax);
263 void GetAddr_(std::vector<CAddress> &vAddr);
301 template<
typename Stream>
306 unsigned char nVersion = 1;
308 s << ((
unsigned char)32);
315 std::map<int, int> mapUnkIds;
317 for (std::map<int, CAddrInfo>::const_iterator it = mapInfo.begin(); it != mapInfo.end(); it++) {
318 mapUnkIds[(*it).first] = nIds;
321 assert(nIds != nNew);
327 for (std::map<int, CAddrInfo>::const_iterator it = mapInfo.begin(); it != mapInfo.end(); it++) {
330 assert(nIds != nTried);
338 if (vvNew[bucket][i] != -1)
343 if (vvNew[bucket][i] != -1) {
344 int nIndex = mapUnkIds[vvNew[bucket][i]];
351 template<
typename Stream>
358 unsigned char nVersion;
360 unsigned char nKeySize;
362 if (nKeySize != 32)
throw std::ios_base::failure(
"Incorrect keysize in addrman deserialization");
369 nUBuckets ^= (1 << 30);
373 throw std::ios_base::failure(
"Corrupt CAddrMan serialization, nNew exceeds limit.");
377 throw std::ios_base::failure(
"Corrupt CAddrMan serialization, nTried exceeds limit.");
381 for (
int n = 0; n < nNew; n++) {
386 vRandom.push_back(n);
390 int nUBucket = info.GetNewBucket(nKey);
391 int nUBucketPos = info.GetBucketPosition(nKey,
true, nUBucket);
392 if (vvNew[nUBucket][nUBucketPos] == -1) {
393 vvNew[nUBucket][nUBucketPos] = n;
402 for (
int n = 0; n < nTried; n++) {
406 int nKBucketPos = info.GetBucketPosition(nKey,
false, nKBucket);
407 if (vvTried[nKBucket][nKBucketPos] == -1) {
408 info.nRandomPos = vRandom.size();
409 info.fInTried =
true;
410 vRandom.push_back(nIdCount);
411 mapInfo[nIdCount] = info;
412 mapAddr[info] = nIdCount;
413 vvTried[nKBucket][nKBucketPos] = nIdCount;
422 for (
int bucket = 0; bucket < nUBuckets; bucket++) {
425 for (
int n = 0; n < nSize; n++) {
428 if (nIndex >= 0 && nIndex < nNew) {
433 vvNew[bucket][nUBucketPos] = nIndex;
441 for (std::map<int, CAddrInfo>::const_iterator it = mapInfo.begin(); it != mapInfo.end(); ) {
442 if (it->second.fInTried ==
false && it->second.nRefCount == 0) {
443 std::map<int, CAddrInfo>::const_iterator itCopy = it++;
444 Delete(itCopy->first);
450 if (nLost + nLostUnk > 0) {
451 LogPrint(
BCLog::ADDRMAN,
"addrman lost %i new and %i tried addresses due to collisions\n", nLostUnk, nLost);
459 std::vector<int>().swap(vRandom);
463 vvNew[bucket][entry] = -1;
468 vvTried[bucket][entry] = -1;
494 return vRandom.size();
505 LogPrintf(
"ADDRMAN CONSISTENCY CHECK FAILED!!! err=%i\n", err);
516 fRet |= Add_(addr, source, nTimePenalty);
532 for (std::vector<CAddress>::const_iterator it = vAddr.begin(); it != vAddr.end(); it++)
533 nAdd += Add_(*it, source, nTimePenalty) ? 1 : 0;
555 Attempt_(addr, fCountFailure,
nTime);
568 addrRet = Select_(newOnly);
578 std::vector<CAddress> vAddr;
592 Connected_(addr,
nTime);
600 SetServices_(addr, nServices);
606 #endif // RAVEN_ADDRMAN_H int nRefCount
reference count in new sets (memory only)
ServiceFlags
nServices flags
CAddrInfo Select(bool newOnly=false)
Choose an address to connect to.
void Attempt(const CService &addr, bool fCountFailure, int64_t nTime=GetAdjustedTime())
Mark an entry as connection attempted to.
int64_t nLastGood
last time Good was called (memory only)
int nAttempts
connection attempts since last successful attempt
std::string ToString() const
int nRandomPos
position in vRandom
bool Add(const CAddress &addr, const CNetAddr &source, int64_t nTimePenalty=0)
Add a single address.
#define ADDRMAN_TRIED_BUCKET_COUNT
Convenience.
bool fInTried
in tried set? (memory only)
Stochastical (IP) address manager.
std::vector< CAddress > GetAddr()
Return a bunch of addresses, selected at random.
Extended statistics about a CAddress.
std::vector< int > vRandom
randomly-ordered vector of all nIds
int GetNewBucket(const uint256 &nKey, const CNetAddr &src) const
Calculate in which "new" bucket this entry belongs, given a certain source.
int GetTriedBucket(const uint256 &nKey) const
Calculate in which "tried" bucket this entry belongs.
FastRandomContext insecure_rand
Source of random numbers for randomization in inner loops.
void Unserialize(Stream &s)
A combination of a network address (CNetAddr) and a (TCP) port.
void Check()
Consistency check.
A CService with information about it as peer.
#define ADDRMAN_BUCKET_SIZE
int nIdCount
last used nId
std::map< CNetAddr, int > mapAddr
find an nId based on its network address
bool IsTerrible(int64_t nNow=GetAdjustedTime()) const
Determine whether the statistics about this entry are bad enough so that it can just be deleted...
#define LogPrint(category,...)
IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96))
size_t size() const
Return the number of (unique) addresses in all tables.
int GetBucketPosition(const uint256 &nKey, bool fNew, int nBucket) const
Calculate in which position of a bucket to store this entry.
CAddrInfo(const CAddress &addrIn, const CNetAddr &addrSource)
#define ADDRMAN_NEW_BUCKET_COUNT
int64_t GetAdjustedTime()
std::string ToStringIPPort() const
int GetNewBucket(const uint256 &nKey) const
Calculate in which "new" bucket this entry belongs, using its default source.
void SerializationOp(Stream &s, Operation ser_action)
double GetChance(int64_t nNow=GetAdjustedTime()) const
Calculate the relative chance this entry should be given when selecting nodes to connect to...
int64_t nLastCountAttempt
last counted attempt (memory only)
std::map< int, CAddrInfo > mapInfo
table with information about all nIds
bool Add(const std::vector< CAddress > &vAddr, const CNetAddr &source, int64_t nTimePenalty=0)
Add multiple addresses.
void SetServices(const CService &addr, ServiceFlags nServices)
uint256 nKey
secret key to randomize bucket select with
void Serialize(Stream &s) const
serialized format:
int nNew
number of (unique) "new" entries
void Connected(const CService &addr, int64_t nTime=GetAdjustedTime())
Mark an entry as currently-connected-to.
int64_t nLastSuccess
last successful connection by us
CCriticalSection cs
critical section to protect the inner data structures
Wrapped boost mutex: supports recursive locking, but no waiting TODO: We should move away from using ...
int64_t nLastTry
last try whatsoever by us (memory only)
#define ADDRMAN_NEW_BUCKETS_PER_ADDRESS
in how many buckets for entries with new addresses a single address may occur
CNetAddr source
where knowledge about this address first came from
void Good(const CService &addr, int64_t nTime=GetAdjustedTime())
Mark an entry as accessible.