aboutsummaryrefslogtreecommitdiff
path: root/src/addrman.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/addrman.cpp')
-rw-r--r--src/addrman.cpp95
1 files changed, 64 insertions, 31 deletions
diff --git a/src/addrman.cpp b/src/addrman.cpp
index c41ee3f9f..b6ab4c630 100644
--- a/src/addrman.cpp
+++ b/src/addrman.cpp
@@ -1,4 +1,5 @@
// Copyright (c) 2012 Pieter Wuille
+// Copyright (c) 2012-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -8,8 +9,6 @@
#include "serialize.h"
#include "streams.h"
-using namespace std;
-
int CAddrInfo::GetTriedBucket(const uint256& nKey) const
{
uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) << nKey << GetKey()).GetHash().GetCheapHash();
@@ -54,21 +53,14 @@ bool CAddrInfo::IsTerrible(int64_t nNow) const
double CAddrInfo::GetChance(int64_t nNow) const
{
double fChance = 1.0;
-
- int64_t nSinceLastSeen = nNow - nTime;
- int64_t nSinceLastTry = nNow - nLastTry;
-
- if (nSinceLastSeen < 0)
- nSinceLastSeen = 0;
- if (nSinceLastTry < 0)
- nSinceLastTry = 0;
+ int64_t nSinceLastTry = std::max<int64_t>(nNow - nLastTry, 0);
// deprioritize very recent attempts away
if (nSinceLastTry < 60 * 10)
fChance *= 0.01;
// deprioritize 66% after each failed attempt, but at most 1/28th to avoid the search taking forever or overly penalizing outages.
- fChance *= pow(0.66, min(nAttempts, 8));
+ fChance *= pow(0.66, std::min(nAttempts, 8));
return fChance;
}
@@ -198,6 +190,9 @@ void CAddrMan::MakeTried(CAddrInfo& info, int nId)
void CAddrMan::Good_(const CService& addr, int64_t nTime)
{
int nId;
+
+ nLastGood = nTime;
+
CAddrInfo* pinfo = Find(addr, &nId);
// if not found, bail out
@@ -222,7 +217,7 @@ void CAddrMan::Good_(const CService& addr, int64_t nTime)
return;
// find a bucket it is in now
- int nRnd = GetRandInt(ADDRMAN_NEW_BUCKET_COUNT);
+ int nRnd = RandomInt(ADDRMAN_NEW_BUCKET_COUNT);
int nUBucket = -1;
for (unsigned int n = 0; n < ADDRMAN_NEW_BUCKET_COUNT; n++) {
int nB = (n + nRnd) % ADDRMAN_NEW_BUCKET_COUNT;
@@ -253,15 +248,20 @@ bool CAddrMan::Add_(const CAddress& addr, const CNetAddr& source, int64_t nTimeP
int nId;
CAddrInfo* pinfo = Find(addr, &nId);
+ // Do not set a penalty for a source's self-announcement
+ if (addr == source) {
+ nTimePenalty = 0;
+ }
+
if (pinfo) {
// periodically update nTime
bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
int64_t nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
if (addr.nTime && (!pinfo->nTime || pinfo->nTime < addr.nTime - nUpdateInterval - nTimePenalty))
- pinfo->nTime = max((int64_t)0, addr.nTime - nTimePenalty);
+ pinfo->nTime = std::max((int64_t)0, addr.nTime - nTimePenalty);
// add services
- pinfo->nServices |= addr.nServices;
+ pinfo->nServices = ServiceFlags(pinfo->nServices | addr.nServices);
// do not update if no new information is present
if (!addr.nTime || (pinfo->nTime && addr.nTime <= pinfo->nTime))
@@ -279,11 +279,11 @@ bool CAddrMan::Add_(const CAddress& addr, const CNetAddr& source, int64_t nTimeP
int nFactor = 1;
for (int n = 0; n < pinfo->nRefCount; n++)
nFactor *= 2;
- if (nFactor > 1 && (GetRandInt(nFactor) != 0))
+ if (nFactor > 1 && (RandomInt(nFactor) != 0))
return false;
} else {
pinfo = Create(addr, source, &nId);
- pinfo->nTime = max((int64_t)0, (int64_t)pinfo->nTime - nTimePenalty);
+ pinfo->nTime = std::max((int64_t)0, (int64_t)pinfo->nTime - nTimePenalty);
nNew++;
fNew = true;
}
@@ -312,7 +312,7 @@ bool CAddrMan::Add_(const CAddress& addr, const CNetAddr& source, int64_t nTimeP
return fNew;
}
-void CAddrMan::Attempt_(const CService& addr, int64_t nTime)
+void CAddrMan::Attempt_(const CService& addr, bool fCountFailure, int64_t nTime)
{
CAddrInfo* pinfo = Find(addr);
@@ -328,27 +328,36 @@ void CAddrMan::Attempt_(const CService& addr, int64_t nTime)
// update info
info.nLastTry = nTime;
- info.nAttempts++;
+ if (fCountFailure && info.nLastCountAttempt < nLastGood) {
+ info.nLastCountAttempt = nTime;
+ info.nAttempts++;
+ }
}
-CAddrInfo CAddrMan::Select_()
+CAddrInfo CAddrMan::Select_(bool newOnly)
{
if (size() == 0)
return CAddrInfo();
+ if (newOnly && nNew == 0)
+ return CAddrInfo();
+
// Use a 50% chance for choosing between tried and new table entries.
- if (nTried > 0 && (nNew == 0 || GetRandInt(2) == 0)) {
+ if (!newOnly &&
+ (nTried > 0 && (nNew == 0 || RandomInt(2) == 0))) {
// use a tried node
double fChanceFactor = 1.0;
while (1) {
- int nKBucket = GetRandInt(ADDRMAN_TRIED_BUCKET_COUNT);
- int nKBucketPos = GetRandInt(ADDRMAN_BUCKET_SIZE);
- if (vvTried[nKBucket][nKBucketPos] == -1)
- continue;
+ int nKBucket = RandomInt(ADDRMAN_TRIED_BUCKET_COUNT);
+ int nKBucketPos = RandomInt(ADDRMAN_BUCKET_SIZE);
+ while (vvTried[nKBucket][nKBucketPos] == -1) {
+ nKBucket = (nKBucket + insecure_rand.rand32()) % ADDRMAN_TRIED_BUCKET_COUNT;
+ nKBucketPos = (nKBucketPos + insecure_rand.rand32()) % ADDRMAN_BUCKET_SIZE;
+ }
int nId = vvTried[nKBucket][nKBucketPos];
assert(mapInfo.count(nId) == 1);
CAddrInfo& info = mapInfo[nId];
- if (GetRandInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30))
+ if (RandomInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30))
return info;
fChanceFactor *= 1.2;
}
@@ -356,14 +365,16 @@ CAddrInfo CAddrMan::Select_()
// use a new node
double fChanceFactor = 1.0;
while (1) {
- int nUBucket = GetRandInt(ADDRMAN_NEW_BUCKET_COUNT);
- int nUBucketPos = GetRandInt(ADDRMAN_BUCKET_SIZE);
- if (vvNew[nUBucket][nUBucketPos] == -1)
- continue;
+ int nUBucket = RandomInt(ADDRMAN_NEW_BUCKET_COUNT);
+ int nUBucketPos = RandomInt(ADDRMAN_BUCKET_SIZE);
+ while (vvNew[nUBucket][nUBucketPos] == -1) {
+ nUBucket = (nUBucket + insecure_rand.rand32()) % ADDRMAN_NEW_BUCKET_COUNT;
+ nUBucketPos = (nUBucketPos + insecure_rand.rand32()) % ADDRMAN_BUCKET_SIZE;
+ }
int nId = vvNew[nUBucket][nUBucketPos];
assert(mapInfo.count(nId) == 1);
CAddrInfo& info = mapInfo[nId];
- if (GetRandInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30))
+ if (RandomInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30))
return info;
fChanceFactor *= 1.2;
}
@@ -459,7 +470,7 @@ void CAddrMan::GetAddr_(std::vector<CAddress>& vAddr)
if (vAddr.size() >= nNodes)
break;
- int nRndPos = GetRandInt(vRandom.size() - n) + n;
+ int nRndPos = RandomInt(vRandom.size() - n) + n;
SwapRandom(n, nRndPos);
assert(mapInfo.count(vRandom[n]) == 1);
@@ -488,3 +499,25 @@ void CAddrMan::Connected_(const CService& addr, int64_t nTime)
if (nTime - info.nTime > nUpdateInterval)
info.nTime = nTime;
}
+
+void CAddrMan::SetServices_(const CService& addr, ServiceFlags nServices)
+{
+ CAddrInfo* pinfo = Find(addr);
+
+ // if not found, bail out
+ if (!pinfo)
+ return;
+
+ CAddrInfo& info = *pinfo;
+
+ // check whether we are talking about the exact same CService (including same port)
+ if (info != addr)
+ return;
+
+ // update info
+ info.nServices = nServices;
+}
+
+int CAddrMan::RandomInt(int nMax){
+ return GetRandInt(nMax);
+}