aboutsummaryrefslogtreecommitdiff
path: root/src/addrman.h
diff options
context:
space:
mode:
authorJohn Newbery <john@johnnewbery.com>2020-12-03 10:54:57 +0000
committerJohn Newbery <john@johnnewbery.com>2021-01-18 13:23:16 +0000
commitb4c5fda417dd9ff8bf9fe24a87d384a649e3730d (patch)
tree8f8bddc6fe9dabcf4474892efb607ab03ae2e67b /src/addrman.h
parent7acda55c4fa611481979a41dfd5ca016bb535409 (diff)
downloadbitcoin-b4c5fda417dd9ff8bf9fe24a87d384a649e3730d.tar.xz
[addrman] Fix new table bucketing during unserialization
An addrman entry can appear in up to 8 new table buckets. We store this entry->bucket indexing during shutdown so that on restart we can restore the entries to their correct buckets. Commit ec45646de9e62b3d42c85716bfeb06d8f2b507dc broke the deserialization code so that each entry could only be put in up to one new bucket. Fix that.
Diffstat (limited to 'src/addrman.h')
-rw-r--r--src/addrman.h13
1 files changed, 8 insertions, 5 deletions
diff --git a/src/addrman.h b/src/addrman.h
index 9ac67b7af6..bcf36d9b3f 100644
--- a/src/addrman.h
+++ b/src/addrman.h
@@ -500,7 +500,9 @@ public:
nTried -= nLost;
// Store positions in the new table buckets to apply later (if possible).
- std::map<int, int> entryToBucket; // Represents which entry belonged to which bucket when serializing
+ // An entry may appear in up to ADDRMAN_NEW_BUCKETS_PER_ADDRESS buckets,
+ // so we store all bucket-entry_index pairs to iterate through later.
+ std::vector<std::pair<int, int>> bucket_entries;
for (int bucket = 0; bucket < nUBuckets; bucket++) {
int nSize = 0;
@@ -509,7 +511,7 @@ public:
int nIndex = 0;
s >> nIndex;
if (nIndex >= 0 && nIndex < nNew) {
- entryToBucket[nIndex] = bucket;
+ bucket_entries.emplace_back(bucket, nIndex);
}
}
}
@@ -523,9 +525,10 @@ public:
s >> serialized_asmap_version;
}
- for (int n = 0; n < nNew; n++) {
- CAddrInfo &info = mapInfo[n];
- int bucket = entryToBucket[n];
+ for (auto bucket_entry : bucket_entries) {
+ int bucket{bucket_entry.first};
+ const int n{bucket_entry.second};
+ CAddrInfo& info = mapInfo[n];
int nUBucketPos = info.GetBucketPosition(nKey, true, bucket);
if (format >= Format::V2_ASMAP && nUBuckets == ADDRMAN_NEW_BUCKET_COUNT && vvNew[bucket][nUBucketPos] == -1 &&
info.nRefCount < ADDRMAN_NEW_BUCKETS_PER_ADDRESS && serialized_asmap_version == supplied_asmap_version) {