Skip to content

Commit 602c8eb

Browse files
committed
Merge bitcoin#22697: addrman: Remove CAddrMan::Clear() function
4d2fa97 [addrman] Clean up ctor (John Newbery) 7e6e659 [addrman] inline Clear() into CAddrMan ctor (John Newbery) 406be5f [addrman] Remove all public uses of CAddrMan.Clear() from the tests (John Newbery) ed9ba8a [tests] Remove CAddrMan.Clear() call from CAddrDB::Read() (John Newbery) e8e7392 [addrman] Don't call Clear() if parsing peers.dat fails (John Newbery) 181a120 [addrman] Move peers.dat parsing to init.cpp (John Newbery) Pull request description: `CAddrMan::Clear()` exists to reset the internal state of `CAddrMan`. It's currently used in two places: - on startup, if deserializing peers.dat fails, `Clear()` is called to reset to an empty addrman - in tests, `Clear()` is called to reset the addrman for more tests In both cases, we can simply destruct the `CAddrMan` and construct a new, empty addrman. That approach is safer - it's possible that `Clear()` could 'reset' the addrman to a state that's not equivalent to a freshly constructed addrman (one actual example of this is that `Clear()` does not clear the `m_tried_collisions` set). On the other hand, if we destruct and then construct a fresh addrman, we're guaranteed that the new object is empty. This wasn't possible when addrman was initially implemented, since it was a global, and so it would only be destructed on shutdown. However, addrman is now owned by `node.context`, so we have control over its destruction/construction. ACKs for top commit: laanwj: Code review ACK 4d2fa97 vasild: ACK 4d2fa97 Zero-1729: crACK 4d2fa97 Tree-SHA512: f715bf2cbff4f8c3a9dbc613f8c7f11846b065d6807faf3c7d346a0b0b29cbe7ce1dc0509465c2c9b88a8ad55299c9182ea53f5f743e47502a69a0f375e09408
2 parents 0263583 + 4d2fa97 commit 602c8eb

File tree

8 files changed

+98
-140
lines changed

8 files changed

+98
-140
lines changed

src/addrdb.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -244,12 +244,7 @@ bool CAddrDB::Read(CAddrMan& addr)
244244

245245
bool CAddrDB::Read(CAddrMan& addr, CDataStream& ssPeers)
246246
{
247-
bool ret = DeserializeDB(ssPeers, addr, false);
248-
if (!ret) {
249-
// Ensure addrman is left in a clean state
250-
addr.Clear();
251-
}
252-
return ret;
247+
return DeserializeDB(ssPeers, addr, false);
253248
}
254249

255250
void DumpAnchors(const fs::path& anchors_db_path, const std::vector<CAddress>& anchors)

src/addrman.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,23 @@ double CAddrInfo::GetChance(int64_t nNow) const
7777
return fChance;
7878
}
7979

80+
CAddrMan::CAddrMan(bool deterministic, int32_t consistency_check_ratio)
81+
: insecure_rand{deterministic}
82+
, nKey{deterministic ? uint256{1} : insecure_rand.rand256()}
83+
, m_consistency_check_ratio{consistency_check_ratio}
84+
{
85+
for (auto& bucket : vvNew) {
86+
for (auto& entry : bucket) {
87+
entry = -1;
88+
}
89+
}
90+
for (auto& bucket : vvTried) {
91+
for (auto& entry : bucket) {
92+
entry = -1;
93+
}
94+
}
95+
}
96+
8097
CAddrInfo* CAddrMan::Find(const CNetAddr& addr, int* pnId)
8198
{
8299
AssertLockHeld(cs);

src/addrman.h

Lines changed: 10 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -471,38 +471,7 @@ class CAddrMan
471471
Check();
472472
}
473473

474-
void Clear()
475-
EXCLUSIVE_LOCKS_REQUIRED(!cs)
476-
{
477-
LOCK(cs);
478-
std::vector<int>().swap(vRandom);
479-
nKey = insecure_rand.rand256();
480-
for (size_t bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) {
481-
for (size_t entry = 0; entry < ADDRMAN_BUCKET_SIZE; entry++) {
482-
vvNew[bucket][entry] = -1;
483-
}
484-
}
485-
for (size_t bucket = 0; bucket < ADDRMAN_TRIED_BUCKET_COUNT; bucket++) {
486-
for (size_t entry = 0; entry < ADDRMAN_BUCKET_SIZE; entry++) {
487-
vvTried[bucket][entry] = -1;
488-
}
489-
}
490-
491-
nIdCount = 0;
492-
nTried = 0;
493-
nNew = 0;
494-
nLastGood = 1; //Initially at 1 so that "never" is strictly worse.
495-
mapInfo.clear();
496-
mapAddr.clear();
497-
}
498-
499-
explicit CAddrMan(bool deterministic, int32_t consistency_check_ratio)
500-
: insecure_rand{deterministic},
501-
m_consistency_check_ratio{consistency_check_ratio}
502-
{
503-
Clear();
504-
if (deterministic) nKey = uint256{1};
505-
}
474+
explicit CAddrMan(bool deterministic, int32_t consistency_check_ratio);
506475

507476
~CAddrMan()
508477
{
@@ -624,17 +593,16 @@ class CAddrMan
624593
Check();
625594
}
626595

