Skip to content

Commit 2f60d9f

Browse files
author
MarcoFalke
committed
Merge bitcoin/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
2 parents bb60960 + fae108c commit 2f60d9f

File tree

5 files changed

+46
-37
lines changed

5 files changed

+46
-37
lines changed

src/addrman.cpp

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

141-
void CAddrMan::SwapRandom(unsigned int nRndPos1, unsigned int nRndPos2)
141+
void CAddrMan::SwapRandom(unsigned int nRndPos1, unsigned int nRndPos2) const
142142
{
143143
AssertLockHeld(cs);
144144

@@ -150,11 +150,13 @@ void CAddrMan::SwapRandom(unsigned int nRndPos1, unsigned int nRndPos2)
150150
int nId1 = vRandom[nRndPos1];
151151
int nId2 = vRandom[nRndPos2];
152152

153-
assert(mapInfo.count(nId1) == 1);
154-
assert(mapInfo.count(nId2) == 1);
153+
const auto it_1{mapInfo.find(nId1)};
154+
const auto it_2{mapInfo.find(nId2)};
155+
assert(it_1 != mapInfo.end());
156+
assert(it_2 != mapInfo.end());
155157

156-
mapInfo[nId1].nRandomPos = nRndPos2;
157-
mapInfo[nId2].nRandomPos = nRndPos1;
158+
it_1->second.nRandomPos = nRndPos2;
159+
it_2->second.nRandomPos = nRndPos1;
158160

159161
vRandom[nRndPos1] = nId2;
160162
vRandom[nRndPos2] = nId1;
@@ -410,7 +412,7 @@ void CAddrMan::Attempt_(const CService& addr, bool fCountFailure, int64_t nTime)
410412
}
411413
}
412414

413-
CAddrInfo CAddrMan::Select_(bool newOnly)
415+
CAddrInfo CAddrMan::Select_(bool newOnly) const
414416
{
415417
AssertLockHeld(cs);
416418

@@ -433,8 +435,9 @@ CAddrInfo CAddrMan::Select_(bool newOnly)
433435
nKBucketPos = (nKBucketPos + insecure_rand.randbits(ADDRMAN_BUCKET_SIZE_LOG2)) % ADDRMAN_BUCKET_SIZE;
434436
}
435437
int nId = vvTried[nKBucket][nKBucketPos];
436-
assert(mapInfo.count(nId) == 1);
437-
CAddrInfo& info = mapInfo[nId];
438+
const auto it_found{mapInfo.find(nId)};
439+
assert(it_found != mapInfo.end());
440+
const CAddrInfo& info{it_found->second};
438441
if (insecure_rand.randbits(30) < fChanceFactor * info.GetChance() * (1 << 30))
439442
return info;
440443
fChanceFactor *= 1.2;
@@ -450,8 +453,9 @@ CAddrInfo CAddrMan::Select_(bool newOnly)
450453
nUBucketPos = (nUBucketPos + insecure_rand.randbits(ADDRMAN_BUCKET_SIZE_LOG2)) % ADDRMAN_BUCKET_SIZE;
451454
}
452455
int nId = vvNew[nUBucket][nUBucketPos];
453-
assert(mapInfo.count(nId) == 1);
454-
CAddrInfo& info = mapInfo[nId];
456+
const auto it_found{mapInfo.find(nId)};
457+
assert(it_found != mapInfo.end());
458+
const CAddrInfo& info{it_found->second};
455459
if (insecure_rand.randbits(30) < fChanceFactor * info.GetChance() * (1 << 30))
456460
return info;
457461
fChanceFactor *= 1.2;
@@ -503,15 +507,15 @@ int CAddrMan::Check_()
503507

