using namespace std;
+void CAddrInfo::Init()
+{
+ nLastSuccess = 0;
+ nLastTry = 0;
+ nAttempts = 0;
+ nRefCount = 0;
+ fInTried = false;
+ nRandomPos = -1;
+}
+
+CAddrInfo::CAddrInfo(const CAddress &addrIn, const CNetAddr &addrSource) : CAddress(addrIn), source(addrSource)
+{
+ Init();
+}
+
+CAddrInfo::CAddrInfo() : CAddress(), source()
+{
+ Init();
+}
+
int CAddrInfo::GetTriedBucket(const std::vector<unsigned char> &nKey) const
{
CDataStream ss1(SER_GETHASH, 0);
std::vector<unsigned char> vchKey = GetKey();
ss1 << nKey << vchKey;
- uint64_t hash1 = Hash(ss1.begin(), ss1.end()).Get64();
+ auto hash1 = Hash(ss1.begin(), ss1.end()).Get64();
CDataStream ss2(SER_GETHASH, 0);
std::vector<unsigned char> vchGroupKey = GetGroup();
ss2 << nKey << vchGroupKey << (hash1 % ADDRMAN_TRIED_BUCKETS_PER_GROUP);
- uint64_t hash2 = Hash(ss2.begin(), ss2.end()).Get64();
+ auto hash2 = Hash(ss2.begin(), ss2.end()).Get64();
return hash2 % ADDRMAN_TRIED_BUCKET_COUNT;
}
std::vector<unsigned char> vchGroupKey = GetGroup();
std::vector<unsigned char> vchSourceGroupKey = src.GetGroup();
ss1 << nKey << vchGroupKey << vchSourceGroupKey;
- uint64_t hash1 = Hash(ss1.begin(), ss1.end()).Get64();
+ auto hash1 = Hash(ss1.begin(), ss1.end()).Get64();
CDataStream ss2(SER_GETHASH, 0);
ss2 << nKey << vchSourceGroupKey << (hash1 % ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP);
- uint64_t hash2 = Hash(ss2.begin(), ss2.end()).Get64();
+ auto hash2 = Hash(ss2.begin(), ss2.end()).Get64();
return hash2 % ADDRMAN_NEW_BUCKET_COUNT;
}
+int CAddrInfo::GetNewBucket(const std::vector<unsigned char> &nKey) const
+{
+ return GetNewBucket(nKey, source);
+}
+
bool CAddrInfo::IsTerrible(int64_t nNow) const
{
if (nLastTry && nLastTry >= nNow-60) // never remove things tried the last minute
{
double fChance = 1.0;
- int64_t nSinceLastSeen = nNow - nTime;
- int64_t nSinceLastTry = nNow - nLastTry;
+ auto nSinceLastSeen = nNow - nTime;
+ auto nSinceLastTry = nNow - nLastTry;
if (nSinceLastSeen < 0) nSinceLastSeen = 0;
if (nSinceLastTry < 0) nSinceLastTry = 0;
}
}
-#ifdef DEBUG_ADDRMAN
-int CAddrMan::Check_()
-{
- std::set<int> setTried;
- std::map<int, int> mapNew;
-
- if (vRandom.size() != nTried + nNew) return -7;
-
- for (auto it = mapInfo.begin(); it != mapInfo.end(); it++)
- {
- int n = (*it).first;
- CAddrInfo &info = (*it).second;
- if (info.fInTried)
- {
-
- if (!info.nLastSuccess) return -1;
- if (info.nRefCount) return -2;
- setTried.insert(n);
- } else {
- if (info.nRefCount < 0 || info.nRefCount > ADDRMAN_NEW_BUCKETS_PER_ADDRESS) return -3;
- if (!info.nRefCount) return -4;
- mapNew[n] = info.nRefCount;
- }
- if (mapAddr[info] != n) return -5;
- if (info.nRandomPos<0 || info.nRandomPos>=vRandom.size() || vRandom[info.nRandomPos] != n) return -14;
- if (info.nLastTry < 0) return -6;
- if (info.nLastSuccess < 0) return -8;
- }
-
- if (setTried.size() != nTried) return -9;
- if (mapNew.size() != nNew) return -10;
-
- for (int n=0; n<vvTried.size(); n++)
- {
- std::vector<int> &vTried = vvTried[n];
- for (auto it = vTried.begin(); it != vTried.end(); it++)
- {
- if (!setTried.count(*it)) return -11;
- setTried.erase(*it);
- }
- }
-
- for (int n=0; n<vvNew.size(); n++)
- {
- std::set<int> &vNew = vvNew[n];
- for (auto it = vNew.begin(); it != vNew.end(); it++)
- {
- if (!mapNew.count(*it)) return -12;
- if (--mapNew[*it] == 0)
- mapNew.erase(*it);
- }
- }
-
- if (setTried.size()) return -13;
- if (mapNew.size()) return -15;
-
- return 0;
-}
-#endif
-
void CAddrMan::GetAddr_(std::vector<CAddress> &vAddr)
{
size_t nNodes = ADDRMAN_GETADDR_MAX_PCT*vRandom.size()/100;
{
for (auto it = mapInfo.begin(); it != mapInfo.end(); it++)
{
- CAddrInfo addr = it->second;
+ auto addr = it->second;
bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < nOneDay);
if (fCurrentlyOnline)
vAddr.push_back(addr);
if (nTime - info.nTime > nUpdateInterval)
info.nTime = nTime;
}
+
+CAddrMan::CAddrMan() : vRandom(0), vvTried(ADDRMAN_TRIED_BUCKET_COUNT, std::vector<int>(0)), vvNew(ADDRMAN_NEW_BUCKET_COUNT, std::set<int>())
+{
+ nKey.resize(32);
+ RAND_bytes(&nKey[0], 32);
+
+ nIdCount = 0;
+ nTried = 0;
+ nNew = 0;
+}
+
+int CAddrMan::size()
+{
+ return (int) vRandom.size();
+}
+
+bool CAddrMan::Add(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty)
+{
+ bool fRet = false;
+ {
+ LOCK(cs);
+ fRet |= Add_(addr, source, nTimePenalty);
+ }
+ if (fRet)
+ printf("Added %s from %s: %i tried, %i new\n", addr.ToStringIPPort().c_str(), source.ToString().c_str(), nTried, nNew);
+ return fRet;
+}
+
+bool CAddrMan::Add(const std::vector<CAddress> &vAddr, const CNetAddr& source, int64_t nTimePenalty)
+{
+ int nAdd = 0;
+ {
+ LOCK(cs);
+ for (auto it = vAddr.begin(); it != vAddr.end(); it++)
+ nAdd += Add_(*it, source, nTimePenalty) ? 1 : 0;
+ }
+ if (nAdd)
+ printf("Added %i addresses from %s: %i tried, %i new\n", nAdd, source.ToString().c_str(), nTried, nNew);
+ return nAdd > 0;
+}
+
+void CAddrMan::Good(const CService &addr, int64_t nTime)
+{
+ {
+ LOCK(cs);
+ Good_(addr, nTime);
+ }
+}
+
+void CAddrMan::Attempt(const CService &addr, int64_t nTime)
+{
+ {
+ LOCK(cs);
+ Attempt_(addr, nTime);
+ }
+}
+
+CAddress CAddrMan::Select(int nUnkBias)
+{
+ CAddress addrRet;
+ {
+ LOCK(cs);
+ addrRet = Select_(nUnkBias);
+ }
+ return addrRet;
+}
+
+std::vector<CAddress> CAddrMan::GetAddr()
+{
+ std::vector<CAddress> vAddr;
+ {
+ LOCK(cs);
+ GetAddr_(vAddr);
+ }
+ return vAddr;
+}
+
+std::vector<CAddrInfo> CAddrMan::GetOnlineAddr()
+{
+ std::vector<CAddrInfo> vAddr;
+ {
+ LOCK(cs);
+ GetOnlineAddr_(vAddr);
+ }
+ return vAddr;
+}
+
+void CAddrMan::Connected(const CService &addr, int64_t nTime)
+{
+ {
+ LOCK(cs);
+ Connected_(addr, nTime);
+ }
+}