6 #ifndef BITCOIN_ADDRMAN_H 7 #define BITCOIN_ADDRMAN_H 58 template <
typename Stream,
typename Operation>
122 #define ADDRMAN_TRIED_BUCKET_COUNT_LOG2 8 126 #define ADDRMAN_NEW_BUCKET_COUNT_LOG2 10 129 #define ADDRMAN_BUCKET_SIZE_LOG2 6 132 #define ADDRMAN_TRIED_BUCKETS_PER_GROUP 8 135 #define ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP 64 138 #define ADDRMAN_NEW_BUCKETS_PER_ADDRESS 8 141 #define ADDRMAN_HORIZON_DAYS 30 144 #define ADDRMAN_RETRIES 3 147 #define ADDRMAN_MAX_FAILURES 10 150 #define ADDRMAN_MIN_FAIL_DAYS 7 153 #define ADDRMAN_REPLACEMENT_HOURS 4 156 #define ADDRMAN_GETADDR_MAX_PCT 23 159 #define ADDRMAN_GETADDR_MAX 2500 162 #define ADDRMAN_TRIED_BUCKET_COUNT (1 << ADDRMAN_TRIED_BUCKET_COUNT_LOG2) 163 #define ADDRMAN_NEW_BUCKET_COUNT (1 << ADDRMAN_NEW_BUCKET_COUNT_LOG2) 164 #define ADDRMAN_BUCKET_SIZE (1 << ADDRMAN_BUCKET_SIZE_LOG2) 167 #define ADDRMAN_SET_TRIED_COLLISION_SIZE 10 300 template<
typename Stream>
305 unsigned char nVersion = 1;
307 s << ((
unsigned char)32);
314 std::map<int, int> mapUnkIds;
316 for (
const auto& entry : mapInfo) {
317 mapUnkIds[entry.first] = nIds;
320 assert(nIds != nNew);
326 for (
const auto& entry : mapInfo) {
329 assert(nIds != nTried);
337 if (vvNew[bucket][i] != -1)
342 if (vvNew[bucket][i] != -1) {
343 int nIndex = mapUnkIds[vvNew[bucket][i]];
350 template<
typename Stream>
357 unsigned char nVersion;
359 unsigned char nKeySize;
361 if (nKeySize != 32)
throw std::ios_base::failure(
"Incorrect keysize in addrman deserialization");
368 nUBuckets ^= (1 << 30);
372 throw std::ios_base::failure(
"Corrupt CAddrMan serialization, nNew exceeds limit.");
376 throw std::ios_base::failure(
"Corrupt CAddrMan serialization, nTried exceeds limit.");
380 for (
int n = 0; n < nNew; n++) {
385 vRandom.push_back(n);
389 int nUBucket = info.GetNewBucket(
nKey);
390 int nUBucketPos = info.GetBucketPosition(
nKey,
true, nUBucket);
391 if (vvNew[nUBucket][nUBucketPos] == -1) {
392 vvNew[nUBucket][nUBucketPos] = n;
401 for (
int n = 0; n < nTried; n++) {
405 int nKBucketPos = info.GetBucketPosition(
nKey,
false, nKBucket);
406 if (vvTried[nKBucket][nKBucketPos] == -1) {
407 info.nRandomPos = vRandom.size();
408 info.fInTried =
true;
409 vRandom.push_back(nIdCount);
410 mapInfo[nIdCount] = info;
411 mapAddr[info] = nIdCount;
412 vvTried[nKBucket][nKBucketPos] = nIdCount;
421 for (
int bucket = 0; bucket < nUBuckets; bucket++) {
424 for (
int n = 0; n < nSize; n++) {
427 if (nIndex >= 0 && nIndex < nNew) {
432 vvNew[bucket][nUBucketPos] = nIndex;
440 for (std::map<int, CAddrInfo>::const_iterator
it = mapInfo.begin();
it != mapInfo.end(); ) {
441 if (
it->second.fInTried ==
false &&
it->second.nRefCount == 0) {
442 std::map<int, CAddrInfo>::const_iterator itCopy =
it++;
449 if (nLost + nLostUnk > 0) {
450 LogPrint(
BCLog::ADDRMAN,
"addrman lost %i new and %i tried addresses due to collisions\n", nLostUnk, nLost);
459 std::vector<int>().swap(vRandom);
463 vvNew[bucket][entry] = -1;
468 vvTried[bucket][entry] = -1;
494 return vRandom.size();
505 LogPrintf(
"ADDRMAN CONSISTENCY CHECK FAILED!!! err=%i\n",
err);
530 for (std::vector<CAddress>::const_iterator
it = vAddr.begin();
it != vAddr.end();
it++)
544 Good_(addr, test_before_evict, nTime);
553 Attempt_(addr, fCountFailure, nTime);
598 std::vector<CAddress> vAddr;
626 #endif // BITCOIN_ADDRMAN_H std::vector< CAddress > GetAddr()
Return a bunch of addresses, selected at random.
Definition: addrman.h:595
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: thread_annotations.h:13
Definition: protocol.h:325
ServiceFlags
Definition: protocol.h:247
void SetNull()
Definition: uint256.h:39
uint256 nKey
secret key to randomize bucket select with
Definition: addrman.h:214
CAddrInfo(const CAddress &addrIn, const CNetAddr &addrSource)
Definition: addrman.h:66
void Clear()
Definition: addrman.h:456
ADD_SERIALIZE_METHODS
Definition: addrman.h:56
Definition: netaddress.h:32
void SerializationOp(Stream &s, Operation ser_action)
Definition: addrman.h:59
void GetAddr_(std::vector< CAddress > &vAddr) EXCLUSIVE_LOCKS_REQUIRED(cs)
Select several addresses at once.
Definition: addrman.cpp:475
static void LogPrintf(const char *fmt, const Args &... args)
Definition: logging.h:144
size_t size() const
Return the number of (unique) addresses in all tables.
Definition: addrman.h:491
void Unserialize(Stream &s)
Definition: addrman.h:351
static const int64_t ADDRMAN_TEST_WINDOW
the maximum time we'll spend trying to resolve a tried table collision, in seconds
Definition: addrman.h:170
void Connected_(const CService &addr, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs)
Mark an entry as currently-connected-to.
Definition: addrman.cpp:496
int64_t nLastCountAttempt
last counted attempt (memory only)
Definition: addrman.h:31
FastRandomContext insecure_rand
Source of random numbers for randomization in inner loops.
Definition: addrman.h:217
void Good(const CService &addr, bool test_before_evict=true, int64_t nTime=GetAdjustedTime())
Mark an entry as accessible.
Definition: addrman.h:540
CAddrInfo SelectTriedCollision_() EXCLUSIVE_LOCKS_REQUIRED(cs)
Return a random to-be-evicted tried table address.
Definition: addrman.cpp:593
void Good_(const CService &addr, bool test_before_evict, int64_t time) EXCLUSIVE_LOCKS_REQUIRED(cs)
Mark an entry "good", possibly moving it from "new" to "tried".
Definition: addrman.cpp:189
#define ADDRMAN_TRIED_BUCKET_COUNT
Convenience.
Definition: addrman.h:162
#define READWRITEAS(type, obj)
Definition: serialize.h:185
bool Add(const CAddress &addr, const CNetAddr &source, int64_t nTimePenalty=0)
Add a single address.
Definition: addrman.h:511
int nRandomPos
position in vRandom
Definition: addrman.h:50
~CAddrMan()
Definition: addrman.h:485
void Attempt(const CService &addr, bool fCountFailure, int64_t nTime=GetAdjustedTime())
Mark an entry as connection attempted to.
Definition: addrman.h:549
CAddrInfo()
Definition: addrman.h:70
CAddrInfo * Find(const CNetAddr &addr, int *pnId=nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs)
Find an entry.
Definition: addrman.cpp:67
bool IsTerrible(int64_t nNow=GetAdjustedTime()) const
Determine whether the statistics about this entry are bad enough so that it can just be deleted.
Definition: addrman.cpp:32
int64_t nLastTry
last try whatsoever by us (memory only)
Definition: addrman.h:28
CAddrInfo Select(bool newOnly=false)
Definition: addrman.h:582
CAddrMan()
Definition: addrman.h:480
bool fInTried
in tried set? (memory only)
Definition: addrman.h:47
void ResolveCollisions_() EXCLUSIVE_LOCKS_REQUIRED(cs)
See if any to-be-evicted tried table entries have been tested and if so resolve the collisions.
Definition: addrman.cpp:534
void MakeTried(CAddrInfo &info, int nId) EXCLUSIVE_LOCKS_REQUIRED(cs)
Move an entry from the "new" table(s) to the "tried" table.
Definition: addrman.cpp:141
CCriticalSection cs
critical section to protect the inner data structures
Definition: addrman.h:179
const char * source
Definition: rpcconsole.cpp:53
CAddrInfo * Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId=nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: addrman.cpp:80
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.
Definition: addrman.cpp:126
int GetBucketPosition(const uint256 &nKey, bool fNew, int nBucket) const
Calculate in which position of a bucket to store this entry.
Definition: addrman.cpp:26
#define LOCK(cs)
Definition: sync.h:182
std::string ToStringIPPort() const
Definition: netaddress.cpp:684
void ResolveCollisions()
See if any to-be-evicted tried table entries have been tested and if so resolve the collisions.
Definition: addrman.h:558
static void LogPrint(const BCLog::LogFlags &category, const Args &... args)
Definition: logging.h:159
void Serialize(Stream &s) const
Definition: addrman.h:301
uint256 rand256() noexcept
Definition: random.cpp:689
#define ADDRMAN_BUCKET_SIZE
Definition: addrman.h:164
int GetNewBucket(const uint256 &nKey, const CNetAddr &src) const
Calculate in which "new" bucket this entry belongs, given a certain source.
Definition: addrman.cpp:18
int GetNewBucket(const uint256 &nKey) const
Calculate in which "new" bucket this entry belongs, using its default source.
Definition: addrman.h:81
void SetServices(const CService &addr, ServiceFlags nServices)
Definition: addrman.h:616
CAddrInfo SelectTriedCollision()
Randomly select an address in tried that another address is attempting to evict.
Definition: addrman.h:567
void SetServices_(const CService &addr, ServiceFlags nServices) EXCLUSIVE_LOCKS_REQUIRED(cs)
Update an entry's service bits.
Definition: addrman.cpp:516
Definition: uint256.h:121
void Check()
Consistency check.
Definition: addrman.h:498
double GetChance(int64_t nNow=GetAdjustedTime()) const
Calculate the relative chance this entry should be given when selecting nodes to connect to.
Definition: addrman.cpp:52
void Connected(const CService &addr, int64_t nTime=GetAdjustedTime())
Mark an entry as currently-connected-to.
Definition: addrman.h:608
void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2) EXCLUSIVE_LOCKS_REQUIRED(cs)
Swap two elements in vRandom.
Definition: addrman.cpp:92
bool Add_(const CAddress &addr, const CNetAddr &source, int64_t nTimePenalty) EXCLUSIVE_LOCKS_REQUIRED(cs)
Add an entry to the "new" table.
Definition: addrman.cpp:255
#define ADDRMAN_NEW_BUCKET_COUNT
Definition: addrman.h:163
int64_t GetAdjustedTime()
Definition: timedata.cpp:34
Definition: netaddress.h:140
std::set< int > m_tried_collisions
Holds addrs inserted into tried table that collide with existing entries. Test-before-evict disciplin...
Definition: addrman.h:210
int64_t nLastSuccess
last successful connection by us
Definition: addrman.h:38
signed long long int64_t
Definition: stdint.h:18
CAddrInfo Select_(bool newOnly) EXCLUSIVE_LOCKS_REQUIRED(cs)
Select an address to connect to, if newOnly is set to true, only the new table is selected from.
Definition: addrman.cpp:350
int nIdCount GUARDED_BY(cs)
last used nId
void Attempt_(const CService &addr, bool fCountFailure, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs)
Mark an entry as attempted to connect.
Definition: addrman.cpp:328
CNetAddr source
where knowledge about this address first came from
Definition: addrman.h:35
int nRefCount
reference count in new sets (memory only)
Definition: addrman.h:44
Definition: addrman.h:175
#define READWRITE(...)
Definition: serialize.h:184
auto it
Definition: validation.cpp:360
bool Add(const std::vector< CAddress > &vAddr, const CNetAddr &source, int64_t nTimePenalty=0)
Add multiple addresses.
Definition: addrman.h:525
int nAttempts
connection attempts since last successful attempt
Definition: addrman.h:41
void Delete(int nId) EXCLUSIVE_LOCKS_REQUIRED(cs)
Delete an entry. It must not be in tried, and have refcount 0.
Definition: addrman.cpp:112
#define ADDRMAN_NEW_BUCKETS_PER_ADDRESS
in how many buckets for entries with new addresses a single address may occur
Definition: addrman.h:138
int GetTriedBucket(const uint256 &nKey) const
Calculate in which "tried" bucket this entry belongs.
Definition: addrman.cpp:11