504508
for (int n = 0; n < ADDRMAN_TRIED_BUCKET_COUNT; n++) {
505509
for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
506-
if (vvTried[n][i] != -1) {
507-
if (!setTried.count(vvTried[n][i]))
508-
return -11;
509-
if (mapInfo[vvTried[n][i]].GetTriedBucket(nKey, m_asmap) != n)
510-
return -17;
511-
if (mapInfo[vvTried[n][i]].GetBucketPosition(nKey, false, n) != i)
512-
return -18;
513-
setTried.erase(vvTried[n][i]);
514-
}
510+
if (vvTried[n][i] != -1) {
511+
if (!setTried.count(vvTried[n][i]))
512+
return -11;
513+
if (mapInfo[vvTried[n][i]].GetTriedBucket(nKey, m_asmap) != n)
514+
return -17;
515+
if (mapInfo[vvTried[n][i]].GetBucketPosition(nKey, false, n) != i)
516+
return -18;
517+
setTried.erase(vvTried[n][i]);
518+
}
515519
}
516520
}
517521

@@ -539,7 +543,7 @@ int CAddrMan::Check_()
539543
}
540544
#endif
541545

542-
void CAddrMan::GetAddr_(std::vector<CAddress>& vAddr, size_t max_addresses, size_t max_pct, std::optional<Network> network)
546+
void CAddrMan::GetAddr_(std::vector<CAddress>& vAddr, size_t max_addresses, size_t max_pct, std::optional<Network> network) const
543547
{
544548
AssertLockHeld(cs);
545549

@@ -559,9 +563,10 @@ void CAddrMan::GetAddr_(std::vector<CAddress>& vAddr, size_t max_addresses, size
559563

560564
int nRndPos = insecure_rand.randrange(vRandom.size() - n) + n;
561565
SwapRandom(n, nRndPos);
562-
assert(mapInfo.count(vRandom[n]) == 1);
566+
const auto it{mapInfo.find(vRandom[n])};
567+
assert(it != mapInfo.end());
563568

564-
const CAddrInfo& ai = mapInfo[vRandom[n]];
569+
const CAddrInfo& ai{it->second};
565570

566571
// Filter by network (optional)
567572
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

@@ -579,7 +579,7 @@ class CAddrMan
579579
/**
580580
* Choose an address to connect to.
581581
*/
582-
CAddrInfo Select(bool newOnly = false)
582+
CAddrInfo Select(bool newOnly = false) const
583583
EXCLUSIVE_LOCKS_REQUIRED(!cs)
584584
{
585585
LOCK(cs);
@@ -596,7 +596,7 @@ class CAddrMan
596596
* @param[in] max_pct Maximum percentage of addresses to return (0 = all).
597597
* @param[in] network Select only addresses of this network (nullopt = all).
598598
*/
599-
std::vector<CAddress> GetAddr(size_t max_addresses, size_t max_pct, std::optional<Network> network)
599+
std::vector<CAddress> GetAddr(size_t max_addresses, size_t max_pct, std::optional<Network> network) const
600600
EXCLUSIVE_LOCKS_REQUIRED(!cs)
601601
{
602602
LOCK(cs);
@@ -631,12 +631,12 @@ class CAddrMan
631631
uint256 nKey;
632632

633633
//! Source of random numbers for randomization in inner loops
634-
FastRandomContext insecure_rand;
634+
mutable FastRandomContext insecure_rand GUARDED_BY(cs);
635635

636-
private:
637636
//! A mutex to protect the inner data structures.
638637
mutable Mutex cs;
639638

639+
private:
640640
//! Serialization versions.
641641
enum Format : uint8_t {
642642
V0_HISTORICAL = 0, //!< historic format, before commit e6b343d88
@@ -669,7 +669,9 @@ class CAddrMan
669669
std::unordered_map<CNetAddr, int, CNetAddrHash> mapAddr GUARDED_BY(cs);
670670

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

674676
// number of "tried" entries
675677
int nTried GUARDED_BY(cs);
@@ -697,7 +699,7 @@ class CAddrMan
697699
CAddrInfo* Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs);
698700

699701
//! Swap two elements in vRandom.
700-
void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2) EXCLUSIVE_LOCKS_REQUIRED(cs);
702+
void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2) const EXCLUSIVE_LOCKS_REQUIRED(cs);
701703

702704
//! Move an entry from the "new" table(s) to the "tried" table
703705
void MakeTried(CAddrInfo& info, int nId) EXCLUSIVE_LOCKS_REQUIRED(cs);
@@ -718,7 +720,7 @@ class CAddrMan
718720
void Attempt_(const CService &addr, bool fCountFailure, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs);
719721

720722
//! Select an address to connect to, if newOnly is set to true, only the new table is selected from.
721-
CAddrInfo Select_(bool newOnly) EXCLUSIVE_LOCKS_REQUIRED(cs);
723+
CAddrInfo Select_(bool newOnly) const EXCLUSIVE_LOCKS_REQUIRED(cs);
722724

723725
//! See if any to-be-evicted tried table entries have been tested and if so resolve the collisions.
724726
void ResolveCollisions_() EXCLUSIVE_LOCKS_REQUIRED(cs);
@@ -727,7 +729,7 @@ class CAddrMan
727729
CAddrInfo SelectTriedCollision_() EXCLUSIVE_LOCKS_REQUIRED(cs);
728730

729731
//! Consistency check
730-
void Check()
732+
void Check() const
731733
EXCLUSIVE_LOCKS_REQUIRED(cs)
732734
{
733735
#ifdef DEBUG_ADDRMAN
@@ -741,7 +743,7 @@ class CAddrMan
741743

742744
#ifdef DEBUG_ADDRMAN
743745
//! Perform consistency check. Returns an error code or zero.
744-
int Check_() EXCLUSIVE_LOCKS_REQUIRED(cs);
746+
int Check_() const EXCLUSIVE_LOCKS_REQUIRED(cs);
745747
#endif
746748

747749
/**
@@ -752,7 +754,7 @@ class CAddrMan
752754
* @param[in] max_pct Maximum percentage of addresses to return (0 = all).
753755
* @param[in] network Select only addresses of this network (nullopt = all).
754756
*/
755-
void GetAddr_(std::vector<CAddress>& vAddr, size_t max_addresses, size_t max_pct, std::optional<Network> network) EXCLUSIVE_LOCKS_REQUIRED(cs);
757+
void GetAddr_(std::vector<CAddress>& vAddr, size_t max_addresses, size_t max_pct, std::optional<Network> network) const EXCLUSIVE_LOCKS_REQUIRED(cs);
756758

757759
/** We have successfully connected to this peer. Calling this function
758760
* 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
@@ -34,6 +34,7 @@ class CAddrManTest : public CAddrMan
3434
//! Ensure that bucket placement is always the same for testing purposes.
3535
void MakeDeterministic()
3636
{
37+
LOCK(cs);
3738
nKey.SetNull();
3839
insecure_rand = FastRandomContext(true);
3940
}
@@ -87,11 +88,11 @@ class CAddrManTest : public CAddrMan
8788
{
8889
CAddrMan::Clear();
8990
if (deterministic) {
91+
LOCK(cs);
9092
nKey.SetNull();
9193
insecure_rand = FastRandomContext(true);
9294
}
9395
}
94-
9596
};
9697

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

src/test/fuzz/addrman.cpp

Lines changed: 3 additions & 3 deletions
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
};
@@ -114,11 +114,11 @@ FUZZ_TARGET_INIT(addrman, initialize_addrman)
114114
});
115115
}
116116
const CAddrMan& const_addr_man{addr_man};
117-
(void)/*const_*/addr_man.GetAddr(
117+
(void)const_addr_man.GetAddr(
118118
/* max_addresses */ fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096),
119119
/* max_pct */ fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096),
120120
/* network */ std::nullopt);
121-
(void)/*const_*/addr_man.Select(fuzzed_data_provider.ConsumeBool());
121+
(void)const_addr_man.Select(fuzzed_data_provider.ConsumeBool());
122122
(void)const_addr_man.size();
123123
CDataStream data_stream(SER_NETWORK, PROTOCOL_VERSION);
124124
data_stream << const_addr_man;

src/test/net_tests.cpp

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

0 commit comments

Comments
 (0)