Changeset View
Changeset View
Standalone View
Standalone View
src/addrman.cpp
Show First 20 Lines • Show All 209 Lines • ▼ Show 20 Lines | void CAddrMan::MakeTried(CAddrInfo &info, int nId) { | ||||
} | } | ||||
assert(vvTried[nKBucket][nKBucketPos] == -1); | assert(vvTried[nKBucket][nKBucketPos] == -1); | ||||
vvTried[nKBucket][nKBucketPos] = nId; | vvTried[nKBucket][nKBucketPos] = nId; | ||||
nTried++; | nTried++; | ||||
info.fInTried = true; | info.fInTried = true; | ||||
} | } | ||||
void CAddrMan::Good_(const CService &addr, int64_t nTime) { | void CAddrMan::Good_(const CService &addr, bool test_before_evict, | ||||
int64_t nTime) { | |||||
int nId; | int nId; | ||||
nLastGood = nTime; | nLastGood = nTime; | ||||
CAddrInfo *pinfo = Find(addr, &nId); | CAddrInfo *pinfo = Find(addr, &nId); | ||||
// if not found, bail out | // if not found, bail out | ||||
if (!pinfo) { | if (!pinfo) { | ||||
Show All 33 Lines | void CAddrMan::Good_(const CService &addr, bool test_before_evict, | ||||
} | } | ||||
// if no bucket is found, something bad happened; | // if no bucket is found, something bad happened; | ||||
// TODO: maybe re-add the node, but for now, just bail out | // TODO: maybe re-add the node, but for now, just bail out | ||||
if (nUBucket == -1) { | if (nUBucket == -1) { | ||||
return; | return; | ||||
} | } | ||||
// which tried bucket to move the entry to | |||||
int tried_bucket = info.GetTriedBucket(nKey); | |||||
int tried_bucket_pos = info.GetBucketPosition(nKey, false, tried_bucket); | |||||
// Will moving this address into tried evict another entry? | |||||
if (test_before_evict && (vvTried[tried_bucket][tried_bucket_pos] != -1)) { | |||||
LogPrint(BCLog::ADDRMAN, "addrman", "Collision inserting element into " | |||||
"tried table, moving %s to " | |||||
"m_tried_collisions=%d\n", | |||||
addr.ToString(), m_tried_collisions.size()); | |||||
if (m_tried_collisions.size() < ADDRMAN_SET_TRIED_COLLISION_SIZE) { | |||||
m_tried_collisions.insert(nId); | |||||
} | |||||
} else { | |||||
LogPrint(BCLog::ADDRMAN, "Moving %s to tried\n", addr.ToString()); | LogPrint(BCLog::ADDRMAN, "Moving %s to tried\n", addr.ToString()); | ||||
// move nId to the tried tables | // move nId to the tried tables | ||||
MakeTried(info, nId); | MakeTried(info, nId); | ||||
} | } | ||||
} | |||||
bool CAddrMan::Add_(const CAddress &addr, const CNetAddr &source, | bool CAddrMan::Add_(const CAddress &addr, const CNetAddr &source, | ||||
int64_t nTimePenalty) { | int64_t nTimePenalty) { | ||||
if (!addr.IsRoutable()) { | if (!addr.IsRoutable()) { | ||||
return false; | return false; | ||||
} | } | ||||
bool fNew = false; | bool fNew = false; | ||||
▲ Show 20 Lines • Show All 326 Lines • ▼ Show 20 Lines | void CAddrMan::SetServices_(const CService &addr, ServiceFlags nServices) { | ||||
// update info | // update info | ||||
info.nServices = nServices; | info.nServices = nServices; | ||||
} | } | ||||
int CAddrMan::RandomInt(int nMax) { | int CAddrMan::RandomInt(int nMax) { | ||||
return GetRandInt(nMax); | return GetRandInt(nMax); | ||||
} | } | ||||
void CAddrMan::ResolveCollisions_() { | |||||
const int64_t adjustedTime = GetAdjustedTime(); | |||||
for (std::set<int>::iterator it = m_tried_collisions.begin(); | |||||
it != m_tried_collisions.end();) { | |||||
int id_new = *it; | |||||
bool erase_collision = false; | |||||
// If id_new not found in mapInfo remove it from m_tried_collisions. | |||||
auto id_new_it = mapInfo.find(id_new); | |||||
if (id_new_it == mapInfo.end()) { | |||||
erase_collision = true; | |||||
} else { | |||||
CAddrInfo &info_new = id_new_it->second; | |||||
// Which tried bucket to move the entry to. | |||||
int tried_bucket = info_new.GetTriedBucket(nKey); | |||||
int tried_bucket_pos = | |||||
info_new.GetBucketPosition(nKey, false, tried_bucket); | |||||
if (!info_new.IsValid()) { | |||||
// id_new may no longer map to a valid address | |||||
erase_collision = true; | |||||
} else if (vvTried[tried_bucket][tried_bucket_pos] != -1) { | |||||
// The position in the tried bucket is not empty | |||||
// Get the to-be-evicted address that is being tested | |||||
int id_old = vvTried[tried_bucket][tried_bucket_pos]; | |||||
CAddrInfo &info_old = mapInfo[id_old]; | |||||
// Has successfully connected in last X hours | |||||
if (adjustedTime - info_old.nLastSuccess < | |||||
ADDRMAN_REPLACEMENT_SECONDS) { | |||||
erase_collision = true; | |||||
} else if (adjustedTime - info_old.nLastTry < | |||||
ADDRMAN_REPLACEMENT_SECONDS) { | |||||
// attempted to connect and failed in last X hours | |||||
// Give address at least 60 seconds to successfully connect | |||||
if (GetAdjustedTime() - info_old.nLastTry > 60) { | |||||
LogPrint(BCLog::ADDRMAN, "addrman", | |||||
"Swapping %s for %s in tried table\n", | |||||
info_new.ToString(), info_old.ToString()); | |||||
// Replaces an existing address already in the tried | |||||
// table with the new address | |||||
Good_(info_new, false, GetAdjustedTime()); | |||||
erase_collision = true; | |||||
} | |||||
} | |||||
} else { | |||||
// Collision is not actually a collision anymore | |||||
Good_(info_new, false, adjustedTime); | |||||
erase_collision = true; | |||||
} | |||||
} | |||||
if (erase_collision) { | |||||
m_tried_collisions.erase(it++); | |||||
} else { | |||||
it++; | |||||
} | |||||
} | |||||
} | |||||
CAddrInfo CAddrMan::SelectTriedCollision_() { | |||||
if (m_tried_collisions.size() == 0) { | |||||
return CAddrInfo(); | |||||
} | |||||
std::set<int>::iterator it = m_tried_collisions.begin(); | |||||
// Selects a random element from m_tried_collisions. | |||||
std::advance(it, GetRandInt(m_tried_collisions.size())); | |||||
int id_new = *it; | |||||
// If id_new not found in mapInfo remove it from m_tried_collisions. | |||||
auto id_new_it = mapInfo.find(id_new); | |||||
if (id_new_it == mapInfo.end()) { | |||||
m_tried_collisions.erase(it); | |||||
return CAddrInfo(); | |||||
} | |||||
CAddrInfo &newInfo = id_new_it->second; | |||||
// which tried bucket to move the entry to | |||||
int tried_bucket = newInfo.GetTriedBucket(nKey); | |||||
int tried_bucket_pos = newInfo.GetBucketPosition(nKey, false, tried_bucket); | |||||
int id_old = vvTried[tried_bucket][tried_bucket_pos]; | |||||
return mapInfo[id_old]; | |||||
} |