Skip to content

Commit

Permalink
Make CAddrman::Select_ select buckets, not positions, first
Browse files Browse the repository at this point in the history
Summary:
```
The original CAddrMan behaviour (before commit
e6b343d) was to pick a uniformly random non-empty bucket, and then pick a random element from that bucket. That commit, which introduced deterministic placement of entries in buckets, changed this to picking a uniformly random non-empty bucket position instead.

This commit reverts the original high-level behavior, but in the deterministic placement model.
```

Backport of [[bitcoin/bitcoin#23140 | core#23140]].

Depends on D12339.

Test Plan:
  ninja all check-all

Reviewers: #bitcoin_abc, sdulfari

Reviewed By: #bitcoin_abc, sdulfari

Differential Revision: https://reviews.bitcoinabc.org/D12340
  • Loading branch information
sipa authored and Fabcien committed Oct 21, 2022
1 parent 1136c0b commit 55e5773
Showing 1 changed file with 39 additions and 16 deletions.
55 changes: 39 additions & 16 deletions src/addrman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -775,52 +775,75 @@ std::pair<CAddress, int64_t> AddrManImpl::Select_(bool newOnly) const {
// use a tried node
double fChanceFactor = 1.0;
while (1) {
// Pick a tried bucket, and an initial position in that bucket.
int nKBucket = insecure_rand.randrange(ADDRMAN_TRIED_BUCKET_COUNT);
int nKBucketPos = insecure_rand.randrange(ADDRMAN_BUCKET_SIZE);
while (vvTried[nKBucket][nKBucketPos] == -1) {
nKBucket = (nKBucket + insecure_rand.randbits(
ADDRMAN_TRIED_BUCKET_COUNT_LOG2)) %
ADDRMAN_TRIED_BUCKET_COUNT;
nKBucketPos = (nKBucketPos + insecure_rand.randbits(
ADDRMAN_BUCKET_SIZE_LOG2)) %
ADDRMAN_BUCKET_SIZE;
// Iterate over the positions of that bucket, starting at the
// initial one, and looping around.
int i;
for (i = 0; i < ADDRMAN_BUCKET_SIZE; ++i) {
if (vvTried[nKBucket]
[(nKBucketPos + i) % ADDRMAN_BUCKET_SIZE] != -1) {
break;
}
}
// If the bucket is entirely empty, start over with a (likely)
// different one.
if (i == ADDRMAN_BUCKET_SIZE) {
continue;
}
int nId = vvTried[nKBucket][nKBucketPos];
// Find the entry to return.
int nId =
vvTried[nKBucket][(nKBucketPos + i) % ADDRMAN_BUCKET_SIZE];
const auto it_found{mapInfo.find(nId)};
assert(it_found != mapInfo.end());
const AddrInfo &info{it_found->second};
// With probability GetChance() * fChanceFactor, return the entry.
if (insecure_rand.randbits(30) <
fChanceFactor * info.GetChance() * (1 << 30)) {
LogPrint(BCLog::ADDRMAN, "Selected %s from tried\n",
info.ToString());
return {info, info.nLastTry};
}
// Otherwise start over with a (likely) different bucket, and
// increased chance factor.
fChanceFactor *= 1.2;
}
} else {
// use a new node
double fChanceFactor = 1.0;
while (1) {
// Pick a new bucket, and an initial position in that bucket.
int nUBucket = insecure_rand.randrange(ADDRMAN_NEW_BUCKET_COUNT);
int nUBucketPos = insecure_rand.randrange(ADDRMAN_BUCKET_SIZE);
while (vvNew[nUBucket][nUBucketPos] == -1) {
nUBucket = (nUBucket + insecure_rand.randbits(
ADDRMAN_NEW_BUCKET_COUNT_LOG2)) %
ADDRMAN_NEW_BUCKET_COUNT;
nUBucketPos = (nUBucketPos + insecure_rand.randbits(
ADDRMAN_BUCKET_SIZE_LOG2)) %
ADDRMAN_BUCKET_SIZE;
// Iterate over the positions of that bucket, starting at the
// initial one, and looping around.
int i;
for (i = 0; i < ADDRMAN_BUCKET_SIZE; ++i) {
if (vvNew[nUBucket][(nUBucketPos + i) % ADDRMAN_BUCKET_SIZE] !=
-1) {
break;
}
}
// If the bucket is entirely empty, start over with a (likely)
// different one.
if (i == ADDRMAN_BUCKET_SIZE) {
continue;
}
int nId = vvNew[nUBucket][nUBucketPos];
// Find the entry to return.
int nId = vvNew[nUBucket][(nUBucketPos + i) % ADDRMAN_BUCKET_SIZE];
const auto it_found{mapInfo.find(nId)};
assert(it_found != mapInfo.end());
const AddrInfo &info{it_found->second};
// With probability GetChance() * fChanceFactor, return the entry.
if (insecure_rand.randbits(30) <
fChanceFactor * info.GetChance() * (1 << 30)) {
LogPrint(BCLog::ADDRMAN, "Selected %s from new\n",
info.ToString());
return {info, info.nLastTry};
}
// Otherwise start over with a (likely) different bucket, and
// increased chance factor.
fChanceFactor *= 1.2;
}
}
Expand Down

0 comments on commit 55e5773

Please sign in to comment.