6 #if defined(HAVE_CONFIG_H)
59 std::vector<unsigned char> vchSourceGroupKey = netgroupman.
GetGroup(src);
60 uint64_t hash1 = (
HashWriter{} << nKey << netgroupman.
GetGroup(*
this) << vchSourceGroupKey).GetCheapHash();
67 uint64_t hash1 = (
HashWriter{} << nKey << (fNew ? uint8_t{
'N'} : uint8_t{
'K'}) << bucket <<
GetKey()).GetCheapHash();
77 if (
nTime > now + 10min) {
106 fChance *= pow(0.66, std::min(
nAttempts, 8));
112 : insecure_rand{deterministic}
113 , nKey{deterministic ?
uint256{1} : insecure_rand.rand256()}
114 , m_consistency_check_ratio{consistency_check_ratio}
115 , m_netgroupman{netgroupman}
117 for (
auto& bucket : vvNew) {
118 for (
auto& entry : bucket) {
122 for (
auto& bucket : vvTried) {
123 for (
auto& entry : bucket) {
134 template <
typename Stream>
184 static constexpr uint8_t lowest_compatible = Format::V4_MULTIPORT;
193 std::unordered_map<int, int> mapUnkIds;
195 for (
const auto& entry : mapInfo) {
196 mapUnkIds[entry.first] = nIds;
197 const AddrInfo& info = entry.second;
205 for (
const auto& entry : mapInfo) {
206 const AddrInfo& info = entry.second;
216 if (vvNew[bucket][i] != -1)
221 if (vvNew[bucket][i] != -1) {
222 int nIndex = mapUnkIds[vvNew[bucket][i]];
232 template <
typename Stream>
240 s_ >> Using<CustomUintFormatter<1>>(
format);
249 "Corrupted addrman database: The compat value (%u) "
250 "is lower than the expected minimum value %u.",
256 "Unsupported format of addrman database: %u. It is compatible with formats >=%u, "
257 "but the maximum supported by this version of %s is %u.",
266 if (
format >= Format::V1_DETERMINISTIC) {
267 nUBuckets ^= (1 << 30);
271 throw std::ios_base::failure(
272 strprintf(
"Corrupt AddrMan serialization: nNew=%d, should be in [0, %d]",
278 throw std::ios_base::failure(
279 strprintf(
"Corrupt AddrMan serialization: nTried=%d, should be in [0, %d]",
285 for (
int n = 0; n < nNew; n++) {
290 vRandom.push_back(n);
297 for (
int n = 0; n < nTried; n++) {
303 && vvTried[nKBucket][nKBucketPos] == -1) {
306 vRandom.push_back(nIdCount);
307 mapInfo[nIdCount] = info;
308 mapAddr[info] = nIdCount;
309 vvTried[nKBucket][nKBucketPos] = nIdCount;
311 m_network_counts[info.
GetNetwork()].n_tried++;
321 std::vector<std::pair<int, int>> bucket_entries;
323 for (
int bucket = 0; bucket < nUBuckets; ++bucket) {
326 for (
int n = 0; n < num_entries; ++n) {
329 if (entry_index >= 0 && entry_index < nNew) {
330 bucket_entries.emplace_back(bucket, entry_index);
339 uint256 serialized_asmap_checksum;
340 if (
format >= Format::V2_ASMAP) {
341 s >> serialized_asmap_checksum;
344 serialized_asmap_checksum == supplied_asmap_checksum};
346 if (!restore_bucketing) {
350 for (
auto bucket_entry : bucket_entries) {
351 int bucket{bucket_entry.first};
352 const int entry_index{bucket_entry.second};
353 AddrInfo& info = mapInfo[entry_index];
364 if (restore_bucketing && vvNew[bucket][bucket_position] == -1) {
366 vvNew[bucket][bucket_position] = entry_index;
373 if (vvNew[bucket][bucket_position] == -1) {
374 vvNew[bucket][bucket_position] = entry_index;
382 for (
auto it = mapInfo.cbegin(); it != mapInfo.cend(); ) {
383 if (it->second.fInTried ==
false && it->second.nRefCount == 0) {
384 const auto itCopy = it++;
391 if (nLost + nLostUnk > 0) {
392 LogPrint(
BCLog::ADDRMAN,
"addrman lost %i new and %i tried addresses due to collisions or invalid addresses\n", nLostUnk, nLost);
396 if (check_code != 0) {
398 "Corrupt data. Consistency check failed with code %s",
407 const auto it = mapAddr.find(addr);
408 if (it == mapAddr.end())
411 *pnId = (*it).second;
412 const auto it2 = mapInfo.find((*it).second);
413 if (it2 != mapInfo.end())
414 return &(*it2).second;
422 int nId = nIdCount++;
423 mapInfo[nId] =
AddrInfo(addr, addrSource);
425 mapInfo[nId].nRandomPos = vRandom.size();
426 vRandom.push_back(nId);
431 return &mapInfo[nId];
438 if (nRndPos1 == nRndPos2)
441 assert(nRndPos1 < vRandom.size() && nRndPos2 < vRandom.size());
443 int nId1 = vRandom[nRndPos1];
444 int nId2 = vRandom[nRndPos2];
446 const auto it_1{mapInfo.find(nId1)};
447 const auto it_2{mapInfo.find(nId2)};
448 assert(it_1 != mapInfo.end());
449 assert(it_2 != mapInfo.end());
451 it_1->second.nRandomPos = nRndPos2;
452 it_2->second.nRandomPos = nRndPos1;
454 vRandom[nRndPos1] = nId2;
455 vRandom[nRndPos2] = nId1;
462 assert(mapInfo.count(nId) != 0);
480 if (vvNew[nUBucket][nUBucketPos] != -1) {
481 int nIdDelete = vvNew[nUBucket][nUBucketPos];
482 AddrInfo& infoDelete = mapInfo[nIdDelete];
485 vvNew[nUBucket][nUBucketPos] = -1;
502 if (vvNew[bucket][pos] == nId) {
503 vvNew[bucket][pos] = -1;
518 if (vvTried[nKBucket][nKBucketPos] != -1) {
520 int nIdEvict = vvTried[nKBucket][nKBucketPos];
521 assert(mapInfo.count(nIdEvict) == 1);
522 AddrInfo& infoOld = mapInfo[nIdEvict];
526 vvTried[nKBucket][nKBucketPos] = -1;
528 m_network_counts[infoOld.
GetNetwork()].n_tried--;
534 assert(vvNew[nUBucket][nUBucketPos] == -1);
538 vvNew[nUBucket][nUBucketPos] = nIdEvict;
540 m_network_counts[infoOld.
GetNetwork()].n_new++;
544 assert(vvTried[nKBucket][nKBucketPos] == -1);
546 vvTried[nKBucket][nKBucketPos] = nId;
549 m_network_counts[info.
GetNetwork()].n_tried++;
570 const auto update_interval{currently_online ? 1h : 24h};
571 if (pinfo->
nTime < addr.
nTime - update_interval - time_penalty) {
593 const int nFactor{1 << pinfo->
nRefCount};
594 if (insecure_rand.randrange(nFactor) != 0)
return false;
603 bool fInsert = vvNew[nUBucket][nUBucketPos] == -1;
604 if (vvNew[nUBucket][nUBucketPos] != nId) {
606 AddrInfo& infoExisting = mapInfo[vvNew[nUBucket][nUBucketPos]];
615 vvNew[nUBucket][nUBucketPos] = nId;
639 if (!pinfo)
return false;
662 if (test_before_evict && (vvTried[tried_bucket][tried_bucket_pos] != -1)) {
667 auto colliding_entry = mapInfo.find(vvTried[tried_bucket][tried_bucket_pos]);
669 colliding_entry != mapInfo.end() ? colliding_entry->second.ToStringAddrPort() :
"",
686 for (std::vector<CAddress>::const_iterator it = vAddr.begin(); it != vAddr.end(); it++) {
690 LogPrint(
BCLog::ADDRMAN,
"Added %i addresses (of %i) from %s: %i tried, %i new\n", added, vAddr.size(),
source.ToStringAddr(), nTried, nNew);
719 if (vRandom.empty())
return {};
721 size_t new_count = nNew;
722 size_t tried_count = nTried;
724 if (network.has_value()) {
725 auto it = m_network_counts.find(*network);
726 if (it == m_network_counts.end())
return {};
728 auto counts = it->second;
729 new_count = counts.n_new;
730 tried_count = counts.n_tried;
733 if (new_only && new_count == 0)
return {};
734 if (new_count + tried_count == 0)
return {};
739 if (new_only || tried_count == 0) {
740 search_tried =
false;
741 }
else if (new_count == 0) {
744 search_tried = insecure_rand.randbool();
750 double chance_factor = 1.0;
753 int bucket = insecure_rand.randrange(bucket_count);
758 int i, position, node_id;
761 node_id =
GetEntry(search_tried, bucket, position);
763 if (network.has_value()) {
764 const auto it{mapInfo.find(node_id)};
765 if (
Assume(it != mapInfo.end()) && it->second.GetNetwork() == *network)
break;
776 const auto it_found{mapInfo.find(node_id)};
777 assert(it_found != mapInfo.end());
778 const AddrInfo& info{it_found->second};
781 if (insecure_rand.randbits(30) < chance_factor * info.GetChance() * (1 << 30)) {
782 LogPrint(
BCLog::ADDRMAN,
"Selected %s from %s\n", info.ToStringAddrPort(), search_tried ?
"tried" :
"new");
783 return {info, info.m_last_try};
787 chance_factor *= 1.2;
797 return vvTried[bucket][position];
801 return vvNew[bucket][position];
808 std::vector<CAddress>
AddrManImpl::GetAddr_(
size_t max_addresses,
size_t max_pct, std::optional<Network> network,
const bool filtered)
const
812 size_t nNodes = vRandom.size();
814 nNodes = max_pct * nNodes / 100;
816 if (max_addresses != 0) {
817 nNodes = std::min(nNodes, max_addresses);
821 const auto now{Now<NodeSeconds>()};
822 std::vector<CAddress> addresses;
823 for (
unsigned int n = 0; n < vRandom.size(); n++) {
824 if (addresses.size() >= nNodes)
827 int nRndPos = insecure_rand.randrange(vRandom.size() - n) + n;
829 const auto it{mapInfo.find(vRandom[n])};
830 assert(it != mapInfo.end());
835 if (network != std::nullopt && ai.GetNetClass() != network)
continue;
838 if (ai.IsTerrible(now) && filtered)
continue;
840 addresses.push_back(ai);
851 std::vector<std::pair<AddrInfo, AddressPosition>> infos;
852 for (
int bucket = 0; bucket < bucket_count; ++bucket) {
854 int id =
GetEntry(from_tried, bucket, position);
862 infos.emplace_back(info, location);
883 const auto update_interval{20min};
884 if (time - info.
nTime > update_interval) {
912 bool erase_collision =
false;
915 if (mapInfo.count(id_new) != 1) {
916 erase_collision =
true;
918 AddrInfo& info_new = mapInfo[id_new];
924 erase_collision =
true;
925 }
else if (vvTried[tried_bucket][tried_bucket_pos] != -1) {
928 int id_old = vvTried[tried_bucket][tried_bucket_pos];
929 AddrInfo& info_old = mapInfo[id_old];
931 const auto current_time{Now<NodeSeconds>()};
935 erase_collision =
true;
939 if (current_time - info_old.
m_last_try > 60s) {
943 Good_(info_new,
false, current_time);
944 erase_collision =
true;
951 Good_(info_new,
false, current_time);
952 erase_collision =
true;
955 Good_(info_new,
false, Now<NodeSeconds>());
956 erase_collision =
true;
960 if (erase_collision) {
981 if (mapInfo.count(id_new) != 1) {
986 const AddrInfo& newInfo = mapInfo[id_new];
992 const AddrInfo& info_old = mapInfo[vvTried[tried_bucket][tried_bucket_pos]];
1002 if (!addr_info)
return std::nullopt;
1023 if (!net.has_value()) {
1024 if (in_new.has_value()) {
1025 return *in_new ? nNew : nTried;
1027 return vRandom.size();
1030 if (
auto it = m_network_counts.find(*net); it != m_network_counts.end()) {
1031 auto net_count = it->second;
1032 if (in_new.has_value()) {
1033 return *in_new ? net_count.n_new : net_count.n_tried;
1035 return net_count.n_new + net_count.n_tried;
1051 LogPrintf(
"ADDRMAN CONSISTENCY CHECK FAILED!!! err=%i\n", err);
1063 std::unordered_set<int> setTried;
1064 std::unordered_map<int, int> mapNew;
1065 std::unordered_map<Network, NewTriedCount> local_counts;
1067 if (vRandom.size() != (
size_t)(nTried + nNew))
1070 for (
const auto& entry : mapInfo) {
1071 int n = entry.first;
1072 const AddrInfo& info = entry.second;
1074 if (!TicksSinceEpoch<std::chrono::seconds>(info.
m_last_success)) {
1089 const auto it{mapAddr.find(info)};
1090 if (it == mapAddr.end() || it->second != n) {
1103 if (setTried.size() != (
size_t)nTried)
1105 if (mapNew.size() != (
size_t)nNew)
1110 if (vvTried[n][i] != -1) {
1111 if (!setTried.count(vvTried[n][i]))
1113 const auto it{mapInfo.find(vvTried[n][i])};
1114 if (it == mapInfo.end() || it->second.GetTriedBucket(
nKey,
m_netgroupman) != n) {
1117 if (it->second.GetBucketPosition(
nKey,
false, n) != i) {
1120 setTried.erase(vvTried[n][i]);
1127 if (vvNew[n][i] != -1) {
1128 if (!mapNew.count(vvNew[n][i]))
1130 const auto it{mapInfo.find(vvNew[n][i])};
1131 if (it == mapInfo.end() || it->second.GetBucketPosition(
nKey,
true, n) != i) {
1134 if (--mapNew[vvNew[n][i]] == 0)
1135 mapNew.erase(vvNew[n][i]);
1140 if (setTried.size())
1149 if (m_network_counts.size() < local_counts.size()) {
1152 for (
const auto& [net,
count] : m_network_counts) {
1153 if (local_counts[net].n_new !=
count.n_new || local_counts[net].n_tried !=
count.n_tried) {
1183 auto ret =
Good_(addr,
true, time);
1192 Attempt_(addr, fCountFailure, time);
1217 auto addrRet =
Select_(new_only, network);
1222 std::vector<CAddress>
AddrManImpl::GetAddr(
size_t max_addresses,
size_t max_pct, std::optional<Network> network,
const bool filtered)
const
1226 auto addresses =
GetAddr_(max_addresses, max_pct, network, filtered);
1266 : m_impl(
std::make_unique<
AddrManImpl>(netgroupman, deterministic, consistency_check_ratio)) {}
1270 template <
typename Stream>
1273 m_impl->Serialize<Stream>(s_);
1276 template <
typename Stream>
1279 m_impl->Unserialize<Stream>(s_);
1290 size_t AddrMan::Size(std::optional<Network> net, std::optional<bool> in_new)
const
1292 return m_impl->Size(net, in_new);
1302 return m_impl->Good(addr, time);
1307 m_impl->Attempt(addr, fCountFailure, time);
1312 m_impl->ResolveCollisions();
1317 return m_impl->SelectTriedCollision();
1320 std::pair<CAddress, NodeSeconds>
AddrMan::Select(
bool new_only, std::optional<Network> network)
const
1322 return m_impl->Select(new_only, network);
1325 std::vector<CAddress>
AddrMan::GetAddr(
size_t max_addresses,
size_t max_pct, std::optional<Network> network,
const bool filtered)
const
1327 return m_impl->GetAddr(max_addresses, max_pct, network, filtered);
1332 return m_impl->GetEntries(use_tried);
1337 m_impl->Connected(addr, time);
1342 m_impl->SetServices(addr, nServices);
1347 return m_impl->FindAddressEntry(addr);
static constexpr uint32_t ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP
Over how many buckets entries with new addresses originating from a single group are spread.
static constexpr auto ADDRMAN_HORIZON
How old addresses can maximally be.
static constexpr int32_t ADDRMAN_MAX_FAILURES
How many successive failures are allowed ...
static constexpr auto ADDRMAN_MIN_FAIL
...
static constexpr auto ADDRMAN_TEST_WINDOW
The maximum time we'll spend trying to resolve a tried table collision.
static constexpr auto ADDRMAN_REPLACEMENT
How recent a successful connection should be before we allow an address to be evicted from tried.
static constexpr int32_t ADDRMAN_RETRIES
After how many failed attempts we give up on a new node.
static constexpr size_t ADDRMAN_SET_TRIED_COLLISION_SIZE
The maximum number of tried addr collisions to store.
static constexpr uint32_t ADDRMAN_TRIED_BUCKETS_PER_GROUP
Over how many buckets entries with tried addresses from a single group (/16 for IPv4) are spread.
static constexpr int32_t ADDRMAN_NEW_BUCKETS_PER_ADDRESS
Maximum number of times an address can occur in the new table.
static constexpr int ADDRMAN_TRIED_BUCKET_COUNT
static constexpr int ADDRMAN_BUCKET_SIZE
static constexpr int ADDRMAN_NEW_BUCKET_COUNT
#define Assume(val)
Assume is the identity function.
Extended statistics about a CAddress.
int GetNewBucket(const uint256 &nKey, const CNetAddr &src, const NetGroupManager &netgroupman) const
Calculate in which "new" bucket this entry belongs, given a certain source.
int GetTriedBucket(const uint256 &nKey, const NetGroupManager &netgroupman) const
Calculate in which "tried" bucket this entry belongs.
int nRandomPos
position in vRandom
int GetBucketPosition(const uint256 &nKey, bool fNew, int bucket) const
Calculate in which position of a bucket to store this entry.
bool fInTried
in tried set? (memory only)
NodeSeconds m_last_success
last successful connection by us
NodeSeconds m_last_count_attempt
last counted attempt (memory only)
NodeSeconds m_last_try
last try whatsoever by us (memory only)
double GetChance(NodeSeconds now=Now< NodeSeconds >()) const
Calculate the relative chance this entry should be given when selecting nodes to connect to.
bool IsTerrible(NodeSeconds now=Now< NodeSeconds >()) const
Determine whether the statistics about this entry are bad enough so that it can just be deleted.
int nRefCount
reference count in new sets (memory only)
int nAttempts
connection attempts since last successful attempt
std::pair< CAddress, NodeSeconds > Select(bool new_only=false, std::optional< Network > network=std::nullopt) const
Choose an address to connect to.
void Connected(const CService &addr, NodeSeconds time=Now< NodeSeconds >())
We have successfully connected to this peer.
const std::unique_ptr< AddrManImpl > m_impl
void Attempt(const CService &addr, bool fCountFailure, NodeSeconds time=Now< NodeSeconds >())
Mark an entry as connection attempted to.
size_t Size(std::optional< Network > net=std::nullopt, std::optional< bool > in_new=std::nullopt) const
Return size information about addrman.
std::optional< AddressPosition > FindAddressEntry(const CAddress &addr)
Test-only function Find the address record in AddrMan and return information about its position.
std::vector< std::pair< AddrInfo, AddressPosition > > GetEntries(bool from_tried) const
Returns an information-location pair for all addresses in the selected addrman table.
void ResolveCollisions()
See if any to-be-evicted tried table entries have been tested and if so resolve the collisions.
bool Good(const CService &addr, NodeSeconds time=Now< NodeSeconds >())
Mark an address record as accessible and attempt to move it to addrman's tried table.
void Serialize(Stream &s_) const
void Unserialize(Stream &s_)
AddrMan(const NetGroupManager &netgroupman, bool deterministic, int32_t consistency_check_ratio)
std::pair< CAddress, NodeSeconds > SelectTriedCollision()
Randomly select an address in the tried table that another address is attempting to evict.
bool Add(const std::vector< CAddress > &vAddr, const CNetAddr &source, std::chrono::seconds time_penalty=0s)
Attempt to add one or more addresses to addrman's new table.
void SetServices(const CService &addr, ServiceFlags nServices)
Update an entry's service bits.
std::vector< CAddress > GetAddr(size_t max_addresses, size_t max_pct, std::optional< Network > network, const bool filtered=true) const
Return all or many randomly selected addresses, optionally by network.
void ClearNew(int nUBucket, int nUBucketPos) EXCLUSIVE_LOCKS_REQUIRED(cs)
Clear a position in a "new" table. This is the only place where entries are actually deleted.
int GetEntry(bool use_tried, size_t bucket, size_t position) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Helper to generalize looking up an addrman entry from either table.
void Connected_(const CService &addr, NodeSeconds time) EXCLUSIVE_LOCKS_REQUIRED(cs)
void Attempt_(const CService &addr, bool fCountFailure, NodeSeconds time) EXCLUSIVE_LOCKS_REQUIRED(cs)
static constexpr Format FILE_FORMAT
The maximum format this software knows it can unserialize.
void ResolveCollisions_() EXCLUSIVE_LOCKS_REQUIRED(cs)
Format
Serialization versions.
void Serialize(Stream &s_) const EXCLUSIVE_LOCKS_REQUIRED(!cs)
void Connected(const CService &addr, NodeSeconds time) EXCLUSIVE_LOCKS_REQUIRED(!cs)
void MakeTried(AddrInfo &info, int nId) EXCLUSIVE_LOCKS_REQUIRED(cs)
Move an entry from the "new" table(s) to the "tried" table.
void SetServices(const CService &addr, ServiceFlags nServices) EXCLUSIVE_LOCKS_REQUIRED(!cs)
std::optional< AddressPosition > FindAddressEntry_(const CAddress &addr) EXCLUSIVE_LOCKS_REQUIRED(cs)
void SetServices_(const CService &addr, ServiceFlags nServices) EXCLUSIVE_LOCKS_REQUIRED(cs)
AddrManImpl(const NetGroupManager &netgroupman, bool deterministic, int32_t consistency_check_ratio)
std::vector< std::pair< AddrInfo, AddressPosition > > GetEntries(bool from_tried) const EXCLUSIVE_LOCKS_REQUIRED(!cs)
const int32_t m_consistency_check_ratio
Perform consistency checks every m_consistency_check_ratio operations (if non-zero).
std::vector< std::pair< AddrInfo, AddressPosition > > GetEntries_(bool from_tried) const EXCLUSIVE_LOCKS_REQUIRED(cs)
void Check() const EXCLUSIVE_LOCKS_REQUIRED(cs)
Consistency check, taking into account m_consistency_check_ratio.
int CheckAddrman() const EXCLUSIVE_LOCKS_REQUIRED(cs)
Perform consistency check, regardless of m_consistency_check_ratio.
bool Add(const std::vector< CAddress > &vAddr, const CNetAddr &source, std::chrono::seconds time_penalty) EXCLUSIVE_LOCKS_REQUIRED(!cs)
std::optional< AddressPosition > FindAddressEntry(const CAddress &addr) EXCLUSIVE_LOCKS_REQUIRED(!cs)
AddrInfo * Find(const CService &addr, int *pnId=nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs)
Find an entry.
bool Good_(const CService &addr, bool test_before_evict, NodeSeconds time) EXCLUSIVE_LOCKS_REQUIRED(cs)
Mutex cs
A mutex to protect the inner data structures.
size_t Size_(std::optional< Network > net, std::optional< bool > in_new) const EXCLUSIVE_LOCKS_REQUIRED(cs)
std::pair< CAddress, NodeSeconds > SelectTriedCollision_() EXCLUSIVE_LOCKS_REQUIRED(cs)
std::pair< CAddress, NodeSeconds > Select(bool new_only, std::optional< Network > network) const EXCLUSIVE_LOCKS_REQUIRED(!cs)
std::pair< CAddress, NodeSeconds > SelectTriedCollision() EXCLUSIVE_LOCKS_REQUIRED(!cs)
static constexpr uint8_t INCOMPATIBILITY_BASE
The initial value of a field that is incremented every time an incompatible format change is made (su...
void Delete(int nId) EXCLUSIVE_LOCKS_REQUIRED(cs)
Delete an entry. It must not be in tried, and have refcount 0.
void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Swap two elements in vRandom.
std::vector< CAddress > GetAddr_(size_t max_addresses, size_t max_pct, std::optional< Network > network, const bool filtered=true) const EXCLUSIVE_LOCKS_REQUIRED(cs)
void Attempt(const CService &addr, bool fCountFailure, NodeSeconds time) EXCLUSIVE_LOCKS_REQUIRED(!cs)
void Unserialize(Stream &s_) EXCLUSIVE_LOCKS_REQUIRED(!cs)
std::set< int > m_tried_collisions
Holds addrs inserted into tried table that collide with existing entries. Test-before-evict disciplin...
uint256 nKey
secret key to randomize bucket select with
void ResolveCollisions() EXCLUSIVE_LOCKS_REQUIRED(!cs)
AddrInfo * Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId=nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs)
Create a new entry and add it to the internal data structures mapInfo, mapAddr and vRandom.
const NetGroupManager & m_netgroupman
Reference to the netgroup manager.
std::pair< CAddress, NodeSeconds > Select_(bool new_only, std::optional< Network > network) const EXCLUSIVE_LOCKS_REQUIRED(cs)
bool Add_(const std::vector< CAddress > &vAddr, const CNetAddr &source, std::chrono::seconds time_penalty) EXCLUSIVE_LOCKS_REQUIRED(cs)
bool Good(const CService &addr, NodeSeconds time) EXCLUSIVE_LOCKS_REQUIRED(!cs)
std::vector< CAddress > GetAddr(size_t max_addresses, size_t max_pct, std::optional< Network > network, const bool filtered=true) const EXCLUSIVE_LOCKS_REQUIRED(!cs)
size_t Size(std::optional< Network > net, std::optional< bool > in_new) const EXCLUSIVE_LOCKS_REQUIRED(!cs)
bool AddSingle(const CAddress &addr, const CNetAddr &source, std::chrono::seconds time_penalty) EXCLUSIVE_LOCKS_REQUIRED(cs)
Attempt to add a single address to addrman's new table.
Non-refcounted RAII wrapper for FILE*.
A CService with information about it as peer.
ServiceFlags nServices
Serialized as uint64_t in V1, and as CompactSize in V2.
NodeSeconds nTime
Always included in serialization. The behavior is unspecified if the value is not representable as ui...
static constexpr SerParams V1_DISK
static constexpr SerParams V2_DISK
enum Network GetNetwork() const
A combination of a network address (CNetAddr) and a (TCP) port.
std::string ToStringAddrPort() const
std::vector< unsigned char > GetKey() const
Double ended buffer combining vector and stream-like interfaces.
Reads data from an underlying stream, while hashing the read data.
A writer stream (for serialization) that computes a 256-bit hash.
Writes data to an underlying source stream, while hashing the written data.
uint256 GetAsmapChecksum() const
Get a checksum identifying the asmap being used.
std::vector< unsigned char > GetGroup(const CNetAddr &address) const
Get the canonical identifier of the network group for address.
uint32_t GetMappedAS(const CNetAddr &address) const
Get the autonomous system on the BGP path to address.
Wrapper that overrides the GetParams() function of a stream (and hides GetVersion/GetType).
constexpr bool IsNull() const
#define LogPrint(category,...)
ServiceFlags
nServices flags
Location information for an address in AddrMan.
static time_point now() noexcept
Return current system time or mocked time, if set.
std::chrono::time_point< NodeClock, std::chrono::seconds > NodeSeconds
#define LOG_TIME_MILLIS_WITH_CATEGORY_MSG_ONCE(end_msg, log_category)