Skip to content

Commit d56702a

Browse files
committed
merge bitcoin#23140: Make CAddrman::Select_ select buckets, not positions, first
1 parent 19b0145 commit d56702a

File tree

1 file changed

+24
-8
lines changed

1 file changed

+24
-8
lines changed

src/addrman.cpp

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -732,40 +732,56 @@ std::pair<CAddress, int64_t> AddrManImpl::Select_(bool newOnly) const
732732
// use a tried node
733733
double fChanceFactor = 1.0;
734734
while (1) {
735+
// Pick a tried bucket, and an initial position in that bucket.
735736
int nKBucket = insecure_rand.randrange(ADDRMAN_TRIED_BUCKET_COUNT);
736737
int nKBucketPos = insecure_rand.randrange(ADDRMAN_BUCKET_SIZE);
737-
while (vvTried[nKBucket][nKBucketPos] == -1) {
738-
nKBucket = (nKBucket + insecure_rand.randbits(ADDRMAN_TRIED_BUCKET_COUNT_LOG2)) % ADDRMAN_TRIED_BUCKET_COUNT;
739-
nKBucketPos = (nKBucketPos + insecure_rand.randbits(ADDRMAN_BUCKET_SIZE_LOG2)) % ADDRMAN_BUCKET_SIZE;
738+
// Iterate over the positions of that bucket, starting at the initial one,
739+
// and looping around.
740+
int i;
741+
for (i = 0; i < ADDRMAN_BUCKET_SIZE; ++i) {
742+
if (vvTried[nKBucket][(nKBucketPos + i) % ADDRMAN_BUCKET_SIZE] != -1) break;
740743
}
741-
int nId = vvTried[nKBucket][nKBucketPos];
744+
// If the bucket is entirely empty, start over with a (likely) different one.
745+
if (i == ADDRMAN_BUCKET_SIZE) continue;
746+
// Find the entry to return.
747+
int nId = vvTried[nKBucket][(nKBucketPos + i) % ADDRMAN_BUCKET_SIZE];
742748
const auto it_found{mapInfo.find(nId)};
743749
assert(it_found != mapInfo.end());
744750
const AddrInfo& info{it_found->second};
751+
// With probability GetChance() * fChanceFactor, return the entry.
745752
if (insecure_rand.randbits(30) < fChanceFactor * info.GetChance() * (1 << 30)) {
746753
LogPrint(BCLog::ADDRMAN, "Selected %s from tried\n", info.ToString());
747754
return {info, info.nLastTry};
748755
}
756+
// Otherwise start over with a (likely) different bucket, and increased chance factor.
749757
fChanceFactor *= 1.2;
750758
}
751759
} else {
752760
// use a new node
753761
double fChanceFactor = 1.0;
754762
while (1) {
763+
// Pick a new bucket, and an initial position in that bucket.
755764
int nUBucket = insecure_rand.randrange(ADDRMAN_NEW_BUCKET_COUNT);
756765
int nUBucketPos = insecure_rand.randrange(ADDRMAN_BUCKET_SIZE);
757-
while (vvNew[nUBucket][nUBucketPos] == -1) {
758-
nUBucket = (nUBucket + insecure_rand.randbits(ADDRMAN_NEW_BUCKET_COUNT_LOG2)) % ADDRMAN_NEW_BUCKET_COUNT;
759-
nUBucketPos = (nUBucketPos + insecure_rand.randbits(ADDRMAN_BUCKET_SIZE_LOG2)) % ADDRMAN_BUCKET_SIZE;
766+
// Iterate over the positions of that bucket, starting at the initial one,
767+
// and looping around.
768+
int i;
769+
for (i = 0; i < ADDRMAN_BUCKET_SIZE; ++i) {
770+
if (vvNew[nUBucket][(nUBucketPos + i) % ADDRMAN_BUCKET_SIZE] != -1) break;
760771
}
761-
int nId = vvNew[nUBucket][nUBucketPos];
772+
// If the bucket is entirely empty, start over with a (likely) different one.
773+
if (i == ADDRMAN_BUCKET_SIZE) continue;
774+
// Find the entry to return.
775+
int nId = vvNew[nUBucket][(nUBucketPos + i) % ADDRMAN_BUCKET_SIZE];
762776
const auto it_found{mapInfo.find(nId)};
763777
assert(it_found != mapInfo.end());
764778
const AddrInfo& info{it_found->second};
779+
// With probability GetChance() * fChanceFactor, return the entry.
765780
if (insecure_rand.randbits(30) < fChanceFactor * info.GetChance() * (1 << 30)) {
766781
LogPrint(BCLog::ADDRMAN, "Selected %s from new\n", info.ToString());
767782
return {info, info.nLastTry};
768783
}
784+
// Otherwise start over with a (likely) different bucket, and increased chance factor.
769785
fChanceFactor *= 1.2;
770786
}
771787
}

0 commit comments

Comments
 (0)