Fix issue #717 where if addrman is starved of addresses (e.g. on testnet)
the Select_() function will loop endlessly trying to find an address, and therefore eat up 100% cpu time on the 'opencon' thread. Solution is to (1) add a delay to the loop and (2) restrict the number of attempts to find an address. On exiting the loop, we return to an outer loop in net.cpp which will sleep, add seed nodes and calcualte new addresses.
This commit is contained in:
@@ -336,11 +336,14 @@ CAddrInfo CAddrMan::Select_()
|
|||||||
if (size() == 0)
|
if (size() == 0)
|
||||||
return CAddrInfo();
|
return CAddrInfo();
|
||||||
|
|
||||||
|
// Track number of attempts to find a table entry, before giving up
|
||||||
|
int nRetries = 0;
|
||||||
|
|
||||||
// Use a 50% chance for choosing between tried and new table entries.
|
// Use a 50% chance for choosing between tried and new table entries.
|
||||||
if (nTried > 0 && (nNew == 0 || GetRandInt(2) == 0)) {
|
if (nTried > 0 && (nNew == 0 || GetRandInt(2) == 0)) {
|
||||||
// use a tried node
|
// use a tried node
|
||||||
double fChanceFactor = 1.0;
|
double fChanceFactor = 1.0;
|
||||||
while (1) {
|
while (nRetries++ < ADDRMAN_TRIED_BUCKET_COUNT) {
|
||||||
int nKBucket = GetRandInt(ADDRMAN_TRIED_BUCKET_COUNT);
|
int nKBucket = GetRandInt(ADDRMAN_TRIED_BUCKET_COUNT);
|
||||||
int nKBucketPos = GetRandInt(ADDRMAN_BUCKET_SIZE);
|
int nKBucketPos = GetRandInt(ADDRMAN_BUCKET_SIZE);
|
||||||
if (vvTried[nKBucket][nKBucketPos] == -1)
|
if (vvTried[nKBucket][nKBucketPos] == -1)
|
||||||
@@ -351,11 +354,12 @@ CAddrInfo CAddrMan::Select_()
|
|||||||
if (GetRandInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30))
|
if (GetRandInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30))
|
||||||
return info;
|
return info;
|
||||||
fChanceFactor *= 1.2;
|
fChanceFactor *= 1.2;
|
||||||
|
MilliSleep(100);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// use a new node
|
// use a new node
|
||||||
double fChanceFactor = 1.0;
|
double fChanceFactor = 1.0;
|
||||||
while (1) {
|
while (nRetries++ < ADDRMAN_NEW_BUCKET_COUNT) {
|
||||||
int nUBucket = GetRandInt(ADDRMAN_NEW_BUCKET_COUNT);
|
int nUBucket = GetRandInt(ADDRMAN_NEW_BUCKET_COUNT);
|
||||||
int nUBucketPos = GetRandInt(ADDRMAN_BUCKET_SIZE);
|
int nUBucketPos = GetRandInt(ADDRMAN_BUCKET_SIZE);
|
||||||
if (vvNew[nUBucket][nUBucketPos] == -1)
|
if (vvNew[nUBucket][nUBucketPos] == -1)
|
||||||
@@ -366,8 +370,11 @@ CAddrInfo CAddrMan::Select_()
|
|||||||
if (GetRandInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30))
|
if (GetRandInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30))
|
||||||
return info;
|
return info;
|
||||||
fChanceFactor *= 1.2;
|
fChanceFactor *= 1.2;
|
||||||
|
MilliSleep(100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return CAddrInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_ADDRMAN
|
#ifdef DEBUG_ADDRMAN
|
||||||
|
|||||||
Reference in New Issue
Block a user