Skip to content

Commit 7cba9d5

Browse files
committed
[net, addrman] Remove external dependencies on CAddrInfo objects
CAddrInfo objects are an implementation detail of how AddrMan manages and adds metadata to different records. Encapsulate this logic by updating Select & SelectTriedCollision to return the additional info that the callers need.
1 parent 8af5b54 commit 7cba9d5

File tree

6 files changed

+70
-60
lines changed

6 files changed

+70
-60
lines changed

src/addrman.cpp

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -694,15 +694,13 @@ void AddrManImpl::Attempt_(const CService& addr, bool fCountFailure, int64_t nTi
694694
}
695695
}
696696

697-
CAddrInfo AddrManImpl::Select_(bool newOnly) const
697+
std::pair<CAddress, int64_t> AddrManImpl::Select_(bool newOnly) const
698698
{
699699
AssertLockHeld(cs);
700700

701-
if (vRandom.empty())
702-
return CAddrInfo();
701+
if (vRandom.empty()) return {};
703702

704-
if (newOnly && nNew == 0)
705-
return CAddrInfo();
703+
if (newOnly && nNew == 0) return {};
706704

707705
// Use a 50% chance for choosing between tried and new table entries.
708706
if (!newOnly &&
@@ -720,8 +718,9 @@ CAddrInfo AddrManImpl::Select_(bool newOnly) const
720718
const auto it_found{mapInfo.find(nId)};
721719
assert(it_found != mapInfo.end());
722720
const CAddrInfo& info{it_found->second};
723-
if (insecure_rand.randbits(30) < fChanceFactor * info.GetChance() * (1 << 30))
724-
return info;
721+
if (insecure_rand.randbits(30) < fChanceFactor * info.GetChance() * (1 << 30)) {
722+
return {info, info.nLastTry};
723+
}
725724
fChanceFactor *= 1.2;
726725
}
727726
} else {
@@ -738,8 +737,9 @@ CAddrInfo AddrManImpl::Select_(bool newOnly) const
738737
const auto it_found{mapInfo.find(nId)};
739738
assert(it_found != mapInfo.end());
740739
const CAddrInfo& info{it_found->second};
741-
if (insecure_rand.randbits(30) < fChanceFactor * info.GetChance() * (1 << 30))
742-
return info;
740+
if (insecure_rand.randbits(30) < fChanceFactor * info.GetChance() * (1 << 30)) {
741+
return {info, info.nLastTry};
742+
}
743743
fChanceFactor *= 1.2;
744744
}
745745
}
@@ -883,11 +883,11 @@ void AddrManImpl::ResolveCollisions_()
883883
}
884884
}
885885

886-
CAddrInfo AddrManImpl::SelectTriedCollision_()
886+
std::pair<CAddress, int64_t> AddrManImpl::SelectTriedCollision_()
887887
{
888888
AssertLockHeld(cs);
889889

890-
if (m_tried_collisions.size() == 0) return CAddrInfo();
890+
if (m_tried_collisions.size() == 0) return {};
891891

892892
std::set<int>::iterator it = m_tried_collisions.begin();
893893

@@ -898,7 +898,7 @@ CAddrInfo AddrManImpl::SelectTriedCollision_()
898898
// If id_new not found in mapInfo remove it from m_tried_collisions
899899
if (mapInfo.count(id_new) != 1) {
900900
m_tried_collisions.erase(it);
901-
return CAddrInfo();
901+
return {};
902902
}
903903

904904
const CAddrInfo& newInfo = mapInfo[id_new];
@@ -907,9 +907,8 @@ CAddrInfo AddrManImpl::SelectTriedCollision_()
907907
int tried_bucket = newInfo.GetTriedBucket(nKey, m_asmap);
908908
int tried_bucket_pos = newInfo.GetBucketPosition(nKey, false, tried_bucket);
909909

910-
int id_old = vvTried[tried_bucket][tried_bucket_pos];
911-
912-
return mapInfo[id_old];
910+
const CAddrInfo& info_old = mapInfo[vvTried[tried_bucket][tried_bucket_pos]];
911+
return {info_old, info_old.nLastTry};
913912
}
914913

915914
void AddrManImpl::Check() const
@@ -1059,20 +1058,20 @@ void AddrManImpl::ResolveCollisions()
10591058
Check();
10601059
}
10611060

1062-
CAddrInfo AddrManImpl::SelectTriedCollision()
1061+
std::pair<CAddress, int64_t> AddrManImpl::SelectTriedCollision()
10631062
{
10641063
LOCK(cs);
10651064
Check();
1066-
const CAddrInfo ret = SelectTriedCollision_();
1065+
const auto ret = SelectTriedCollision_();
10671066
Check();
10681067
return ret;
10691068
}
10701069

1071-
CAddrInfo AddrManImpl::Select(bool newOnly) const
1070+
std::pair<CAddress, int64_t> AddrManImpl::Select(bool newOnly) const
10721071
{
10731072
LOCK(cs);
10741073
Check();
1075-
const CAddrInfo addrRet = Select_(newOnly);
1074+
const auto addrRet = Select_(newOnly);
10761075
Check();
10771076
return addrRet;
10781077
}
@@ -1159,12 +1158,12 @@ void CAddrMan::ResolveCollisions()
11591158
m_impl->ResolveCollisions();
11601159
}
11611160

1162-
CAddrInfo CAddrMan::SelectTriedCollision()
1161+
std::pair<CAddress, int64_t> CAddrMan::SelectTriedCollision()
11631162
{
11641163
return m_impl->SelectTriedCollision();
11651164
}
11661165

