Skip to content

Commit dad5f76

Browse files
addrman: Introduce a test-only function to lookup addresses
Co-Authored-By: Martin Zumsande <[email protected]>
1 parent 7551ae8 commit dad5f76

File tree

3 files changed

+76
-0
lines changed

3 files changed

+76
-0
lines changed

src/addrman.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,29 @@ std::pair<CAddress, int64_t> AddrManImpl::SelectTriedCollision_()
930930
return {info_old, info_old.nLastTry};
931931
}
932932

933+
std::optional<AddressPosition> AddrManImpl::FindAddressEntry_(const CAddress& addr)
934+
{
935+
AssertLockHeld(cs);
936+
937+
AddrInfo* addr_info = Find(addr);
938+
939+
if (!addr_info) return std::nullopt;
940+
941+
if(addr_info->fInTried) {
942+
int bucket{addr_info->GetTriedBucket(nKey, m_asmap)};
943+
return AddressPosition(/*tried=*/true,
944+
/*multiplicity=*/1,
945+
/*bucket=*/bucket,
946+
/*position=*/addr_info->GetBucketPosition(nKey, false, bucket));
947+
} else {
948+
int bucket{addr_info->GetNewBucket(nKey, m_asmap)};
949+
return AddressPosition(/*tried=*/false,
950+
/*multiplicity=*/addr_info->nRefCount,
951+
/*bucket=*/bucket,
952+
/*position=*/addr_info->GetBucketPosition(nKey, true, bucket));
953+
}
954+
}
955+
933956
void AddrManImpl::Check() const
934957
{
935958
AssertLockHeld(cs);
@@ -1116,6 +1139,15 @@ void AddrManImpl::SetServices(const CService& addr, ServiceFlags nServices)
11161139
Check();
11171140
}
11181141

1142+
std::optional<AddressPosition> AddrManImpl::FindAddressEntry(const CAddress& addr)
1143+
{
1144+
LOCK(cs);
1145+
Check();
1146+
auto entry = FindAddressEntry_(addr);
1147+
Check();
1148+
return entry;
1149+
}
1150+
11191151
const std::vector<bool>& AddrManImpl::GetAsmap() const
11201152
{
11211153
return m_asmap;
@@ -1201,3 +1233,8 @@ const std::vector<bool>& AddrMan::GetAsmap() const
12011233
{
12021234
return m_impl->GetAsmap();
12031235
}
1236+
1237+
std::optional<AddressPosition> AddrMan::FindAddressEntry(const CAddress& addr)
1238+
{
1239+
return m_impl->FindAddressEntry(addr);
1240+
}

src/addrman.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,31 @@ class AddrManImpl;
2222
/** Default for -checkaddrman */
2323
static constexpr int32_t DEFAULT_ADDRMAN_CONSISTENCY_CHECKS{0};
2424

25+
/** Test-only struct, capturing info about an address in AddrMan */
26+
struct AddressPosition {
27+
// Whether the address is in the new or tried table
28+
const bool tried;
29+
30+
// Addresses in the tried table should always have a multiplicity of 1.
31+
// Addresses in the new table can have multiplicity between 1 and
32+
// ADDRMAN_NEW_BUCKETS_PER_ADDRESS
33+
const int multiplicity;
34+
35+
// If the address is in the new table, the bucket and position are
36+
// populated based on the first source who sent the address.
37+
// In certain edge cases, this may not be where the address is currently
38+
// located.
39+
const int bucket;
40+
const int position;
41+
42+
bool operator==(AddressPosition other) {
43+
return std::tie(tried, multiplicity, bucket, position) ==
44+
std::tie(other.tried, other.multiplicity, other.bucket, other.position);
45+
}
46+
explicit AddressPosition(bool tried_in, int multiplicity_in, int bucket_in, int position_in)
47+
: tried{tried_in}, multiplicity{multiplicity_in}, bucket{bucket_in}, position{position_in} {}
48+
};
49+
2550
/** Stochastic address manager
2651
*
2752
* Design goals:
@@ -142,6 +167,15 @@ class AddrMan
142167
void SetServices(const CService& addr, ServiceFlags nServices);
143168

144169
const std::vector<bool>& GetAsmap() const;
170+
171+
/** Test-only function
172+
* Find the address record in AddrMan and return information about its
173+
* position.
174+
* @param[in] addr The address record to look up.
175+
* @return Information about the address record in AddrMan
176+
* or nullopt if address is not found.
177+
*/
178+
std::optional<AddressPosition> FindAddressEntry(const CAddress& addr);
145179
};
146180

147181
#endif // BITCOIN_ADDRMAN_H

src/addrman_impl.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ class AddrManImpl
137137
void SetServices(const CService& addr, ServiceFlags nServices)
138138
EXCLUSIVE_LOCKS_REQUIRED(!cs);
139139

140+
std::optional<AddressPosition> FindAddressEntry(const CAddress& addr)
141+
EXCLUSIVE_LOCKS_REQUIRED(!cs);
142+
140143
const std::vector<bool>& GetAsmap() const;
141144

142145
friend class AddrManTest;
@@ -266,6 +269,8 @@ class AddrManImpl
266269

267270
std::pair<CAddress, int64_t> SelectTriedCollision_() EXCLUSIVE_LOCKS_REQUIRED(cs);
268271

272+
std::optional<AddressPosition> FindAddressEntry_(const CAddress& addr) EXCLUSIVE_LOCKS_REQUIRED(cs);
273+
269274
//! Consistency check, taking into account m_consistency_check_ratio.
270275
//! Will std::abort if an inconsistency is detected.
271276
void Check() const EXCLUSIVE_LOCKS_REQUIRED(cs);

0 commit comments

Comments
 (0)