Skip to content

Commit f40cb71

Browse files
MarcoFalkePastaPastaPasta
authored andcommitted
(partial) Merge bitcoin#21940: refactor: Mark CAddrMan::Select and GetAddr const
fae108c Fix incorrect whitespace in addrman (MarcoFalke) fa32024 Add missing GUARDED_BY to CAddrMan::insecure_rand (MarcoFalke) fab755b fuzz: Actually use const addrman (MarcoFalke) fae0c79 refactor: Mark CAddrMan::GetAddr const (MarcoFalke) fa02934 refactor: Mark CAddrMan::Select const (MarcoFalke) Pull request description: To clarify that a call to this only changes the random state and nothing else. ACKs for top commit: jnewbery: Code review ACK fae108c theStack: re-ACK fae108c 🍦 Tree-SHA512: 3ffb211d4715cc3daeb3bfcdb3fcc6b108ca96df5fa565510436fac0e8da86c93b30c9c4aad0563e27d84f615fcd729481072009a4e2360c8b3d40787ab6506a
1 parent 63b9071 commit f40cb71

File tree

5 files changed

+44
-35
lines changed

5 files changed

+44
-35
lines changed

src/addrman.cpp

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ CAddrInfo* CAddrMan::Create(const CAddress& addr, const CNetAddr& addrSource, in
144144
return &mapInfo[nId];
145145
}
146146

147-
void CAddrMan::SwapRandom(unsigned int nRndPos1, unsigned int nRndPos2)
147+
void CAddrMan::SwapRandom(unsigned int nRndPos1, unsigned int nRndPos2) const
148148
{
149149
AssertLockHeld(cs);
150150

@@ -156,11 +156,13 @@ void CAddrMan::SwapRandom(unsigned int nRndPos1, unsigned int nRndPos2)
156156
int nId1 = vRandom[nRndPos1];
157157
int nId2 = vRandom[nRndPos2];
158158

159-
assert(mapInfo.count(nId1) == 1);
160-
assert(mapInfo.count(nId2) == 1);
159+
const auto it_1{mapInfo.find(nId1)};
160+
const auto it_2{mapInfo.find(nId2)};
161+
assert(it_1 != mapInfo.end());
162+
assert(it_2 != mapInfo.end());
161163

162-
mapInfo[nId1].nRandomPos = nRndPos2;
163-
mapInfo[nId2].nRandomPos = nRndPos1;
164+
it_1->second.nRandomPos = nRndPos2;
165+
it_2->second.nRandomPos = nRndPos1;
164166

165167
vRandom[nRndPos1] = nId2;
166168
vRandom[nRndPos2] = nId1;
@@ -425,7 +427,7 @@ void CAddrMan::Attempt_(const CService& addr, bool fCountFailure, int64_t nTime)
425427
}
426428
}
427429

428-
CAddrInfo CAddrMan::Select_(bool newOnly)
430+
CAddrInfo CAddrMan::Select_(bool newOnly) const
429431
{
430432
AssertLockHeld(cs);
431433

@@ -448,8 +450,9 @@ CAddrInfo CAddrMan::Select_(bool newOnly)
448450
nKBucketPos = (nKBucketPos + insecure_rand.randbits(ADDRMAN_BUCKET_SIZE_LOG2)) % ADDRMAN_BUCKET_SIZE;
449451
}
450452
int nId = vvTried[nKBucket][nKBucketPos];
451-
assert(mapInfo.count(nId) == 1);
452-
CAddrInfo& info = mapInfo[nId];
453+
const auto it_found{mapInfo.find(nId)};
454+
assert(it_found != mapInfo.end());
455+
const CAddrInfo& info{it_found->second};
453456
if (insecure_rand.randbits(30) < fChanceFactor * info.GetChance() * (1 << 30))
454457
return info;
455458
fChanceFactor *= 1.2;
@@ -465,8 +468,9 @@ CAddrInfo CAddrMan::Select_(bool newOnly)
465468
nUBucketPos = (nUBucketPos + insecure_rand.randbits(ADDRMAN_BUCKET_SIZE_LOG2)) % ADDRMAN_BUCKET_SIZE;
466469
}
467470
int nId = vvNew[nUBucket][nUBucketPos];
468-
assert(mapInfo.count(nId) == 1);
469-
CAddrInfo& info = mapInfo[nId];
471+
const auto it_found{mapInfo.find(nId)};
472+
assert(it_found != mapInfo.end());
473+
const CAddrInfo& info{it_found->second};
470474
if (insecure_rand.randbits(30) < fChanceFactor * info.GetChance() * (1 << 30))
471475
return info;
472476
fChanceFactor *= 1.2;
@@ -517,15 +521,15 @@ int CAddrMan::Check_()
517521