627-
protected:
628-
//! secret key to randomize bucket select with
629-
uint256 nKey;
630-
596+
private:
631597
//! A mutex to protect the inner data structures.
632598
mutable Mutex cs;
633599

634-
private:
635600
//! Source of random numbers for randomization in inner loops
636601
mutable FastRandomContext insecure_rand GUARDED_BY(cs);
637602

603+
//! secret key to randomize bucket select with
604+
uint256 nKey;
605+
638606
//! Serialization versions.
639607
enum Format : uint8_t {
640608
V0_HISTORICAL = 0, //!< historic format, before commit e6b343d88
@@ -658,7 +626,7 @@ class CAddrMan
658626
static constexpr uint8_t INCOMPATIBILITY_BASE = 32;
659627

660628
//! last used nId
661-
int nIdCount GUARDED_BY(cs);
629+
int nIdCount GUARDED_BY(cs){0};
662630

663631
//! table with information about all nIds
664632
std::unordered_map<int, CAddrInfo> mapInfo GUARDED_BY(cs);
@@ -672,19 +640,19 @@ class CAddrMan
672640
mutable std::vector<int> vRandom GUARDED_BY(cs);
673641

674642
// number of "tried" entries
675-
int nTried GUARDED_BY(cs);
643+
int nTried GUARDED_BY(cs){0};
676644

677645
//! list of "tried" buckets
678646
int vvTried[ADDRMAN_TRIED_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE] GUARDED_BY(cs);
679647

680648
//! number of (unique) "new" entries
681-
int nNew GUARDED_BY(cs);
649+
int nNew GUARDED_BY(cs){0};
682650

683651
//! list of "new" buckets
684652
int vvNew[ADDRMAN_NEW_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE] GUARDED_BY(cs);
685653

686-
//! last time Good was called (memory only)
687-
int64_t nLastGood GUARDED_BY(cs);
654+
//! last time Good was called (memory only). Initially set to 1 so that "never" is strictly worse.
655+
int64_t nLastGood GUARDED_BY(cs){1};
688656

689657
//! Holds addrs inserted into tried table that collide with existing entries. Test-before-evict discipline used to resolve these collisions.
690658
std::set<int> m_tried_collisions;

src/bench/addrman.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,9 @@ static void AddrManAdd(benchmark::Bench& bench)
7272
{
7373
CreateAddresses();
7474

75-
CAddrMan addrman(/* deterministic */ false, /* consistency_check_ratio */ 0);
76-
7775
bench.run([&] {
76+
CAddrMan addrman{/* deterministic */ false, /* consistency_check_ratio */ 0};
7877
AddAddressesToAddrMan(addrman);
79-
addrman.Clear();
8078
});
8179
}
8280

src/init.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,6 +1167,20 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
11671167
assert(!node.addrman);
11681168
auto check_addrman = std::clamp<int32_t>(args.GetArg("-checkaddrman", DEFAULT_ADDRMAN_CONSISTENCY_CHECKS), 0, 1000000);
11691169
node.addrman = std::make_unique<CAddrMan>(/* deterministic */ false, /* consistency_check_ratio */ check_addrman);
1170+
{
1171+
// Load addresses from peers.dat
1172+
uiInterface.InitMessage(_("Loading P2P addresses…").translated);
1173+
int64_t nStart = GetTimeMillis();
1174+
CAddrDB adb;
1175+
if (adb.Read(*node.addrman)) {
1176+
LogPrintf("Loaded %i addresses from peers.dat %dms\n", node.addrman->size(), GetTimeMillis() - nStart);
1177+
} else {
1178+
// Addrman can be in an inconsistent state after failure, reset it
1179+
node.addrman = std::make_unique<CAddrMan>(/* deterministic */ false, /* consistency_check_ratio */ check_addrman);
1180+
LogPrintf("Recreating peers.dat\n");
1181+
adb.Write(*node.addrman);
1182+
}
1183+
}
11701184
assert(!node.banman);
11711185
node.banman = std::make_unique<BanMan>(gArgs.GetDataDirNet() / "banlist", &uiInterface, args.GetArg("-bantime", DEFAULT_MISBEHAVING_BANTIME));
11721186
assert(!node.connman);

src/net.cpp

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2534,22 +2534,6 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
25342534
AddAddrFetch(strDest);
25352535
}
25362536

2537-
if (m_client_interface) {
2538-
m_client_interface->InitMessage(_("Loading P2P addresses…").translated);
2539-
}
2540-
// Load addresses from peers.dat
2541-
int64_t nStart = GetTimeMillis();
2542-
{
2543-
CAddrDB adb;
2544-
if (adb.Read(addrman))
2545-
LogPrintf("Loaded %i addresses from peers.dat %dms\n", addrman.size(), GetTimeMillis() - nStart);
2546-
else {
2547-
addrman.Clear(); // Addrman can be in an inconsistent state after failure, reset it
2548-
LogPrintf("Recreating peers.dat\n");
2549-
DumpAddresses();
2550-
}
2551-
}
2552-
25532537
if (m_use_addrman_outgoing) {
25542538
// Load addresses from anchors.dat
25552539
m_anchors = ReadAnchors(gArgs.GetDataDirNet() / ANCHORS_DATABASE_FILENAME);

0 commit comments

Comments
 (0)