57 std::vector<unsigned char> vchSourceGroupKey = netgroupman.
GetGroup(src);
58 uint64_t hash1 = (
HashWriter{} << nKey << netgroupman.
GetGroup(*
this) << vchSourceGroupKey).GetCheapHash();
65 uint64_t hash1 = (
HashWriter{} << nKey << (fNew ? uint8_t{
'N'} : uint8_t{
'K'}) << bucket <<
GetKey()).GetCheapHash();
75 if (
nTime > now + 10min) {
104 fChance *= pow(0.66, std::min(
nAttempts, 8));
110 : insecure_rand{deterministic}
111 , nKey{deterministic ?
uint256{1} : insecure_rand.rand256()}
112 , m_consistency_check_ratio{consistency_check_ratio}
113 , m_netgroupman{netgroupman}
115 for (
auto& bucket : vvNew) {
116 for (
auto& entry : bucket) {
120 for (
auto& bucket : vvTried) {
121 for (
auto& entry : bucket) {
132 template <
typename Stream>
182 static constexpr uint8_t lowest_compatible = Format::V4_MULTIPORT;
191 std::unordered_map<int, int> mapUnkIds;
193 for (
const auto& entry : mapInfo) {
194 mapUnkIds[entry.first] = nIds;
195 const AddrInfo& info = entry.second;
203 for (
const auto& entry : mapInfo) {
204 const AddrInfo& info = entry.second;
214 if (vvNew[bucket][i] != -1)
219 if (vvNew[bucket][i] != -1) {
220 int nIndex = mapUnkIds[vvNew[bucket][i]];
230 template <
typename Stream>
238 s_ >> Using<CustomUintFormatter<1>>(
format);
247 "Corrupted addrman database: The compat value (%u) "
248 "is lower than the expected minimum value %u.",
254 "Unsupported format of addrman database: %u. It is compatible with formats >=%u, "
255 "but the maximum supported by this version of %s is %u.",
264 if (
format >= Format::V1_DETERMINISTIC) {
265 nUBuckets ^= (1 << 30);
269 throw std::ios_base::failure(
270 strprintf(
"Corrupt AddrMan serialization: nNew=%d, should be in [0, %d]",
276 throw std::ios_base::failure(
277 strprintf(
"Corrupt AddrMan serialization: nTried=%d, should be in [0, %d]",
283 for (
int n = 0; n < nNew; n++) {
288 vRandom.push_back(n);
295 for (
int n = 0; n < nTried; n++) {
301 && vvTried[nKBucket][nKBucketPos] == -1) {
304 vRandom.push_back(nIdCount);
305 mapInfo[nIdCount] = info;
306 mapAddr[info] = nIdCount;
307 vvTried[nKBucket][nKBucketPos] = nIdCount;
309 m_network_counts[info.
GetNetwork()].n_tried++;
319 std::vector<std::pair<int, int>> bucket_entries;
321 for (
int bucket = 0; bucket < nUBuckets; ++bucket) {
324 for (
int n = 0; n < num_entries; ++n) {
327 if (entry_index >= 0 && entry_index < nNew) {
328 bucket_entries.emplace_back(bucket, entry_index);
337 uint256 serialized_asmap_checksum;
338 if (
format >= Format::V2_ASMAP) {
339 s >> serialized_asmap_checksum;
342 serialized_asmap_checksum == supplied_asmap_checksum};
344 if (!restore_bucketing) {
348 for (
auto bucket_entry : bucket_entries) {
349 int bucket{bucket_entry.first};
350 const int entry_index{bucket_entry.second};
351 AddrInfo& info = mapInfo[entry_index];
362 if (restore_bucketing && vvNew[bucket][bucket_position] == -1) {
364 vvNew[bucket][bucket_position] = entry_index;
371 if (vvNew[bucket][bucket_position] == -1) {
372 vvNew[bucket][bucket_position] = entry_index;
380 for (
auto it = mapInfo.cbegin(); it != mapInfo.cend(); ) {
381 if (it->second.fInTried ==
false && it->second.nRefCount == 0) {
382 const auto itCopy = it++;
389 if (nLost + nLostUnk > 0) {
390 LogPrint(
BCLog::ADDRMAN,
"addrman lost %i new and %i tried addresses due to collisions or invalid addresses\n", nLostUnk, nLost);
394 if (check_code != 0) {
396 "Corrupt data. Consistency check failed with code %s",
405 const auto it = mapAddr.find(addr);
406 if (it == mapAddr.end())
409 *pnId = (*it).second;
410 const auto it2 = mapInfo.find((*it).second);
411 if (it2 != mapInfo.end())
412 return &(*it2).second;
420 int nId = nIdCount++;
421 mapInfo[nId] =
AddrInfo(addr, addrSource);
423 mapInfo[nId].nRandomPos = vRandom.size();
424 vRandom.push_back(nId);
429 return &mapInfo[nId];
436 if (nRndPos1 == nRndPos2)
439 assert(nRndPos1 < vRandom.size() && nRndPos2 < vRandom.size());
441 int nId1 = vRandom[nRndPos1];
442 int nId2 = vRandom[nRndPos2];
444 const auto it_1{mapInfo.find(nId1)};
445 const auto it_2{mapInfo.find(nId2)};
446 assert(it_1 != mapInfo.end());
447 assert(it_2 != mapInfo.end());
449 it_1->second.nRandomPos = nRndPos2;
450 it_2->second.nRandomPos = nRndPos1;
452 vRandom[nRndPos1] = nId2;
453 vRandom[nRndPos2] = nId1;
460 assert(mapInfo.count(nId) != 0);
478 if (vvNew[nUBucket][nUBucketPos] != -1) {
479 int nIdDelete = vvNew[nUBucket][nUBucketPos];
480 AddrInfo& infoDelete = mapInfo[nIdDelete];
483 vvNew[nUBucket][nUBucketPos] = -1;
500 if (vvNew[bucket][pos] == nId) {
501 vvNew[bucket][pos] = -1;
516 if (vvTried[nKBucket][nKBucketPos] != -1) {
518 int nIdEvict = vvTried[nKBucket][nKBucketPos];
519 assert(mapInfo.count(nIdEvict) == 1);
520 AddrInfo& infoOld = mapInfo[nIdEvict];
524 vvTried[nKBucket][nKBucketPos] = -1;
526 m_network_counts[infoOld.
GetNetwork()].n_tried--;
532 assert(vvNew[nUBucket][nUBucketPos] == -1);
536 vvNew[nUBucket][nUBucketPos] = nIdEvict;
538 m_network_counts[infoOld.
GetNetwork()].n_new++;
542 assert(vvTried[nKBucket][nKBucketPos] == -1);
544 vvTried[nKBucket][nKBucketPos] = nId;
547 m_network_counts[info.
GetNetwork()].n_tried++;
568 const auto update_interval{currently_online ? 1h : 24h};
569 if (pinfo->
nTime < addr.
nTime - update_interval - time_penalty) {
591 const int nFactor{1 << pinfo->
nRefCount};
592 if (insecure_rand.randrange(nFactor) != 0)
return false;
601 bool fInsert = vvNew[nUBucket][nUBucketPos] == -1;
602 if (vvNew[nUBucket][nUBucketPos] != nId) {
604 AddrInfo& infoExisting = mapInfo[vvNew[nUBucket][nUBucketPos]];
613 vvNew[nUBucket][nUBucketPos] = nId;
637 if (!pinfo)
return false;
660 if (test_before_evict && (vvTried[tried_bucket][tried_bucket_pos] != -1)) {
665 auto colliding_entry = mapInfo.find(vvTried[tried_bucket][tried_bucket_pos]);
667 colliding_entry != mapInfo.end() ? colliding_entry->second.ToStringAddrPort() :
"",
684 for (std::vector<CAddress>::const_iterator it = vAddr.begin(); it != vAddr.end(); it++) {
688 LogPrint(
BCLog::ADDRMAN,
"Added %i addresses (of %i) from %s: %i tried, %i new\n", added, vAddr.size(),
source.ToStringAddr(), nTried, nNew);
717 if (vRandom.empty())
return {};
719 size_t new_count = nNew;
720 size_t tried_count = nTried;
722 if (network.has_value()) {
723 auto it = m_network_counts.find(*network);
724 if (it == m_network_counts.end())
return {};
726 auto counts = it->second;
727 new_count = counts.n_new;
728 tried_count = counts.n_tried;
731 if (new_only && new_count == 0)
return {};
732 if (new_count + tried_count == 0)
return {};
737 if (new_only || tried_count == 0) {
738 search_tried =
false;
739 }
else if (new_count == 0) {
742 search_tried = insecure_rand.randbool();
748 double chance_factor = 1.0;
751 int bucket = insecure_rand.randrange(bucket_count);
756 int i, position, node_id;
759 node_id =
GetEntry(search_tried, bucket, position);
761 if (network.has_value()) {
762 const auto it{mapInfo.find(node_id)};
763 if (
Assume(it != mapInfo.end()) && it->second.GetNetwork() == *network)
break;
774 const auto it_found{mapInfo.find(node_id)};
775 assert(it_found != mapInfo.end());
776 const AddrInfo& info{it_found->second};
779 if (insecure_rand.randbits<30>() < chance_factor * info.GetChance() * (1 << 30)) {
780 LogPrint(
BCLog::ADDRMAN,
"Selected %s from %s\n", info.ToStringAddrPort(), search_tried ?
"tried" :
"new");
781 return {info, info.m_last_try};
785 chance_factor *= 1.2;
795 return vvTried[bucket][position];
799 return vvNew[bucket][position];
806 std::vector<CAddress>
AddrManImpl::GetAddr_(
size_t max_addresses,
size_t max_pct, std::optional<Network> network,
const bool filtered)
const
810 size_t nNodes = vRandom.size();
812 nNodes = max_pct * nNodes / 100;
814 if (max_addresses != 0) {
815 nNodes = std::min(nNodes, max_addresses);
819 const auto now{Now<NodeSeconds>()};
820 std::vector<CAddress> addresses;
821 for (
unsigned int n = 0; n < vRandom.size(); n++) {
822 if (addresses.size() >= nNodes)
825 int nRndPos = insecure_rand.randrange(vRandom.size() - n) + n;
827 const auto it{mapInfo.find(vRandom[n])};
828 assert(it != mapInfo.end());
833 if (network != std::nullopt && ai.GetNetClass() != network)
continue;
836 if (ai.IsTerrible(now) && filtered)
continue;
838 addresses.push_back(ai);
849 std::vector<std::pair<AddrInfo, AddressPosition>> infos;
850 for (
int bucket = 0; bucket < bucket_count; ++bucket) {
852 int id =
GetEntry(from_tried, bucket, position);
860 infos.emplace_back(info, location);
881 const auto update_interval{20min};
882 if (time - info.
nTime > update_interval) {
910 bool erase_collision =
false;
913 if (mapInfo.count(id_new) != 1) {
914 erase_collision =
true;
916 AddrInfo& info_new = mapInfo[id_new];
922 erase_collision =
true;
923 }
else if (vvTried[tried_bucket][tried_bucket_pos] != -1) {
926 int id_old = vvTried[tried_bucket][tried_bucket_pos];
927 AddrInfo& info_old = mapInfo[id_old];
929 const auto current_time{Now<NodeSeconds>()};
933 erase_collision =
true;
937 if (current_time - info_old.
m_last_try > 60s) {
941 Good_(info_new,
false, current_time);
942 erase_collision =
true;
949 Good_(info_new,
false, current_time);
950 erase_collision =
true;
953 Good_(info_new,
false, Now<NodeSeconds>());
954 erase_collision =
true;
958 if (erase_collision) {
979 if (mapInfo.count(id_new) != 1) {
984 const AddrInfo& newInfo = mapInfo[id_new];
990 const AddrInfo& info_old = mapInfo[vvTried[tried_bucket][tried_bucket_pos]];
1000 if (!addr_info)
return std::nullopt;
1021 if (!net.has_value()) {
1022 if (in_new.has_value()) {
1023 return *in_new ? nNew : nTried;
1025 return vRandom.size();
1028 if (
auto it = m_network_counts.find(*net); it != m_network_counts.end()) {
1029 auto net_count = it->second;
1030 if (in_new.has_value()) {
1031 return *in_new ? net_count.n_new : net_count.n_tried;
1033 return net_count.n_new + net_count.n_tried;
1049 LogPrintf(
"ADDRMAN CONSISTENCY CHECK FAILED!!! err=%i\n", err);
1061 std::unordered_set<int> setTried;
1062 std::unordered_map<int, int> mapNew;
1063 std::unordered_map<Network, NewTriedCount> local_counts;
1065 if (vRandom.size() != (
size_t)(nTried + nNew))
1068 for (
const auto& entry : mapInfo) {
1069 int n = entry.first;
1070 const AddrInfo& info = entry.second;
1072 if (!TicksSinceEpoch<std::chrono::seconds>(info.
m_last_success)) {
1087 const auto it{mapAddr.find(info)};
1088 if (it == mapAddr.end() || it->second != n) {
1101 if (setTried.size() != (
size_t)nTried)
1103 if (mapNew.size() != (
size_t)nNew)
1108 if (vvTried[n][i] != -1) {
1109 if (!setTried.count(vvTried[n][i]))
1111 const auto it{mapInfo.find(vvTried[n][i])};
1112 if (it == mapInfo.end() || it->second.GetTriedBucket(
nKey,
m_netgroupman) != n) {
1115 if (it->second.GetBucketPosition(
nKey,
false, n) != i) {
1118 setTried.erase(vvTried[n][i]);
1125 if (vvNew[n][i] != -1) {
1126 if (!mapNew.count(vvNew[n][i]))
1128 const auto it{mapInfo.find(vvNew[n][i])};
1129 if (it == mapInfo.end() || it->second.GetBucketPosition(
nKey,
true, n) != i) {
1132 if (--mapNew[vvNew[n][i]] == 0)
1133 mapNew.erase(vvNew[n][i]);
1138 if (setTried.size())
1147 if (m_network_counts.size() < local_counts.size()) {
1150 for (
const auto& [net,
count] : m_network_counts) {
1151 if (local_counts[net].n_new !=
count.n_new || local_counts[net].n_tried !=
count.n_tried) {
1181 auto ret =
Good_(addr,
true, time);
1190 Attempt_(addr, fCountFailure, time);
1215 auto addrRet =
Select_(new_only, network);
1220 std::vector<CAddress>
AddrManImpl::GetAddr(
size_t max_addresses,
size_t max_pct, std::optional<Network> network,
const bool filtered)
const
1224 auto addresses =
GetAddr_(max_addresses, max_pct, network, filtered);
1264 : m_impl(
std::make_unique<
AddrManImpl>(netgroupman, deterministic, consistency_check_ratio)) {}
1268 template <
typename Stream>
1271 m_impl->Serialize<Stream>(s_);
1274 template <
typename Stream>
1277 m_impl->Unserialize<Stream>(s_);
1288 size_t AddrMan::Size(std::optional<Network> net, std::optional<bool> in_new)
const
1290 return m_impl->Size(net, in_new);
1300 return m_impl->Good(addr, time);
1305 m_impl->Attempt(addr, fCountFailure, time);
1310 m_impl->ResolveCollisions();
1315 return m_impl->SelectTriedCollision();
1318 std::pair<CAddress, NodeSeconds>
AddrMan::Select(
bool new_only, std::optional<Network> network)
const
1320 return m_impl->Select(new_only, network);
1323 std::vector<CAddress>
AddrMan::GetAddr(
size_t max_addresses,
size_t max_pct, std::optional<Network> network,
const bool filtered)
const
1325 return m_impl->GetAddr(max_addresses, max_pct, network, filtered);
1330 return m_impl->GetEntries(use_tried);
1335 m_impl->Connected(addr, time);
1340 m_impl->SetServices(addr, nServices);
1345 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.
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)