1167-
CAddrInfo CAddrMan::Select(bool newOnly) const
1166+
std::pair<CAddress, int64_t> CAddrMan::Select(bool newOnly) const
11681167
{
11691168
return m_impl->Select(newOnly);
11701169
}

src/addrman.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,13 +171,23 @@ class CAddrMan
171171
//! See if any to-be-evicted tried table entries have been tested and if so resolve the collisions.
172172
void ResolveCollisions();
173173

174-
//! Randomly select an address in tried that another address is attempting to evict.
175-
CAddrInfo SelectTriedCollision();
174+
/**
175+
* Randomly select an address in the tried table that another address is
176+
* attempting to evict.
177+
*
178+
* @return CAddress The record for the selected tried peer.
179+
* int64_t The last time we attempted to connect to that peer.
180+
*/
181+
std::pair<CAddress, int64_t> SelectTriedCollision();
176182

177183
/**
178184
* Choose an address to connect to.
185+
*
186+
* @param[in] newOnly Whether to only select addresses from the new table.
187+
* @return CAddress The record for the selected peer.
188+
* int64_t The last time we attempted to connect to that peer.
179189
*/
180-
CAddrInfo Select(bool newOnly = false) const;
190+
std::pair<CAddress, int64_t> Select(bool newOnly = false) const;
181191

182192
/**
183193
* Return all or many randomly selected addresses, optionally by network.

src/addrman_impl.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ class AddrManImpl
3131

3232
void ResolveCollisions() EXCLUSIVE_LOCKS_REQUIRED(!cs);
3333

34-
CAddrInfo SelectTriedCollision() EXCLUSIVE_LOCKS_REQUIRED(!cs);
34+
std::pair<CAddress, int64_t> SelectTriedCollision() EXCLUSIVE_LOCKS_REQUIRED(!cs);
3535

36-
CAddrInfo Select(bool newOnly) const
36+
std::pair<CAddress, int64_t> Select(bool newOnly) const
3737
EXCLUSIVE_LOCKS_REQUIRED(!cs);
3838

3939
std::vector<CAddress> GetAddr(size_t max_addresses, size_t max_pct, std::optional<Network> network) const
@@ -161,7 +161,7 @@ class AddrManImpl
161161
void Attempt_(const CService &addr, bool fCountFailure, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs);
162162

163163
//! Select an address to connect to, if newOnly is set to true, only the new table is selected from.
164-
CAddrInfo Select_(bool newOnly) const EXCLUSIVE_LOCKS_REQUIRED(cs);
164+
std::pair<CAddress, int64_t> Select_(bool newOnly) const EXCLUSIVE_LOCKS_REQUIRED(cs);
165165

166166
/**
167167
* Return all or many randomly selected addresses, optionally by network.
@@ -193,7 +193,7 @@ class AddrManImpl
193193
void ResolveCollisions_() EXCLUSIVE_LOCKS_REQUIRED(cs);
194194

195195
//! Return a random to-be-evicted tried table address.
196-
CAddrInfo SelectTriedCollision_() EXCLUSIVE_LOCKS_REQUIRED(cs);
196+
std::pair<CAddress, int64_t> SelectTriedCollision_() EXCLUSIVE_LOCKS_REQUIRED(cs);
197197

198198
//! Consistency check, taking into account m_consistency_check_ratio. Will std::abort if an inconsistency is detected.
199199
void Check() const EXCLUSIVE_LOCKS_REQUIRED(cs);

src/bench/addrman.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ static void AddrManSelect(benchmark::Bench& bench)
8787

8888
bench.run([&] {
8989
const auto& address = addrman.Select();
90-
assert(address.GetPort() > 0);
90+
assert(address.first.GetPort() > 0);
9191
});
9292
}
9393

src/net.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2006,17 +2006,18 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
20062006
if (nTries > 100)
20072007
break;
20082008

2009-
CAddrInfo addr;
2009+
CAddress addr;
2010+
int64_t addr_last_try{0};
20102011

20112012
if (fFeeler) {
20122013
// First, try to get a tried table collision address. This returns
20132014
// an empty (invalid) address if there are no collisions to try.
2014-
addr = addrman.SelectTriedCollision();
2015+
std::tie(addr, addr_last_try) = addrman.SelectTriedCollision();
20152016

20162017
if (!addr.IsValid()) {
20172018
// No tried table collisions. Select a new table address
20182019
// for our feeler.
2019-
addr = addrman.Select(true);
2020+
std::tie(addr, addr_last_try) = addrman.Select(true);
20202021
} else if (AlreadyConnectedToAddress(addr)) {
20212022
// If test-before-evict logic would have us connect to a
20222023
// peer that we're already connected to, just mark that
@@ -2025,11 +2026,11 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
20252026
// a currently-connected peer.
20262027
addrman.Good(addr);
20272028
// Select a new table address for our feeler instead.
2028-
addr = addrman.Select(true);
2029+
std::tie(addr, addr_last_try) = addrman.Select(true);
20292030
}
20302031
} else {
20312032
// Not a feeler
2032-
addr = addrman.Select();
2033+
std::tie(addr, addr_last_try) = addrman.Select();
20332034
}
20342035

20352036
// Require outbound connections, other than feelers, to be to distinct network groups
@@ -2046,7 +2047,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
20462047
continue;
20472048

20482049
// only consider very recently tried nodes after 30 failed attempts
2049-
if (nANow - addr.nLastTry < 600 && nTries < 30)
2050+
if (nANow - addr_last_try < 600 && nTries < 30)
20502051
continue;
20512052

20522053
// for non-feelers, require all the services we'll want,

0 commit comments

Comments
 (0)