aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/addrman.cpp8
-rw-r--r--src/addrman.h239
2 files changed, 128 insertions, 119 deletions
diff --git a/src/addrman.cpp b/src/addrman.cpp
index 7b674a66e7..7ff21b00ec 100644
--- a/src/addrman.cpp
+++ b/src/addrman.cpp
@@ -1,5 +1,5 @@
// Copyright (c) 2012 Pieter Wuille
-// Distributed under the MIT/X11 software license, see the accompanying
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "addrman.h"
@@ -39,7 +39,7 @@ int CAddrInfo::GetNewBucket(const std::vector<unsigned char>& nKey, const CNetAd
bool CAddrInfo::IsTerrible(int64_t nNow) const
{
- if (nLastTry && nLastTry >= nNow - 60) // never remove things tried the last minute
+ if (nLastTry && nLastTry >= nNow - 60) // never remove things tried in the last minute
return false;
if (nTime > nNow + 10 * 60) // came in a flying DeLorean
@@ -131,7 +131,7 @@ int CAddrMan::SelectTried(int nKBucket)
{
std::vector<int>& vTried = vvTried[nKBucket];
- // random shuffle the first few elements (using the entire list)
+ // randomly shuffle the first few elements (using the entire list)
// find the least recently tried among them
int64_t nOldest = -1;
int nOldestPos = -1;
@@ -211,7 +211,7 @@ void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin)
assert(info.nRefCount == 0);
- // what tried bucket to move the entry to
+ // which tried bucket to move the entry to
int nKBucket = info.GetTriedBucket(nKey);
std::vector<int>& vTried = vvTried[nKBucket];
diff --git a/src/addrman.h b/src/addrman.h
index 5fd698f18a..914086fc76 100644
--- a/src/addrman.h
+++ b/src/addrman.h
@@ -1,5 +1,5 @@
// Copyright (c) 2012 Pieter Wuille
-// Distributed under the MIT/X11 software license, see the accompanying
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef _BITCOIN_ADDRMAN
@@ -17,29 +17,31 @@
#include <stdint.h>
#include <vector>
-/** Extended statistics about a CAddress */
+/**
+ * Extended statistics about a CAddress
+ */
class CAddrInfo : public CAddress
{
private:
- // where knowledge about this address first came from
+ //! where knowledge about this address first came from
CNetAddr source;
- // last successful connection by us
+ //! last successful connection by us
int64_t nLastSuccess;
- // last try whatsoever by us:
+ //! last try whatsoever by us:
// int64_t CAddress::nLastTry
- // connection attempts since last successful attempt
+ //! connection attempts since last successful attempt
int nAttempts;
- // reference count in new sets (memory only)
+ //! reference count in new sets (memory only)
int nRefCount;
- // in tried set? (memory only)
+ //! in tried set? (memory only)
bool fInTried;
- // position in vRandom
+ //! position in vRandom
int nRandomPos;
friend class CAddrMan;
@@ -76,200 +78,205 @@ public:
Init();
}
- // Calculate in which "tried" bucket this entry belongs
+ //! Calculate in which "tried" bucket this entry belongs
int GetTriedBucket(const std::vector<unsigned char> &nKey) const;
- // Calculate in which "new" bucket this entry belongs, given a certain source
+ //! Calculate in which "new" bucket this entry belongs, given a certain source
int GetNewBucket(const std::vector<unsigned char> &nKey, const CNetAddr& src) const;
- // Calculate in which "new" bucket this entry belongs, using its default source
+ //! Calculate in which "new" bucket this entry belongs, using its default source
int GetNewBucket(const std::vector<unsigned char> &nKey) const
{
return GetNewBucket(nKey, source);
}
- // Determine whether the statistics about this entry are bad enough so that it can just be deleted
+ //! Determine whether the statistics about this entry are bad enough so that it can just be deleted
bool IsTerrible(int64_t nNow = GetAdjustedTime()) const;
- // Calculate the relative chance this entry should be given when selecting nodes to connect to
+ //! Calculate the relative chance this entry should be given when selecting nodes to connect to
double GetChance(int64_t nNow = GetAdjustedTime()) const;
};
-// Stochastic address manager
-//
-// Design goals:
-// * Only keep a limited number of addresses around, so that addr.dat and memory requirements do not grow without bound.
-// * Keep the address tables in-memory, and asynchronously dump the entire to able in addr.dat.
-// * Make sure no (localized) attacker can fill the entire table with his nodes/addresses.
-//
-// To that end:
-// * Addresses are organized into buckets.
-// * Address that have not yet been tried go into 256 "new" buckets.
-// * Based on the address range (/16 for IPv4) of source of the information, 32 buckets are selected at random
-// * The actual bucket is chosen from one of these, based on the range the address itself is located.
-// * One single address can occur in up to 4 different buckets, to increase selection chances for addresses that
-// are seen frequently. The chance for increasing this multiplicity decreases exponentially.
-// * When adding a new address to a full bucket, a randomly chosen entry (with a bias favoring less recently seen
-// ones) is removed from it first.
-// * Addresses of nodes that are known to be accessible go into 64 "tried" buckets.
-// * Each address range selects at random 4 of these buckets.
-// * The actual bucket is chosen from one of these, based on the full address.
-// * When adding a new good address to a full bucket, a randomly chosen entry (with a bias favoring less recently
-// tried ones) is evicted from it, back to the "new" buckets.
-// * Bucket selection is based on cryptographic hashing, using a randomly-generated 256-bit key, which should not
-// be observable by adversaries.
-// * Several indexes are kept for high performance. Defining DEBUG_ADDRMAN will introduce frequent (and expensive)
-// consistency checks for the entire data structure.
-
-// total number of buckets for tried addresses
+/** Stochastic address manager
+ *
+ * Design goals:
+ * * Keep the address tables in-memory, and asynchronously dump the entire to able in peers.dat.
+ * * Make sure no (localized) attacker can fill the entire table with his nodes/addresses.
+ *
+ * To that end:
+ * * Addresses are organized into buckets.
+ * * Address that have not yet been tried go into 256 "new" buckets.
+ * * Based on the address range (/16 for IPv4) of source of the information, 32 buckets are selected at random
+ * * The actual bucket is chosen from one of these, based on the range the address itself is located.
+ * * One single address can occur in up to 4 different buckets, to increase selection chances for addresses that
+ * are seen frequently. The chance for increasing this multiplicity decreases exponentially.
+ * * When adding a new address to a full bucket, a randomly chosen entry (with a bias favoring less recently seen
+ * ones) is removed from it first.
+ * * Addresses of nodes that are known to be accessible go into 64 "tried" buckets.
+ * * Each address range selects at random 4 of these buckets.
+ * * The actual bucket is chosen from one of these, based on the full address.
+ * * When adding a new good address to a full bucket, a randomly chosen entry (with a bias favoring less recently
+ * tried ones) is evicted from it, back to the "new" buckets.
+ * * Bucket selection is based on cryptographic hashing, using a randomly-generated 256-bit key, which should not
+ * be observable by adversaries.
+ * * Several indexes are kept for high performance. Defining DEBUG_ADDRMAN will introduce frequent (and expensive)
+ * consistency checks for the entire data structure.
+ */
+
+//! total number of buckets for tried addresses
#define ADDRMAN_TRIED_BUCKET_COUNT 64
-// maximum allowed number of entries in buckets for tried addresses
+//! maximum allowed number of entries in buckets for tried addresses
#define ADDRMAN_TRIED_BUCKET_SIZE 64
-// total number of buckets for new addresses
+//! total number of buckets for new addresses
#define ADDRMAN_NEW_BUCKET_COUNT 256
-// maximum allowed number of entries in buckets for new addresses
+//! maximum allowed number of entries in buckets for new addresses
#define ADDRMAN_NEW_BUCKET_SIZE 64
-// over how many buckets entries with tried addresses from a single group (/16 for IPv4) are spread
+//! over how many buckets entries with tried addresses from a single group (/16 for IPv4) are spread
#define ADDRMAN_TRIED_BUCKETS_PER_GROUP 4
-// over how many buckets entries with new addresses originating from a single group are spread
+//! over how many buckets entries with new addresses originating from a single group are spread
#define ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP 32
-// in how many buckets for entries with new addresses a single address may occur
+//! in how many buckets for entries with new addresses a single address may occur
#define ADDRMAN_NEW_BUCKETS_PER_ADDRESS 4
-// how many entries in a bucket with tried addresses are inspected, when selecting one to replace
+//! how many entries in a bucket with tried addresses are inspected, when selecting one to replace
#define ADDRMAN_TRIED_ENTRIES_INSPECT_ON_EVICT 4
-// how old addresses can maximally be
+//! how old addresses can maximally be
#define ADDRMAN_HORIZON_DAYS 30
-// after how many failed attempts we give up on a new node
+//! after how many failed attempts we give up on a new node
#define ADDRMAN_RETRIES 3
-// how many successive failures are allowed ...
+//! how many successive failures are allowed ...
#define ADDRMAN_MAX_FAILURES 10
-// ... in at least this many days
+//! ... in at least this many days
#define ADDRMAN_MIN_FAIL_DAYS 7
-// the maximum percentage of nodes to return in a getaddr call
+//! the maximum percentage of nodes to return in a getaddr call
#define ADDRMAN_GETADDR_MAX_PCT 23
-// the maximum number of nodes to return in a getaddr call
+//! the maximum number of nodes to return in a getaddr call
#define ADDRMAN_GETADDR_MAX 2500
-/** Stochastical (IP) address manager */
+/**
+ * Stochastical (IP) address manager
+ */
class CAddrMan
{
private:
- // critical section to protect the inner data structures
+ //! critical section to protect the inner data structures
mutable CCriticalSection cs;
- // secret key to randomize bucket select with
+ //! secret key to randomize bucket select with
std::vector<unsigned char> nKey;
- // last used nId
+ //! last used nId
int nIdCount;
- // table with information about all nIds
+ //! table with information about all nIds
std::map<int, CAddrInfo> mapInfo;
- // find an nId based on its network address
+ //! find an nId based on its network address
std::map<CNetAddr, int> mapAddr;
- // randomly-ordered vector of all nIds
+ //! randomly-ordered vector of all nIds
std::vector<int> vRandom;
// number of "tried" entries
int nTried;
- // list of "tried" buckets
+ //! list of "tried" buckets
std::vector<std::vector<int> > vvTried;
- // number of (unique) "new" entries
+ //! number of (unique) "new" entries
int nNew;
- // list of "new" buckets
+ //! list of "new" buckets
std::vector<std::set<int> > vvNew;
protected:
- // Find an entry.
+ //! Find an entry.
CAddrInfo* Find(const CNetAddr& addr, int *pnId = NULL);
- // find an entry, creating it if necessary.
- // nTime and nServices of found node is updated, if necessary.
+ //! find an entry, creating it if necessary.
+ //! nTime and nServices of the found node are updated, if necessary.
CAddrInfo* Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId = NULL);
- // Swap two elements in vRandom.
+ //! Swap two elements in vRandom.
void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2);
- // Return position in given bucket to replace.
+ //! Return position in given bucket to replace.
int SelectTried(int nKBucket);
- // Remove an element from a "new" bucket.
- // This is the only place where actual deletes occur.
- // They are never deleted while in the "tried" table, only possibly evicted back to the "new" table.
+ //! Remove an element from a "new" bucket.
+ //! This is the only place where actual deletions occur.
+ //! Elements are never deleted while in the "tried" table, only possibly evicted back to the "new" table.
int ShrinkNew(int nUBucket);
- // Move an entry from the "new" table(s) to the "tried" table
- // @pre vvUnkown[nOrigin].count(nId) != 0
+ //! Move an entry from the "new" table(s) to the "tried" table
+ //! @pre vvUnkown[nOrigin].count(nId) != 0
void MakeTried(CAddrInfo& info, int nId, int nOrigin);
- // Mark an entry "good", possibly moving it from "new" to "tried".
+ //! Mark an entry "good", possibly moving it from "new" to "tried".
void Good_(const CService &addr, int64_t nTime);
- // Add an entry to the "new" table.
+ //! Add an entry to the "new" table.
bool Add_(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty);
- // Mark an entry as attempted to connect.
+ //! Mark an entry as attempted to connect.
void Attempt_(const CService &addr, int64_t nTime);
- // Select an address to connect to.
- // nUnkBias determines how much to favor new addresses over tried ones (min=0, max=100)
+ //! Select an address to connect to.
+ //! nUnkBias determines how much to favor new addresses over tried ones (min=0, max=100)
CAddress Select_(int nUnkBias);
#ifdef DEBUG_ADDRMAN
- // Perform consistency check. Returns an error code or zero.
+ //! Perform consistency check. Returns an error code or zero.
int Check_();
#endif
- // Select several addresses at once.
+ //! Select several addresses at once.
void GetAddr_(std::vector<CAddress> &vAddr);
- // Mark an entry as currently-connected-to.
+ //! Mark an entry as currently-connected-to.
void Connected_(const CService &addr, int64_t nTime);
public:
- // serialized format:
- // * version byte (currently 0)
- // * nKey
- // * nNew
- // * nTried
- // * number of "new" buckets
- // * all nNew addrinfos in vvNew
- // * all nTried addrinfos in vvTried
- // * for each bucket:
- // * number of elements
- // * for each element: index
- //
- // Notice that vvTried, mapAddr and vVector are never encoded explicitly;
- // they are instead reconstructed from the other information.
- //
- // vvNew is serialized, but only used if ADDRMAN_UNKOWN_BUCKET_COUNT didn't change,
- // otherwise it is reconstructed as well.
- //
- // This format is more complex, but significantly smaller (at most 1.5 MiB), and supports
- // changes to the ADDRMAN_ parameters without breaking the on-disk structure.
- //
- // We don't use ADD_SERIALIZE_METHODS since the serialization and deserialization code has
- // very little in common.
+ /**
+ * serialized format:
+ * * version byte (currently 0)
+ * * nKey
+ * * nNew
+ * * nTried
+ * * number of "new" buckets
+ * * all nNew addrinfos in vvNew
+ * * all nTried addrinfos in vvTried
+ * * for each bucket:
+ * * number of elements
+ * * for each element: index
+ *
+ * Notice that vvTried, mapAddr and vVector are never encoded explicitly;
+ * they are instead reconstructed from the other information.
+ *
+ * vvNew is serialized, but only used if ADDRMAN_UNKOWN_BUCKET_COUNT didn't change,
+ * otherwise it is reconstructed as well.
+ *
+ * This format is more complex, but significantly smaller (at most 1.5 MiB), and supports
+ * changes to the ADDRMAN_ parameters without breaking the on-disk structure.
+ *
+ * We don't use ADD_SERIALIZE_METHODS since the serialization and deserialization code has
+ * very little in common.
+ *
+ */
template<typename Stream>
void Serialize(Stream &s, int nType, int nVersionDummy) const
{
@@ -394,13 +401,13 @@ public:
nNew = 0;
}
- // Return the number of (unique) addresses in all tables.
+ //! Return the number of (unique) addresses in all tables.
int size()
{
return vRandom.size();
}
- // Consistency check
+ //! Consistency check
void Check()
{
#ifdef DEBUG_ADDRMAN
@@ -413,7 +420,7 @@ public:
#endif
}
- // Add a single address.
+ //! Add a single address.
bool Add(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty = 0)
{
bool fRet = false;
@@ -428,7 +435,7 @@ public:
return fRet;
}
- // Add multiple addresses.
+ //! Add multiple addresses.
bool Add(const std::vector<CAddress> &vAddr, const CNetAddr& source, int64_t nTimePenalty = 0)
{
int nAdd = 0;
@@ -444,7 +451,7 @@ public:
return nAdd > 0;
}
- // Mark an entry as accessible.
+ //! Mark an entry as accessible.
void Good(const CService &addr, int64_t nTime = GetAdjustedTime())
{
{
@@ -455,7 +462,7 @@ public:
}
}
- // Mark an entry as connection attempted to.
+ //! Mark an entry as connection attempted to.
void Attempt(const CService &addr, int64_t nTime = GetAdjustedTime())
{
{
@@ -466,8 +473,10 @@ public:
}
}
- // Choose an address to connect to.
- // nUnkBias determines how much "new" entries are favored over "tried" ones (0-100).
+ /**
+ * Choose an address to connect to.
+ * nUnkBias determines how much "new" entries are favored over "tried" ones (0-100).
+ */
CAddress Select(int nUnkBias = 50)
{
CAddress addrRet;
@@ -480,7 +489,7 @@ public:
return addrRet;
}
- // Return a bunch of addresses, selected at random.
+ //! Return a bunch of addresses, selected at random.
std::vector<CAddress> GetAddr()
{
Check();
@@ -493,7 +502,7 @@ public:
return vAddr;
}
- // Mark an entry as currently-connected-to.
+ //! Mark an entry as currently-connected-to.
void Connected(const CService &addr, int64_t nTime = GetAdjustedTime())
{
{