518522
for (int n = 0; n < ADDRMAN_TRIED_BUCKET_COUNT; n++) {
519523
for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
520-
if (vvTried[n][i] != -1) {
521-
if (!setTried.count(vvTried[n][i]))
522-
return -11;
523-
if (mapInfo[vvTried[n][i]].GetTriedBucket(nKey, m_asmap) != n)
524-
return -17;
525-
if (mapInfo[vvTried[n][i]].GetBucketPosition(nKey, false, n) != i)
526-
return -18;
527-
setTried.erase(vvTried[n][i]);
528-
}
524+
if (vvTried[n][i] != -1) {
525+
if (!setTried.count(vvTried[n][i]))
526+
return -11;
527+
if (mapInfo[vvTried[n][i]].GetTriedBucket(nKey, m_asmap) != n)
528+
return -17;
529+
if (mapInfo[vvTried[n][i]].GetBucketPosition(nKey, false, n) != i)
530+
return -18;
531+
setTried.erase(vvTried[n][i]);
532+
}
529533
}
530534
}
531535

@@ -553,7 +557,7 @@ int CAddrMan::Check_()
553557
}
554558
#endif
555559

556-
void CAddrMan::GetAddr_(std::vector<CAddress>& vAddr, size_t max_addresses, size_t max_pct, std::optional<Network> network)
560+
void CAddrMan::GetAddr_(std::vector<CAddress>& vAddr, size_t max_addresses, size_t max_pct, std::optional<Network> network) const
557561
{
558562
AssertLockHeld(cs);
559563

@@ -573,9 +577,10 @@ void CAddrMan::GetAddr_(std::vector<CAddress>& vAddr, size_t max_addresses, size
573577

574578
int nRndPos = insecure_rand.randrange(vRandom.size() - n) + n;
575579
SwapRandom(n, nRndPos);
576-
assert(mapInfo.count(vRandom[n]) == 1);
580+
const auto it{mapInfo.find(vRandom[n])};
581+
assert(it != mapInfo.end());
577582

578-
const CAddrInfo& ai = mapInfo[vRandom[n]];
583+
const CAddrInfo& ai{it->second};
579584

580585
// Filter by network (optional)
581586
if (network != std::nullopt && ai.GetNetClass() != network) continue;

src/addrman.h

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class CAddrInfo : public CAddress
5555
bool fInTried{false};
5656

5757
//! position in vRandom
58-
int nRandomPos{-1};
58+
mutable int nRandomPos{-1};
5959

6060
friend class CAddrMan;
6161

@@ -587,7 +587,7 @@ class CAddrMan
587587
/**
588588
* Choose an address to connect to.
589589
*/
590-
CAddrInfo Select(bool newOnly = false)
590+
CAddrInfo Select(bool newOnly = false) const
591591
EXCLUSIVE_LOCKS_REQUIRED(!cs)
592592
{
593593
LOCK(cs);
@@ -604,7 +604,7 @@ class CAddrMan
604604
* @param[in] max_pct Maximum percentage of addresses to return (0 = all).
605605
* @param[in] network Select only addresses of this network (nullopt = all).
606606
*/
607-
std::vector<CAddress> GetAddr(size_t max_addresses, size_t max_pct, std::optional<Network> network)
607+
std::vector<CAddress> GetAddr(size_t max_addresses, size_t max_pct, std::optional<Network> network) const
608608
EXCLUSIVE_LOCKS_REQUIRED(!cs)
609609
{
610610
LOCK(cs);
@@ -650,12 +650,12 @@ class CAddrMan
650650
uint256 nKey;
651651

652652
//! Source of random numbers for randomization in inner loops
653-
FastRandomContext insecure_rand;
653+
mutable FastRandomContext insecure_rand GUARDED_BY(cs);
654654

655-
private:
656655
//! A mutex to protect the inner data structures.
657656
mutable Mutex cs;
658657

658+
private:
659659
//! Serialization versions.
660660
enum Format : uint8_t {
661661
V0_HISTORICAL = 0, //!< historic format, before commit e6b343d88
@@ -688,7 +688,9 @@ class CAddrMan
688688
std::map<CService, int> mapAddr GUARDED_BY(cs);
689689

690690
//! randomly-ordered vector of all nIds
691-
std::vector<int> vRandom GUARDED_BY(cs);
691+
//! This is mutable because it is unobservable outside the class, so any
692+
//! changes to it (even in const methods) are also unobservable.
693+
mutable std::vector<int> vRandom GUARDED_BY(cs);
692694

693695
// number of "tried" entries
694696
int nTried GUARDED_BY(cs);
@@ -718,7 +720,7 @@ class CAddrMan
718720
CAddrInfo* Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs);
719721

720722
//! Swap two elements in vRandom.
721-
void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2) EXCLUSIVE_LOCKS_REQUIRED(cs);
723+
void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2) const EXCLUSIVE_LOCKS_REQUIRED(cs);
722724

723725
//! Move an entry from the "new" table(s) to the "tried" table
724726
void MakeTried(CAddrInfo& info, int nId) EXCLUSIVE_LOCKS_REQUIRED(cs);
@@ -739,7 +741,7 @@ class CAddrMan
739741
void Attempt_(const CService &addr, bool fCountFailure, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs);
740742

741743
//! Select an address to connect to, if newOnly is set to true, only the new table is selected from.
742-
CAddrInfo Select_(bool newOnly) EXCLUSIVE_LOCKS_REQUIRED(cs);
744+
CAddrInfo Select_(bool newOnly) const EXCLUSIVE_LOCKS_REQUIRED(cs);
743745

744746
//! See if any to-be-evicted tried table entries have been tested and if so resolve the collisions.
745747
void ResolveCollisions_() EXCLUSIVE_LOCKS_REQUIRED(cs);
@@ -748,7 +750,7 @@ class CAddrMan
748750
CAddrInfo SelectTriedCollision_() EXCLUSIVE_LOCKS_REQUIRED(cs);
749751

750752
//! Consistency check
751-
void Check()
753+
void Check() const
752754
EXCLUSIVE_LOCKS_REQUIRED(cs)
753755
{
754756
#ifdef DEBUG_ADDRMAN
@@ -762,7 +764,7 @@ class CAddrMan
762764

763765
#ifdef DEBUG_ADDRMAN
764766
//! Perform consistency check. Returns an error code or zero.
765-
int Check_() EXCLUSIVE_LOCKS_REQUIRED(cs);
767+
int Check_() const EXCLUSIVE_LOCKS_REQUIRED(cs);
766768
#endif
767769

768770
/**
@@ -773,7 +775,7 @@ class CAddrMan
773775
* @param[in] max_pct Maximum percentage of addresses to return (0 = all).
774776
* @param[in] network Select only addresses of this network (nullopt = all).
775777
*/
776-
void GetAddr_(std::vector<CAddress>& vAddr, size_t max_addresses, size_t max_pct, std::optional<Network> network) EXCLUSIVE_LOCKS_REQUIRED(cs);
778+
void GetAddr_(std::vector<CAddress>& vAddr, size_t max_addresses, size_t max_pct, std::optional<Network> network) const EXCLUSIVE_LOCKS_REQUIRED(cs);
777779

778780
/** We have successfully connected to this peer. Calling this function
779781
* updates the CAddress's nTime, which is used in our IsTerrible()

src/test/addrman_tests.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class CAddrManTest : public CAddrMan
3535
//! Ensure that bucket placement is always the same for testing purposes.
3636
void MakeDeterministic()
3737
{
38+
LOCK(cs);
3839
nKey.SetNull();
3940
insecure_rand = FastRandomContext(true);
4041
}
@@ -88,11 +89,11 @@ class CAddrManTest : public CAddrMan
8889
{
8990
CAddrMan::Clear();
9091
if (deterministic) {
92+
LOCK(cs);
9193
nKey.SetNull();
9294
insecure_rand = FastRandomContext(true);
9395
}
9496
}
95-
9697
};
9798

9899
static CNetAddr ResolveIP(const std::string& ip)

src/test/fuzz/addrman.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class CAddrManDeterministic : public CAddrMan
2727
public:
2828
void MakeDeterministic(const uint256& random_seed)
2929
{
30-
insecure_rand = FastRandomContext{random_seed};
30+
WITH_LOCK(cs, insecure_rand = FastRandomContext{random_seed});
3131
Clear();
3232
}
3333
};

src/test/net_tests.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class CAddrManSerializationMock : public CAddrMan
3636
//! Ensure that bucket placement is always the same for testing purposes.
3737
void MakeDeterministic()
3838
{
39+
LOCK(cs);
3940
nKey.SetNull();
4041
insecure_rand = FastRandomContext(true);
4142
}

0 commit comments

Comments
 (0)