Skip to content

Commit 28daf0d

Browse files
fanquakePastaPastaPasta
authored andcommitted
Merge bitcoin#22496: addrman: Remove addrman hotfixes
65332b1 [addrman] Remove RemoveInvalid() (John Newbery) Pull request description: PRs bitcoin#22179 and bitcoin#22112 (EDIT: later reverted in bitcoin#22497) added hotfix code to addrman to remove invalid addresses and mutate the ports of I2P entries after entering into addrman. Those hotfixes included at least two addrman data corruption bugs: - bitcoin#22467 (Assertion `nRndPos1 < vRandom.size() && nRndPos2 < vRandom.size()' failed) - bitcoin#22470 (Changing I2P ports in addrman may wronly skip some entries from "new" buckets) Hotfixing addrman is inherently dangerous. There are many members that have implicit assumptions on each others' state, and mutating those directly can lead to violating addrman's internal invariants. Instead of trying to hotfix addrman, just don't insert any invalid addresses. For now, those are addresses which fail `CNetAddr::IsValid()`. ACKs for top commit: sipa: utACK 65332b1. I tried to reason through scenarios that could introduce inconsistencies with this code, but can't find any. fanquake: ACK 65332b1 - Skipping the addition of invalid addresses (this code was initially added for Tor addrs) rather than adding all the invalids then removing them all when finishing unserializing seems like an improvement. Especially if it can be achieved with less code. Tree-SHA512: 023113764cb475572f15da7bf9824b62b79e10a7e359af2eee59017df354348d2aeed88de0fd4ad7a9f89a0dad10827f99d70af6f1cb20abb0eca2714689c8d7
1 parent 5945c37 commit 28daf0d

File tree

2 files changed

+7
-37
lines changed

2 files changed

+7
-37
lines changed

src/addrman.cpp

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -79,37 +79,6 @@ double CAddrInfo::GetChance(int64_t nNow) const
7979
return fChance;
8080
}
8181

82-
void CAddrMan::RemoveInvalid()
83-
{
84-
for (size_t bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; ++bucket) {
85-
for (size_t i = 0; i < ADDRMAN_BUCKET_SIZE; ++i) {
86-
const auto id = vvNew[bucket][i];
87-
if (id != -1 && !mapInfo[id].IsValid()) {
88-
ClearNew(bucket, i);
89-
}
90-
}
91-
}
92-
93-
for (size_t bucket = 0; bucket < ADDRMAN_TRIED_BUCKET_COUNT; ++bucket) {
94-
for (size_t i = 0; i < ADDRMAN_BUCKET_SIZE; ++i) {
95-
const auto id = vvTried[bucket][i];
96-
if (id == -1) {
97-
continue;
98-
}
99-
const auto& addr_info = mapInfo[id];
100-
if (addr_info.IsValid()) {
101-
continue;
102-
}
103-
vvTried[bucket][i] = -1;
104-
--nTried;
105-
SwapRandom(addr_info.nRandomPos, vRandom.size() - 1);
106-
vRandom.pop_back();
107-
mapAddr.erase(addr_info);
108-
mapInfo.erase(id);
109-
m_tried_collisions.erase(id);
110-
}
111-
}
112-
}
11382

11483
CAddrInfo* CAddrMan::Find(const CService& addr, int* pnId)
11584
{

src/addrman.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,8 @@ class CAddrMan
371371
s >> info;
372372
int nKBucket = info.GetTriedBucket(nKey, m_asmap);
373373
int nKBucketPos = info.GetBucketPosition(nKey, false, nKBucket);
374-
if (vvTried[nKBucket][nKBucketPos] == -1) {
374+
if (info.IsValid()
375+
&& vvTried[nKBucket][nKBucketPos] == -1) {
375376
info.nRandomPos = vRandom.size();
376377
info.fInTried = true;
377378
vRandom.push_back(nIdCount);
@@ -425,6 +426,9 @@ class CAddrMan
425426
const int entry_index{bucket_entry.second};
426427
CAddrInfo& info = mapInfo[entry_index];
427428

429+
// Don't store the entry in the new bucket if it's not a valid address for our addrman
430+
if (!info.IsValid()) continue;
431+
428432
// The entry shouldn't appear in more than
429433
// ADDRMAN_NEW_BUCKETS_PER_ADDRESS. If it has already, just skip
430434
// this bucket_entry.
@@ -447,7 +451,7 @@ class CAddrMan
447451
}
448452
}
449453

450-
// Prune new entries with refcount 0 (as a result of collisions).
454+
// Prune new entries with refcount 0 (as a result of collisions or invalid address).
451455
int nLostUnk = 0;
452456
for (auto it = mapInfo.cbegin(); it != mapInfo.cend(); ) {
453457
if (it->second.fInTried == false && it->second.nRefCount == 0) {
@@ -459,10 +463,9 @@ class CAddrMan
459463
}
460464
}
461465
if (nLost + nLostUnk > 0) {
462-
LogPrint(BCLog::ADDRMAN, "addrman lost %i new and %i tried addresses due to collisions\n", nLostUnk, nLost);
466+
LogPrint(BCLog::ADDRMAN, "addrman lost %i new and %i tried addresses due to collisions or invalid addresses\n", nLostUnk, nLost);
463467
}
464468

465-
RemoveInvalid();
466469

467470
Check();
468471
}
@@ -795,8 +798,6 @@ class CAddrMan
795798
//! Get address info for address
796799
CAddrInfo GetAddressInfo_(const CService& addr) EXCLUSIVE_LOCKS_REQUIRED(cs);
797800

798-
//! Remove invalid addresses.
799-
void RemoveInvalid() EXCLUSIVE_LOCKS_REQUIRED(cs);
800801

801802
friend class CAddrManTest;
802803
friend class CAddrManDeterministic;

0 commit comments

Comments
 (0)