@@ -714,28 +714,41 @@ void AddrManImpl::Attempt_(const CService& addr, bool fCountFailure, NodeSeconds
714
714
}
715
715
}
716
716
717
- std::pair<CAddress, NodeSeconds> AddrManImpl::Select_ (bool new_only) const
717
+ std::pair<CAddress, NodeSeconds> AddrManImpl::Select_ (bool new_only, std::optional<Network> network ) const
718
718
{
719
719
AssertLockHeld (cs);
720
720
721
721
if (vRandom.empty ()) return {};
722
- if (new_only && nNew == 0 ) return {};
722
+
723
+ size_t new_count = nNew;
724
+ size_t tried_count = nTried;
725
+
726
+ if (network.has_value ()) {
727
+ auto it = m_network_counts.find (*network);
728
+ if (it == m_network_counts.end ()) return {};
729
+
730
+ auto counts = it->second ;
731
+ new_count = counts.n_new ;
732
+ tried_count = counts.n_tried ;
733
+ }
734
+
735
+ if (new_only && new_count == 0 ) return {};
736
+ if (new_count + tried_count == 0 ) return {};
723
737
724
738
// Decide if we are going to search the new or tried table
739
+ // If either option is viable, use a 50% chance to choose
725
740
bool search_tried;
726
- int bucket_count;
727
-
728
- // Use a 50% chance for choosing between tried and new table entries.
729
- if (!new_only &&
730
- (nTried > 0 &&
731
- (nNew == 0 || insecure_rand.randbool () == 0 ))) {
741
+ if (new_only || tried_count == 0 ) {
742
+ search_tried = false ;
743
+ } else if (new_count == 0 ) {
732
744
search_tried = true ;
733
- bucket_count = ADDRMAN_TRIED_BUCKET_COUNT;
734
745
} else {
735
- search_tried = false ;
736
- bucket_count = ADDRMAN_NEW_BUCKET_COUNT;
746
+ search_tried = insecure_rand.randbool ();
737
747
}
738
748
749
+ const int bucket_count{search_tried ? ADDRMAN_TRIED_BUCKET_COUNT : ADDRMAN_NEW_BUCKET_COUNT};
750
+
751
+ // Loop through the addrman table until we find an appropriate entry
739
752
double chance_factor = 1.0 ;
740
753
while (1 ) {
741
754
// Pick a bucket, and an initial position in that bucket.
@@ -748,7 +761,16 @@ std::pair<CAddress, NodeSeconds> AddrManImpl::Select_(bool new_only) const
748
761
for (i = 0 ; i < ADDRMAN_BUCKET_SIZE; ++i) {
749
762
int position = (initial_position + i) % ADDRMAN_BUCKET_SIZE;
750
763
int node_id = GetEntry (search_tried, bucket, position);
751
- if (node_id != -1 ) break ;
764
+ if (node_id != -1 ) {
765
+ if (network.has_value ()) {
766
+ const auto it{mapInfo.find (node_id)};
767
+ assert (it != mapInfo.end ());
768
+ const auto info{it->second };
769
+ if (info.GetNetwork () == *network) break ;
770
+ } else {
771
+ break ;
772
+ }
773
+ }
752
774
}
753
775
754
776
// If the bucket is entirely empty, start over with a (likely) different one.
@@ -1168,11 +1190,11 @@ std::pair<CAddress, NodeSeconds> AddrManImpl::SelectTriedCollision()
1168
1190
return ret;
1169
1191
}
1170
1192
1171
- std::pair<CAddress, NodeSeconds> AddrManImpl::Select (bool new_only) const
1193
+ std::pair<CAddress, NodeSeconds> AddrManImpl::Select (bool new_only, std::optional<Network> network ) const
1172
1194
{
1173
1195
LOCK (cs);
1174
1196
Check ();
1175
- auto addrRet = Select_ (new_only);
1197
+ auto addrRet = Select_ (new_only, network );
1176
1198
Check ();
1177
1199
return addrRet;
1178
1200
}
@@ -1266,9 +1288,9 @@ std::pair<CAddress, NodeSeconds> AddrMan::SelectTriedCollision()
1266
1288
return m_impl->SelectTriedCollision ();
1267
1289
}
1268
1290
1269
- std::pair<CAddress, NodeSeconds> AddrMan::Select (bool new_only) const
1291
+ std::pair<CAddress, NodeSeconds> AddrMan::Select (bool new_only, std::optional<Network> network ) const
1270
1292
{
1271
- return m_impl->Select (new_only);
1293
+ return m_impl->Select (new_only, network );
1272
1294
}
1273
1295
1274
1296
std::vector<CAddress> AddrMan::GetAddr (size_t max_addresses, size_t max_pct, std::optional<Network> network) const
0 commit comments