5 #ifndef _ANONCOIN_ADDRMAN
6 #define _ANONCOIN_ADDRMAN 1
18 #include <openssl/rand.h>
125 #define ADDRMAN_TRIED_BUCKET_COUNT 64
128 #define ADDRMAN_TRIED_BUCKET_SIZE 64
131 #define ADDRMAN_NEW_BUCKET_COUNT 256
134 #define ADDRMAN_NEW_BUCKET_SIZE 64
137 #define ADDRMAN_TRIED_BUCKETS_PER_GROUP 4
140 #define ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP 32
143 #define ADDRMAN_NEW_BUCKETS_PER_ADDRESS 4
146 #define ADDRMAN_TRIED_ENTRIES_INSPECT_ON_EVICT 4
149 #define ADDRMAN_HORIZON_DAYS 30
152 #define ADDRMAN_RETRIES 3
155 #define ADDRMAN_MAX_FAILURES 10
158 #define ADDRMAN_MIN_FAIL_DAYS 7
161 #define ADDRMAN_GETADDR_MAX_PCT 23
164 #define ADDRMAN_GETADDR_MAX 2500
174 std::vector<unsigned char>
nKey;
210 void SwapRandom(
unsigned int nRandomPos1,
unsigned int nRandomPos2);
243 void GetAddr_(std::vector<CAddress> &vAddr);
274 unsigned char nVersion = 0;
285 std::map<int, int> mapUnkIds;
287 for (std::map<int, CAddrInfo>::iterator it = am->
mapInfo.begin(); it != am->
mapInfo.end(); it++)
289 if (nIds == nNew)
break;
290 mapUnkIds[(*it).first] = nIds;
299 for (std::map<int, CAddrInfo>::iterator it = am->
mapInfo.begin(); it != am->
mapInfo.end(); it++)
301 if (nIds == nTried)
break;
309 for (std::vector<std::set<int> >::iterator it = am->
vvNew.begin(); it != am->
vvNew.end(); it++)
311 const std::set<int> &vNew = (*it);
312 int nSize = vNew.size();
314 for (std::set<int>::iterator it2 = vNew.begin(); it2 != vNew.end(); it2++)
316 int nIndex = mapUnkIds[*it2];
329 for (
int n = 0; n < am->
nNew; n++)
336 if (nUBuckets != ADDRMAN_NEW_BUCKET_COUNT)
344 for (
int n = 0; n < am->
nTried; n++)
363 for (
int b = 0; b < nUBuckets; b++)
365 std::set<int> &vNew = am->
vvNew[b];
368 for (
int n = 0; n < nSize; n++)
387 RAND_bytes(&nKey[0], 32);
397 return vRandom.size();
408 LogPrintf(
"ADDRMAN CONSISTENCY CHECK FAILED!!! err=%i\n", err);
420 fRet |=
Add_(addr, source, nTimePenalty);
429 bool Add(
const std::vector<CAddress> &vAddr,
const CNetAddr& source, int64_t nTimePenalty = 0)
435 for (std::vector<CAddress>::const_iterator it = vAddr.begin(); it != vAddr.end(); it++)
436 nAdd +=
Add_(*it, source, nTimePenalty) ? 1 : 0;
440 LogPrint(
"addrman",
"Added %i addresses from %s: %i tried, %i new\n", nAdd, source.
ToString().c_str(),
nTried,
nNew);
484 std::vector<CAddress> vAddr;
void Attempt(const CService &addr, int64_t nTime=GetAdjustedTime())
int GetNewBucket(const std::vector< unsigned char > &nKey, const CNetAddr &src) const
CAddrInfo * Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId=NULL)
std::string ToStringIPPort() const
CAddress Select_(int nUnkBias)
bool Add(const CAddress &addr, const CNetAddr &source, int64_t nTimePenalty=0)
#define ADDRMAN_TRIED_BUCKET_COUNT
double GetChance(int64_t nNow=GetAdjustedTime()) const
CAddrInfo * Find(const CNetAddr &addr, int *pnId=NULL)
Stochastical (IP) address manager.
std::vector< CAddress > GetAddr()
Extended statistics about a CAddress.
std::vector< int > vRandom
int64_t GetAdjustedTime()
int SelectTried(int nKBucket)
std::vector< std::set< int > > vvNew
A combination of a network address (CNetAddr) and a (TCP) port.
void MakeTried(CAddrInfo &info, int nId, int nOrigin)
A CService with information about it as peer.
void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2)
int ShrinkNew(int nUBucket)
std::map< CNetAddr, int > mapAddr
IMPLEMENT_SERIALIZE(CAddress *pthis=(CAddress *)(this);READWRITE(*pthis);READWRITE(source);READWRITE(nLastSuccess);READWRITE(nAttempts);) void Init()
#define ADDRMAN_TRIED_BUCKET_SIZE
std::vector< std::vector< int > > vvTried
IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96))
void Good_(const CService &addr, int64_t nTime)
std::vector< unsigned char > nKey
CAddrInfo(const CAddress &addrIn, const CNetAddr &addrSource)
#define ADDRMAN_NEW_BUCKET_COUNT
int GetTriedBucket(const std::vector< unsigned char > &nKey) const
bool Add_(const CAddress &addr, const CNetAddr &source, int64_t nTimePenalty)
void Connected_(const CService &addr, int64_t nTime)
CAddress Select(int nUnkBias=50)
void GetAddr_(std::vector< CAddress > &vAddr)
std::map< int, CAddrInfo > mapInfo
bool Add(const std::vector< CAddress > &vAddr, const CNetAddr &source, int64_t nTimePenalty=0)
int GetNewBucket(const std::vector< unsigned char > &nKey) const
std::string ToString() const
void Connected(const CService &addr, int64_t nTime=GetAdjustedTime())
void Attempt_(const CService &addr, int64_t nTime)
bool IsTerrible(int64_t nNow=GetAdjustedTime()) const
IMPLEMENT_SERIALIZE(({{LOCK(cs);unsigned char nVersion=0;READWRITE(nVersion);READWRITE(nKey);READWRITE(nNew);READWRITE(nTried);CAddrMan *am=const_cast< CAddrMan * >(this);if(fWrite){int nUBuckets=ADDRMAN_NEW_BUCKET_COUNT;READWRITE(nUBuckets);std::map< int, int > mapUnkIds;int nIds=0;for(std::map< int, CAddrInfo >::iterator it=am->mapInfo.begin();it!=am->mapInfo.end();it++){if(nIds==nNew) break;mapUnkIds[(*it).first]=nIds;CAddrInfo &info=(*it).second;if(info.nRefCount){READWRITE(info);nIds++;}}nIds=0;for(std::map< int, CAddrInfo >::iterator it=am->mapInfo.begin();it!=am->mapInfo.end();it++){if(nIds==nTried) break;CAddrInfo &info=(*it).second;if(info.fInTried){READWRITE(info);nIds++;}}for(std::vector< std::set< int > >::iterator it=am->vvNew.begin();it!=am->vvNew.end();it++){const std::set< int > &vNew=(*it);int nSize=vNew.size();READWRITE(nSize);for(std::set< int >::iterator it2=vNew.begin();it2!=vNew.end();it2++){int nIndex=mapUnkIds[*it2];READWRITE(nIndex);}}}else{int nUBuckets=0;READWRITE(nUBuckets);am->nIdCount=0;am->mapInfo.clear();am->mapAddr.clear();am->vRandom.clear();am->vvTried=std::vector< std::vector< int > >(ADDRMAN_TRIED_BUCKET_COUNT, std::vector< int >(0));am->vvNew=std::vector< std::set< int > >(ADDRMAN_NEW_BUCKET_COUNT, std::set< int >());for(int n=0;n< am->nNew;n++){CAddrInfo &info=am->mapInfo[n];READWRITE(info);am->mapAddr[info]=n;info.nRandomPos=vRandom.size();am->vRandom.push_back(n);if(nUBuckets!=ADDRMAN_NEW_BUCKET_COUNT){am->vvNew[info.GetNewBucket(am->nKey)].insert(n);info.nRefCount++;}}am->nIdCount=am->nNew;int nLost=0;for(int n=0;n< am->nTried;n++){CAddrInfo info;READWRITE(info);std::vector< int > &vTried=am->vvTried[info.GetTriedBucket(am->nKey)];if(vTried.size()< ADDRMAN_TRIED_BUCKET_SIZE){info.nRandomPos=vRandom.size();info.fInTried=true;am->vRandom.push_back(am->nIdCount);am->mapInfo[am->nIdCount]=info;am->mapAddr[info]=am->nIdCount;vTried.push_back(am->nIdCount);am->nIdCount++;}else{nLost++;}}am->nTried-=nLost;for(int b=0;b< nUBuckets;b++){std::set< int > &vNew=am->vvNew[b];int nSize=0;READWRITE(nSize);for(int n=0;n< nSize;n++){int nIndex=0;READWRITE(nIndex);CAddrInfo &info=am->mapInfo[nIndex];if(nUBuckets==ADDRMAN_NEW_BUCKET_COUNT &&info.nRefCount< ADDRMAN_NEW_BUCKETS_PER_ADDRESS){info.nRefCount++;vNew.insert(nIndex);}}}}}});) CAddrMan()
#define ADDRMAN_NEW_BUCKETS_PER_ADDRESS
void Good(const CService &addr, int64_t nTime=GetAdjustedTime())