@@ -732,40 +732,56 @@ std::pair<CAddress, int64_t> AddrManImpl::Select_(bool newOnly) const
732
732
// use a tried node
733
733
double fChanceFactor = 1.0 ;
734
734
while (1 ) {
735
+ // Pick a tried bucket, and an initial position in that bucket.
735
736
int nKBucket = insecure_rand.randrange (ADDRMAN_TRIED_BUCKET_COUNT);
736
737
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 ;
740
743
}
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];
742
748
const auto it_found{mapInfo.find (nId)};
743
749
assert (it_found != mapInfo.end ());
744
750
const AddrInfo& info{it_found->second };
751
+ // With probability GetChance() * fChanceFactor, return the entry.
745
752
if (insecure_rand.randbits (30 ) < fChanceFactor * info.GetChance () * (1 << 30 )) {
746
753
LogPrint (BCLog::ADDRMAN, " Selected %s from tried\n " , info.ToString ());
747
754
return {info, info.nLastTry };
748
755
}
756
+ // Otherwise start over with a (likely) different bucket, and increased chance factor.
749
757
fChanceFactor *= 1.2 ;
750
758
}
751
759
} else {
752
760
// use a new node
753
761
double fChanceFactor = 1.0 ;
754
762
while (1 ) {
763
+ // Pick a new bucket, and an initial position in that bucket.
755
764
int nUBucket = insecure_rand.randrange (ADDRMAN_NEW_BUCKET_COUNT);
756
765
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 ;
760
771
}
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];
762
776
const auto it_found{mapInfo.find (nId)};
763
777
assert (it_found != mapInfo.end ());
764
778
const AddrInfo& info{it_found->second };
779
+ // With probability GetChance() * fChanceFactor, return the entry.
765
780
if (insecure_rand.randbits (30 ) < fChanceFactor * info.GetChance () * (1 << 30 )) {
766
781
LogPrint (BCLog::ADDRMAN, " Selected %s from new\n " , info.ToString ());
767
782
return {info, info.nLastTry };
768
783
}
784
+ // Otherwise start over with a (likely) different bucket, and increased chance factor.
769
785
fChanceFactor *= 1.2 ;
770
786
}
771
787
}
0 commit comments