X-Git-Url: https://git.novaco.in/?p=novacoin.git;a=blobdiff_plain;f=src%2Faddrman.h;h=7e5f9f5beca95e82cf3ce520545d44eb62686dd6;hp=5f1d7b2af9c24a63709ee502d6e9b59b094f0dcf;hb=415da519893e8fef7a10007fc82934385addd03d;hpb=700e5a4d86d5180e6bb905c25a9e05695617f445 diff --git a/src/addrman.h b/src/addrman.h index 5f1d7b2..7e5f9f5 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -1,12 +1,13 @@ // Copyright (c) 2012 Pieter Wuille // Distributed under the MIT/X11 software license, see the accompanying -// file license.txt or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef _BITCOIN_ADDRMAN #define _BITCOIN_ADDRMAN 1 #include "netbase.h" #include "protocol.h" #include "util.h" +#include "sync.h" #include @@ -22,13 +23,13 @@ private: // where knowledge about this address first came from CNetAddr source; - // last succesfull connection by us - int64 nLastSuccess; + // last successful connection by us + int64_t nLastSuccess; // last try whatsoever by us: - // int64 CAddress::nLastTry + // int64_t CAddress::nLastTry - // connection attempts since last succesful attempt + // connection attempts since last successful attempt int nAttempts; // reference count in new sets (memory only) @@ -85,10 +86,10 @@ public: } // Determine whether the statistics about this entry are bad enough so that it can just be deleted - bool IsTerrible(int64 nNow = GetAdjustedTime()) const; + bool IsTerrible(int64_t nNow = GetAdjustedTime()) const; // Calculate the relative chance this entry should be given when selecting nodes to connect to - double GetChance(int64 nNow = GetAdjustedTime()) const; + double GetChance(int64_t nNow = GetAdjustedTime()) const; }; @@ -116,7 +117,7 @@ public: // * 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 datastructure. +// consistency checks for the entire data structure. // total number of buckets for tried addresses #define ADDRMAN_TRIED_BUCKET_COUNT 64 @@ -173,13 +174,13 @@ private: // last used nId int nIdCount; - // table with information about all nId's + // table with information about all nIds std::map mapInfo; // find an nId based on its network address std::map mapAddr; - // randomly-ordered vector of all nId's + // randomly-ordered vector of all nIds std::vector vRandom; // number of "tried" entries @@ -204,7 +205,7 @@ protected: CAddrInfo* Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId = NULL); // Swap two elements in vRandom. - void SwapRandom(int nRandomPos1, int nRandomPos2); + void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2); // Return position in given bucket to replace. int SelectTried(int nKBucket); @@ -213,19 +214,19 @@ protected: // 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. int ShrinkNew(int nUBucket); - + // 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". - void Good_(const CService &addr, int64 nTime); + void Good_(const CService &addr, int64_t nTime); // Add an entry to the "new" table. - bool Add_(const CAddress &addr, const CNetAddr& source, int64 nTimePenalty); + bool Add_(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty); // Mark an entry as attempted to connect. - void Attempt_(const CService &addr, int64 nTime); + 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) @@ -238,145 +239,186 @@ protected: // Select several addresses at once. void GetAddr_(std::vector &vAddr); + void GetOnlineAddr_(std::vector &vAddr); // Mark an entry as currently-connected-to. - void Connected_(const CService &addr, int64 nTime); + void Connected_(const CService &addr, int64_t nTime); public: + typedef std::map MapUnkIds; // For MSVC macro IMPLEMENT_SERIALIZE - (({ - // serialized format: - // * version byte (currently 0) - // * nKey - // * nNew - // * nTried - // * number of "new" buckets - // * all nNew addrinfo's in vvNew - // * all nTried addrinfo's 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. - CRITICAL_BLOCK(cs) - { - unsigned char nVersion = 0; - READWRITE(nVersion); - READWRITE(nKey); - READWRITE(nNew); - READWRITE(nTried); - - CAddrMan *am = const_cast(this); - if (fWrite) - { - int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT; - READWRITE(nUBuckets); - std::map mapUnkIds; - int nIds = 0; - for (std::map::iterator it = am->mapInfo.begin(); it != am->mapInfo.end(); it++) + ( + LOCK(cs); + unsigned char + nVersion = 0; + + READWRITE(nVersion); + READWRITE(nKey); + READWRITE(nNew); + READWRITE(nTried); + + CAddrMan + *am = const_cast(this); + + if (fWrite) { - if (nIds == nNew) break; // this means nNew was wrong, oh ow - mapUnkIds[(*it).first] = nIds; - CAddrInfo &info = (*it).second; - if (info.nRefCount) + int + nUBuckets = ADDRMAN_NEW_BUCKET_COUNT; + + READWRITE(nUBuckets); + MapUnkIds mapUnkIds; + int + nIds = 0; + for (std::map::iterator it = am->mapInfo.begin(); it != am->mapInfo.end(); it++) { - READWRITE(info); - nIds++; + if (nIds == nNew) + break; // this means nNew was wrong, oh ow + mapUnkIds[(*it).first] = nIds; + + CAddrInfo + &info = (*it).second; + + if (info.nRefCount) + { + READWRITE(info); + nIds++; + } } - } - nIds = 0; - for (std::map::iterator it = am->mapInfo.begin(); it != am->mapInfo.end(); it++) - { - if (nIds == nTried) break; // this means nTried was wrong, oh ow - CAddrInfo &info = (*it).second; - if (info.fInTried) + nIds = 0; + for (std::map::iterator it = am->mapInfo.begin(); it != am->mapInfo.end(); it++) { - READWRITE(info); - nIds++; + if (nIds == nTried) + break; /* this means nTried was wrong, oh ow */ + + CAddrInfo + &info = (*it).second; + + if (info.fInTried) + { + READWRITE(info); + nIds++; + } } - } - for (std::vector >::iterator it = am->vvNew.begin(); it != am->vvNew.end(); it++) - { - const std::set &vNew = (*it); - int nSize = vNew.size(); - READWRITE(nSize); - for (std::set::iterator it2 = vNew.begin(); it2 != vNew.end(); it2++) + for ( + std::vector >::iterator it = am->vvNew.begin(); + it != am->vvNew.end(); + it++ + ) { - int nIndex = mapUnkIds[*it2]; + std::set + &vNew = (*it); + + int + nSize = int( vNew.size() ); + + READWRITE(nSize); + for (std::set::iterator it2 = vNew.begin(); it2 != vNew.end(); it2++) + { + int + nIndex = mapUnkIds[*it2]; READWRITE(nIndex); + } } - } - } else { - int nUBuckets = 0; - READWRITE(nUBuckets); - am->nIdCount = 0; - am->mapInfo.clear(); - am->mapAddr.clear(); - am->vRandom.clear(); - am->vvTried = std::vector >(ADDRMAN_TRIED_BUCKET_COUNT, std::vector(0)); - am->vvNew = std::vector >(ADDRMAN_NEW_BUCKET_COUNT, std::set()); - for (int n = 0; n < am->nNew; n++) + } + else { - CAddrInfo &info = am->mapInfo[n]; - READWRITE(info); - am->mapAddr[info] = n; - info.nRandomPos = vRandom.size(); - am->vRandom.push_back(n); - if (nUBuckets != ADDRMAN_NEW_BUCKET_COUNT) + int + nUBuckets = 0; + + READWRITE(nUBuckets); + am->nIdCount = 0; + am->mapInfo.clear(); + am->mapAddr.clear(); + am->vRandom.clear(); + am->vvTried = + std::vector >( + ADDRMAN_TRIED_BUCKET_COUNT, + std::vector(0) + ); + am->vvNew = + std::vector >( + ADDRMAN_NEW_BUCKET_COUNT, + std::set() + ); + for (int n = 0; n < am->nNew; n++) { - am->vvNew[info.GetNewBucket(am->nKey)].insert(n); - info.nRefCount++; + CAddrInfo + &info = am->mapInfo[n]; + + READWRITE(info); + am->mapAddr[info] = n; + info.nRandomPos = int( vRandom.size() ); + am->vRandom.push_back(n); + if (nUBuckets != ADDRMAN_NEW_BUCKET_COUNT) + { + am->vvNew[info.GetNewBucket(am->nKey)].insert(n); + info.nRefCount++; + } } - } - am->nIdCount = am->nNew; - int nLost = 0; - for (int n = 0; n < am->nTried; n++) - { - CAddrInfo info; - READWRITE(info); - std::vector &vTried = am->vvTried[info.GetTriedBucket(am->nKey)]; - if (vTried.size() < ADDRMAN_TRIED_BUCKET_SIZE) + am->nIdCount = am->nNew; + + int + nLost = 0; + + for (int n = 0; n < am->nTried; n++) { - info.nRandomPos = vRandom.size(); - info.fInTried = true; - am->vRandom.push_back(am->nIdCount); - am->mapInfo[am->nIdCount] = info; - am->mapAddr[info] = am->nIdCount; - vTried.push_back(am->nIdCount); - am->nIdCount++; - } else { - nLost++; + CAddrInfo + info; + + READWRITE(info); + + std::vector + &vTried = am->vvTried[info.GetTriedBucket(am->nKey)]; + + if (vTried.size() < ADDRMAN_TRIED_BUCKET_SIZE) + { + info.nRandomPos = int( vRandom.size() ); + info.fInTried = true; + am->vRandom.push_back(am->nIdCount); + am->mapInfo[am->nIdCount] = info; + am->mapAddr[info] = am->nIdCount; + vTried.push_back(am->nIdCount); + am->nIdCount++; + } + else + { + nLost++; + } } - } - am->nTried -= nLost; - for (int b = 0; b < nUBuckets; b++) - { - std::set &vNew = am->vvNew[b]; - int nSize = 0; - READWRITE(nSize); - for (int n = 0; n < nSize; n++) + am->nTried -= nLost; + for (int b = 0; b < nUBuckets; b++) { - int nIndex = 0; - READWRITE(nIndex); - CAddrInfo &info = am->mapInfo[nIndex]; - if (nUBuckets == ADDRMAN_NEW_BUCKET_COUNT && info.nRefCount < ADDRMAN_NEW_BUCKETS_PER_ADDRESS) + std::set + &vNew = am->vvNew[b]; + + int + nSize = 0; + + READWRITE(nSize); + for (int n = 0; n < nSize; n++) { - info.nRefCount++; - vNew.insert(nIndex); + int + nIndex = 0; + + READWRITE(nIndex); + + CAddrInfo + &info = am->mapInfo[nIndex]; + + if ( + (nUBuckets == ADDRMAN_NEW_BUCKET_COUNT) && + (info.nRefCount < ADDRMAN_NEW_BUCKETS_PER_ADDRESS) + ) + { + info.nRefCount++; + vNew.insert(nIndex); + } } } } - } - } - });) + ) + CAddrMan() : vRandom(0), vvTried(ADDRMAN_TRIED_BUCKET_COUNT, std::vector(0)), vvNew(ADDRMAN_NEW_BUCKET_COUNT, std::set()) { @@ -391,15 +433,15 @@ public: // Return the number of (unique) addresses in all tables. int size() { - return vRandom.size(); + return (int) vRandom.size(); } // Consistency check void Check() { #ifdef DEBUG_ADDRMAN - CRITICAL_BLOCK(cs) { + LOCK(cs); int err; if ((err=Check_())) printf("ADDRMAN CONSISTENCY CHECK FAILED!!! err=%i\n", err); @@ -408,11 +450,11 @@ public: } // Add a single address. - bool Add(const CAddress &addr, const CNetAddr& source, int64 nTimePenalty = 0) + bool Add(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty = 0) { bool fRet = false; - CRITICAL_BLOCK(cs) { + LOCK(cs); Check(); fRet |= Add_(addr, source, nTimePenalty); Check(); @@ -423,11 +465,11 @@ public: } // Add multiple addresses. - bool Add(const std::vector &vAddr, const CNetAddr& source, int64 nTimePenalty = 0) + bool Add(const std::vector &vAddr, const CNetAddr& source, int64_t nTimePenalty = 0) { int nAdd = 0; - CRITICAL_BLOCK(cs) { + LOCK(cs); Check(); for (std::vector::const_iterator it = vAddr.begin(); it != vAddr.end(); it++) nAdd += Add_(*it, source, nTimePenalty) ? 1 : 0; @@ -439,10 +481,10 @@ public: } // Mark an entry as accessible. - void Good(const CService &addr, int64 nTime = GetAdjustedTime()) + void Good(const CService &addr, int64_t nTime = GetAdjustedTime()) { - CRITICAL_BLOCK(cs) { + LOCK(cs); Check(); Good_(addr, nTime); Check(); @@ -450,10 +492,10 @@ public: } // Mark an entry as connection attempted to. - void Attempt(const CService &addr, int64 nTime = GetAdjustedTime()) + void Attempt(const CService &addr, int64_t nTime = GetAdjustedTime()) { - CRITICAL_BLOCK(cs) { + LOCK(cs); Check(); Attempt_(addr, nTime); Check(); @@ -465,8 +507,8 @@ public: CAddress Select(int nUnkBias = 50) { CAddress addrRet; - CRITICAL_BLOCK(cs) { + LOCK(cs); Check(); addrRet = Select_(nUnkBias); Check(); @@ -479,17 +521,31 @@ public: { Check(); std::vector vAddr; - CRITICAL_BLOCK(cs) + { + LOCK(cs); GetAddr_(vAddr); + } + Check(); + return vAddr; + } + + std::vector GetOnlineAddr() + { + Check(); + std::vector vAddr; + { + LOCK(cs); + GetOnlineAddr_(vAddr); + } Check(); return vAddr; } // Mark an entry as currently-connected-to. - void Connected(const CService &addr, int64 nTime = GetAdjustedTime()) + void Connected(const CService &addr, int64_t nTime = GetAdjustedTime()) { - CRITICAL_BLOCK(cs) { + LOCK(cs); Check(); Connected_(addr, nTime); Check();