Merge #15486: [addrman, net] Ensure tried collisions resolve, and allow feeler connections to existing outbound netgroups
20e6ea259b
[addrman] Improve collision logging and address nits (Suhas Daftuar)f71fdda3bc
[addrman] Ensure collisions eventually get resolved (Suhas Daftuar)4991e3c813
[net] feeler connections can be made to outbound peers in same netgroup (Suhas Daftuar)4d834018e3
[addrman] Improve tried table collision logging (Suhas Daftuar) Pull request description: The restriction on outbound peers sharing the same network group is not intended to apply to feeler connections, so fix this. This fixes an issue where a tried table collision with an entry to a netgroup we already have an outbound connection to could cause feelers to stop working, because the tried collision buffer (`m_tried_collisions`) would never be drained. Also, ensure that all entries don't linger in `m_tried_collisions` by evicting an old entry if its collisions is unresolved after 40 minutes. Tree-SHA512: 553fe2b01b82cd7f0f62f90c6781e373455a45b254e3bec085b5e6b16690aa9f3938e8c50e7136f19dafa250ed4578a26227d944b76daf9ce4ef0c75802389b6
This commit is contained in:
commit
ff38148808
3 changed files with 22 additions and 4 deletions
|
@ -239,7 +239,9 @@ void CAddrMan::Good_(const CService& addr, bool test_before_evict, int64_t nTime
|
|||
|
||||
// Will moving this address into tried evict another entry?
|
||||
if (test_before_evict && (vvTried[tried_bucket][tried_bucket_pos] != -1)) {
|
||||
LogPrint(BCLog::ADDRMAN, "Collision inserting element into tried table, moving %s to m_tried_collisions=%d\n", addr.ToString(), m_tried_collisions.size());
|
||||
// Output the entry we'd be colliding with, for debugging purposes
|
||||
auto colliding_entry = mapInfo.find(vvTried[tried_bucket][tried_bucket_pos]);
|
||||
LogPrint(BCLog::ADDRMAN, "Collision inserting element into tried table (%s), moving %s to m_tried_collisions=%d\n", colliding_entry != mapInfo.end() ? colliding_entry->second.ToString() : "", addr.ToString(), m_tried_collisions.size());
|
||||
if (m_tried_collisions.size() < ADDRMAN_SET_TRIED_COLLISION_SIZE) {
|
||||
m_tried_collisions.insert(nId);
|
||||
}
|
||||
|
@ -561,12 +563,19 @@ void CAddrMan::ResolveCollisions_()
|
|||
|
||||
// Give address at least 60 seconds to successfully connect
|
||||
if (GetAdjustedTime() - info_old.nLastTry > 60) {
|
||||
LogPrint(BCLog::ADDRMAN, "Swapping %s for %s in tried table\n", info_new.ToString(), info_old.ToString());
|
||||
LogPrint(BCLog::ADDRMAN, "Replacing %s with %s in tried table\n", info_old.ToString(), info_new.ToString());
|
||||
|
||||
// Replaces an existing address already in the tried table with the new address
|
||||
Good_(info_new, false, GetAdjustedTime());
|
||||
erase_collision = true;
|
||||
}
|
||||
} else if (GetAdjustedTime() - info_new.nLastSuccess > ADDRMAN_TEST_WINDOW) {
|
||||
// If the collision hasn't resolved in some reasonable amount of time,
|
||||
// just evict the old entry -- we must not be able to
|
||||
// connect to it for some reason.
|
||||
LogPrint(BCLog::ADDRMAN, "Unable to test; replacing %s with %s in tried table anyway\n", info_old.ToString(), info_new.ToString());
|
||||
Good_(info_new, false, GetAdjustedTime());
|
||||
erase_collision = true;
|
||||
}
|
||||
} else { // Collision is not actually a collision anymore
|
||||
Good_(info_new, false, GetAdjustedTime());
|
||||
|
|
|
@ -166,6 +166,9 @@ public:
|
|||
//! the maximum number of tried addr collisions to store
|
||||
#define ADDRMAN_SET_TRIED_COLLISION_SIZE 10
|
||||
|
||||
//! the maximum time we'll spend trying to resolve a tried table collision, in seconds
|
||||
static const int64_t ADDRMAN_TEST_WINDOW = 40*60; // 40 minutes
|
||||
|
||||
/**
|
||||
* Stochastical (IP) address manager
|
||||
*/
|
||||
|
|
10
src/net.cpp
10
src/net.cpp
|
@ -1765,9 +1765,15 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
|
|||
addr = addrman.Select(fFeeler);
|
||||
}
|
||||
|
||||
// if we selected an invalid address, restart
|
||||
if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr))
|
||||
// Require outbound connections, other than feelers, to be to distinct network groups
|
||||
if (!fFeeler && setConnected.count(addr.GetGroup())) {
|
||||
break;
|
||||
}
|
||||
|
||||
// if we selected an invalid or local address, restart
|
||||
if (!addr.IsValid() || IsLocal(addr)) {
|
||||
break;
|
||||
}
|
||||
|
||||
// If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
|
||||
// stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
|
||||
|
|
Loading…
Reference in a new issue