56 const std::vector<bool> &
asmap)
const {
65 const std::vector<bool> &
asmap)
const {
93 if (
nTime > now + 10min) {
203 for (
const auto &entry :
mapInfo) {
205 const AddrInfo &info = entry.second;
214 for (
const auto &entry :
mapInfo) {
215 const AddrInfo &info = entry.second;
268 throw std::ios_base::failure(
269 strprintf(
"Corrupted addrman database: The compat value (%u) "
270 "is lower than the expected minimum value %u.",
276 "Unsupported format of addrman database: %u. It is compatible with "
277 "formats >=%u, but the maximum supported by this version of %s is "
294 "Corrupt AddrMan serialization: nNew=%d, should be in [0, %d]",
301 "Corrupt AddrMan serialization: nTried=%d, should be in [0, "
307 for (
int n = 0; n < nNew; n++) {
318 for (
int n = 0; n <
nTried; n++) {
372 "Bucketing method was updated, re-bucketing addrman "
373 "entries from disk\n");
410 if (it->second.fInTried ==
false && it->second.nRefCount == 0) {
420 "addrman lost %i new and %i tried addresses due to "
428 "Corrupt data. Consistency check failed with code %s",
check_code));
435 const auto it =
mapAddr.find(addr);
440 *
pnId = (*it).second;
444 return &(*it2).second;
570 "Moved %s from tried[%i][%i] to new[%i][%i] to make space\n",
614 if (
pinfo->fInTried) {
626 for (
int n = 0; n <
pinfo->nRefCount; n++) {
658 }
else if (
pinfo->nRefCount == 0) {
712 "Collision with %s while attempting to move %s to tried "
713 "table. Collisions=%d\n",
731 for (std::vector<CAddress>::const_iterator it = vAddr.begin();
732 it != vAddr.end(); it++) {
737 "Added %i addresses (of %i) from %s: %i tried, %i new\n",
809 return {info, info.m_last_try};
846 return {info, info.m_last_try};
857 std::optional<Network> network)
const {
871 for (
unsigned int n = 0; n <
vRandom.size(); n++) {
884 if (network != std::nullopt &&
ai.GetNetClass() != network) {
889 if (
ai.IsTerrible(now)) {
980 "Replacing %s with %s in tried table\n",
995 "Unable to test; replacing %s with %s in tried "
1059 LogPrintf(
"ADDRMAN CONSISTENCY CHECK FAILED!!! err=%i\n",
err);
1072 std::unordered_map<int, int>
mapNew;
1078 for (
const auto &entry :
mapInfo) {
1079 int n = entry.first;
1080 const AddrInfo &info = entry.second;
1099 const auto it{
mapAddr.find(info)};
1100 if (it ==
mapAddr.end() || it->second != n) {
1130 it->second.GetTriedBucket(nKey, m_asmap) != n) {
1133 if (it->second.GetBucketPosition(nKey,
false, n) != i) {
1143 if (
vvNew[n][i] != -1) {
1149 it->second.GetBucketPosition(nKey,
true, n) != i) {
1165 if (nKey.IsNull()) {
1227std::vector<CAddress>
1229 std::optional<Network> network)
const {
1257 std::vector<int>().swap(
vRandom);
1334 m_impl->ResolveCollisions();
1338 return m_impl->SelectTriedCollision();
1346 std::optional<Network> network)
const {
1351 m_impl->Connected(addr, time);
1355 m_impl->SetServices(addr, nServices);
1359 return m_impl->GetAsmap();
1367 return m_impl->MakeDeterministic();
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
... in at least this duration
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 GetTriedBucket(const uint256 &nKey, const std::vector< bool > &asmap) const
Calculate in which "tried" bucket this entry belongs.
int nRandomPos
position in vRandom
bool fInTried
in tried set? (memory only)
NodeSeconds m_last_success
last successful connection by us
int GetNewBucket(const uint256 &nKey, const CNetAddr &src, const std::vector< bool > &asmap) const
Calculate in which "new" bucket this entry belongs, given a certain source.
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 GetBucketPosition(const uint256 &nKey, bool fNew, int nBucket) const
Calculate in which position of a bucket to store this entry.
int nAttempts
connection attempts since last successful attempt
void Connected(const CService &addr, NodeSeconds time=Now< NodeSeconds >())
We have successfully connected to this peer.
void MakeDeterministic()
Ensure that bucket placement is always the same for testing purposes.
const std::unique_ptr< AddrManImpl > m_impl
std::vector< CAddress > GetAddr(size_t max_addresses, size_t max_pct, std::optional< Network > network) const
Return all or many randomly selected addresses, optionally by network.
const std::vector< bool > & GetAsmap() const
void Attempt(const CService &addr, bool fCountFailure, NodeSeconds time=Now< NodeSeconds >())
Mark an entry as connection attempted to.
std::pair< CAddress, NodeSeconds > Select(bool newOnly=false) const
Choose an address to connect to.
void ResolveCollisions()
See if any to-be-evicted tried table entries have been tested and if so resolve the collisions.
AddrMan(std::vector< bool > asmap, int32_t consistency_check_ratio)
void Serialize(Stream &s_) const
size_t size() const
Return the number of (unique) addresses in all tables.
void Unserialize(Stream &s_)
void Good(const CService &addr, bool test_before_evict=true, NodeSeconds time=Now< NodeSeconds >())
Mark an entry as accessible, possibly moving it from "new" to "tried".
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.
void ClearNew(int nUBucket, int nUBucketPos) EXCLUSIVE_LOCKS_REQUIRED(cs)
Clear a position in a "new" table.
std::pair< CAddress, NodeSeconds > Select(bool newOnly) const EXCLUSIVE_LOCKS_REQUIRED(!cs)
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.
@ V4_MULTIPORT
adds support for multiple ports per IP
@ V3_BIP155
same as V2_ASMAP plus addresses are in BIP155 format
@ V2_ASMAP
for files including asmap version
@ V1_DETERMINISTIC
for pre-asmap files
void Serialize(Stream &s_) const EXCLUSIVE_LOCKS_REQUIRED(!cs)
void Connected(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 EXCLUSIVE_LOCKS_REQUIRED(!cs)
size_t size() const 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)
AddrManImpl(std::vector< bool > &&asmap, int32_t consistency_check_ratio)
void SetServices_(const CService &addr, ServiceFlags nServices) EXCLUSIVE_LOCKS_REQUIRED(cs)
const int32_t m_consistency_check_ratio
Perform consistency checks every m_consistency_check_ratio operations (if non-zero).
const std::vector< bool > & GetAsmap() const
void MakeDeterministic() 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)
AddrInfo * Find(const CService &addr, int *pnId=nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs)
Find an entry.
Mutex cs
A mutex to protect the inner data structures.
std::pair< CAddress, NodeSeconds > SelectTriedCollision_() EXCLUSIVE_LOCKS_REQUIRED(cs)
std::pair< CAddress, NodeSeconds > Select_(bool newOnly) const EXCLUSIVE_LOCKS_REQUIRED(cs)
std::pair< CAddress, NodeSeconds > SelectTriedCollision() EXCLUSIVE_LOCKS_REQUIRED(!cs)
bool deterministic
Use deterministic bucket selection and inner loops randomization.
void Good_(const CService &addr, bool test_before_evict, NodeSeconds time) 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.
void Attempt(const CService &addr, bool fCountFailure, NodeSeconds time) EXCLUSIVE_LOCKS_REQUIRED(!cs)
FastRandomContext insecure_rand
Source of random numbers for randomization in inner loops.
void Good(const CService &addr, bool test_before_evict, NodeSeconds time) EXCLUSIVE_LOCKS_REQUIRED(!cs)
void Clear() 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.
const std::vector< bool > m_asmap
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)
find an entry, creating it if necessary.
std::vector< CAddress > GetAddr_(size_t max_addresses, size_t max_pct, 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 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.
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, except in the network format on INIT_PROTO_VERSION.
Double ended buffer combining vector and stream-like interfaces.
Reads data from an underlying stream, while hashing the read data.
std::vector< uint8_t > GetGroup(const std::vector< bool > &asmap) const
Get the canonical identifier of our network group.
uint32_t GetMappedAS(const std::vector< bool > &asmap) const
A combination of a network address (CNetAddr) and a (TCP) port.
std::string ToString() const
std::vector< uint8_t > GetKey() const
uint256 rand256() noexcept
generate a random uint256.
bool randbool() noexcept
Generate a random boolean.
uint64_t randbits(int bits) noexcept
Generate a random (bits)-bit integer.
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
A writer stream (for serialization) that computes a 256-bit hash.
Writes data to an underlying source stream, while hashing the written data.
uint256 SerializeHash(const T &obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION)
Compute the 256-bit hash of an object's serialization.
#define LogPrint(category,...)
Implement std::hash so RCUPtr can be used as a key for maps or sets.
static constexpr int ADDRV2_FORMAT
A flag that is ORed into the protocol version to designate that addresses should be serialized in (un...
ServiceFlags
nServices flags.
T GetRand(T nMax=std::numeric_limits< T >::max()) noexcept
Generate a uniform random integer of type T in the range [0..nMax) nMax defaults to std::numeric_limi...
static time_point now() noexcept
Return current system time or mocked time, if set.
#define AssertLockHeld(cs)
std::chrono::time_point< NodeClock, std::chrono::seconds > NodeSeconds
#define LOG_TIME_MILLIS_WITH_CATEGORY_MSG_ONCE(end_msg, log_category)