Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Makefile.test.include
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ BITCOIN_TESTS =\
test/benchmark_zerocoin.cpp \
test/tutorial_zerocoin.cpp \
test/libzerocoin_tests.cpp \
test/addrman_tests.cpp \
test/allocator_tests.cpp \
test/base32_tests.cpp \
test/base58_tests.cpp \
Expand Down
29 changes: 18 additions & 11 deletions src/addrman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,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;
Expand Down Expand Up @@ -281,7 +281,7 @@ 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);
Expand Down Expand Up @@ -333,43 +333,46 @@ void CAddrMan::Attempt_(const CService& addr, int64_t 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);
int nKBucket = RandomInt(ADDRMAN_TRIED_BUCKET_COUNT);
int nKBucketPos = RandomInt(ADDRMAN_BUCKET_SIZE);
while (vvTried[nKBucket][nKBucketPos] == -1) {
nKBucket = (nKBucket + insecure_rand()) % ADDRMAN_TRIED_BUCKET_COUNT;
nKBucketPos = (nKBucketPos + insecure_rand()) % 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;
}
} else {
// use a new node
double fChanceFactor = 1.0;
while (1) {
int nUBucket = GetRandInt(ADDRMAN_NEW_BUCKET_COUNT);
int nUBucketPos = GetRandInt(ADDRMAN_BUCKET_SIZE);
int nUBucket = RandomInt(ADDRMAN_NEW_BUCKET_COUNT);
int nUBucketPos = RandomInt(ADDRMAN_BUCKET_SIZE);
while (vvNew[nUBucket][nUBucketPos] == -1) {
nUBucket = (nUBucket + insecure_rand()) % ADDRMAN_NEW_BUCKET_COUNT;
nUBucketPos = (nUBucketPos + insecure_rand()) % 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;
}
Expand Down Expand Up @@ -465,7 +468,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);

Expand Down Expand Up @@ -494,3 +497,7 @@ void CAddrMan::Connected_(const CService& addr, int64_t nTime)
if (nTime - info.nTime > nUpdateInterval)
info.nTime = nTime;
}

int CAddrMan::RandomInt(int nMax){
return GetRandInt(nMax);
}
28 changes: 16 additions & 12 deletions src/addrman.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@
#include <stdint.h>
#include <vector>

/**
* Extended statistics about a CAddress
/**
* Extended statistics about a CAddress
*/
class CAddrInfo : public CAddress
{


public:
//! last try whatsoever by us (memory only)
int64_t nLastTry;
Expand Down Expand Up @@ -165,18 +167,15 @@ class CAddrInfo : public CAddress
//! the maximum number of nodes to return in a getaddr call
#define ADDRMAN_GETADDR_MAX 2500

/**
* Stochastical (IP) address manager
/**
* Stochastical (IP) address manager
*/
class CAddrMan
{
private:
//! critical section to protect the inner data structures
mutable CCriticalSection cs;

//! secret key to randomize bucket select with
uint256 nKey;

//! last used nId
int nIdCount;

Expand All @@ -202,6 +201,9 @@ class CAddrMan
int vvNew[ADDRMAN_NEW_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE];

protected:
//! secret key to randomize bucket select with
uint256 nKey;

//! Find an entry.
CAddrInfo* Find(const CNetAddr& addr, int* pnId = NULL);

Expand Down Expand Up @@ -230,9 +232,11 @@ class CAddrMan
//! Mark an entry as attempted to connect.
void Attempt_(const CService& addr, int64_t nTime);

//! Select an address to connect to.
//! nUnkBias determines how much to favor new addresses over tried ones (min=0, max=100)
CAddrInfo Select_();
//! Select an address to connect to, if newOnly is set to true, only the new table is selected from.
CAddrInfo Select_(bool newOnly);

//! Wraps GetRandInt to allow tests to override RandomInt and make it determinismistic.
virtual int RandomInt(int nMax);

#ifdef DEBUG_ADDRMAN
//! Perform consistency check. Returns an error code or zero.
Expand Down Expand Up @@ -534,13 +538,13 @@ class CAddrMan
* Choose an address to connect to.
* nUnkBias determines how much "new" entries are favored over "tried" ones (0-100).
*/
CAddrInfo Select()
CAddrInfo Select(bool newOnly = false)
{
CAddrInfo addrRet;
{
LOCK(cs);
Check();
addrRet = Select_();
addrRet = Select_(newOnly);
Check();
}
return addrRet;
Expand Down
Loading