mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-10 22:18:54 +01:00
addrman: add function to return size by network and table
For now, the new functionality will be used in the context of querying fixed seeds. Other possible applications for future changes is the use in the context of making automatic connections to specific networks, or making more detailed info about addrman accessible via rpc.
This commit is contained in:
@@ -291,6 +291,7 @@ void AddrManImpl::Unserialize(Stream& s_)
|
||||
mapAddr[info] = n;
|
||||
info.nRandomPos = vRandom.size();
|
||||
vRandom.push_back(n);
|
||||
m_network_counts[info.GetNetwork()].n_new++;
|
||||
}
|
||||
nIdCount = nNew;
|
||||
|
||||
@@ -310,6 +311,7 @@ void AddrManImpl::Unserialize(Stream& s_)
|
||||
mapAddr[info] = nIdCount;
|
||||
vvTried[nKBucket][nKBucketPos] = nIdCount;
|
||||
nIdCount++;
|
||||
m_network_counts[info.GetNetwork()].n_tried++;
|
||||
} else {
|
||||
nLost++;
|
||||
}
|
||||
@@ -464,6 +466,7 @@ void AddrManImpl::Delete(int nId)
|
||||
assert(info.nRefCount == 0);
|
||||
|
||||
SwapRandom(info.nRandomPos, vRandom.size() - 1);
|
||||
m_network_counts[info.GetNetwork()].n_new--;
|
||||
vRandom.pop_back();
|
||||
mapAddr.erase(info);
|
||||
mapInfo.erase(nId);
|
||||
@@ -504,6 +507,7 @@ void AddrManImpl::MakeTried(AddrInfo& info, int nId)
|
||||
}
|
||||
}
|
||||
nNew--;
|
||||
m_network_counts[info.GetNetwork()].n_new--;
|
||||
|
||||
assert(info.nRefCount == 0);
|
||||
|
||||
@@ -522,6 +526,7 @@ void AddrManImpl::MakeTried(AddrInfo& info, int nId)
|
||||
infoOld.fInTried = false;
|
||||
vvTried[nKBucket][nKBucketPos] = -1;
|
||||
nTried--;
|
||||
m_network_counts[infoOld.GetNetwork()].n_tried--;
|
||||
|
||||
// find which new bucket it belongs to
|
||||
int nUBucket = infoOld.GetNewBucket(nKey, m_netgroupman);
|
||||
@@ -533,6 +538,7 @@ void AddrManImpl::MakeTried(AddrInfo& info, int nId)
|
||||
infoOld.nRefCount = 1;
|
||||
vvNew[nUBucket][nUBucketPos] = nIdEvict;
|
||||
nNew++;
|
||||
m_network_counts[infoOld.GetNetwork()].n_new++;
|
||||
LogPrint(BCLog::ADDRMAN, "Moved %s from tried[%i][%i] to new[%i][%i] to make space\n",
|
||||
infoOld.ToString(), nKBucket, nKBucketPos, nUBucket, nUBucketPos);
|
||||
}
|
||||
@@ -541,6 +547,7 @@ void AddrManImpl::MakeTried(AddrInfo& info, int nId)
|
||||
vvTried[nKBucket][nKBucketPos] = nId;
|
||||
nTried++;
|
||||
info.fInTried = true;
|
||||
m_network_counts[info.GetNetwork()].n_tried++;
|
||||
}
|
||||
|
||||
bool AddrManImpl::AddSingle(const CAddress& addr, const CNetAddr& source, std::chrono::seconds time_penalty)
|
||||
@@ -592,6 +599,7 @@ bool AddrManImpl::AddSingle(const CAddress& addr, const CNetAddr& source, std::c
|
||||
pinfo = Create(addr, source, &nId);
|
||||
pinfo->nTime = std::max(NodeSeconds{0s}, pinfo->nTime - time_penalty);
|
||||
nNew++;
|
||||
m_network_counts[pinfo->GetNetwork()].n_new++;
|
||||
}
|
||||
|
||||
int nUBucket = pinfo->GetNewBucket(nKey, source, m_netgroupman);
|
||||
@@ -962,6 +970,28 @@ std::optional<AddressPosition> AddrManImpl::FindAddressEntry_(const CAddress& ad
|
||||
}
|
||||
}
|
||||
|
||||
size_t AddrManImpl::Size_(std::optional<Network> net, std::optional<bool> in_new) const
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
|
||||
if (!net.has_value()) {
|
||||
if (in_new.has_value()) {
|
||||
return *in_new ? nNew : nTried;
|
||||
} else {
|
||||
return vRandom.size();
|
||||
}
|
||||
}
|
||||
if (auto it = m_network_counts.find(*net); it != m_network_counts.end()) {
|
||||
auto net_count = it->second;
|
||||
if (in_new.has_value()) {
|
||||
return *in_new ? net_count.n_new : net_count.n_tried;
|
||||
} else {
|
||||
return net_count.n_new + net_count.n_tried;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AddrManImpl::Check() const
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
@@ -986,6 +1016,7 @@ int AddrManImpl::CheckAddrman() const
|
||||
|
||||
std::unordered_set<int> setTried;
|
||||
std::unordered_map<int, int> mapNew;
|
||||
std::unordered_map<Network, NewTriedCount> local_counts;
|
||||
|
||||
if (vRandom.size() != (size_t)(nTried + nNew))
|
||||
return -7;
|
||||
@@ -1000,12 +1031,14 @@ int AddrManImpl::CheckAddrman() const
|
||||
if (info.nRefCount)
|
||||
return -2;
|
||||
setTried.insert(n);
|
||||
local_counts[info.GetNetwork()].n_tried++;
|
||||
} else {
|
||||
if (info.nRefCount < 0 || info.nRefCount > ADDRMAN_NEW_BUCKETS_PER_ADDRESS)
|
||||
return -3;
|
||||
if (!info.nRefCount)
|
||||
return -4;
|
||||
mapNew[n] = info.nRefCount;
|
||||
local_counts[info.GetNetwork()].n_new++;
|
||||
}
|
||||
const auto it{mapAddr.find(info)};
|
||||
if (it == mapAddr.end() || it->second != n) {
|
||||
@@ -1065,6 +1098,17 @@ int AddrManImpl::CheckAddrman() const
|
||||
if (nKey.IsNull())
|
||||
return -16;
|
||||
|
||||
// It's possible that m_network_counts may have all-zero entries that local_counts
|
||||
// doesn't have if addrs from a network were being added and then removed again in the past.
|
||||
if (m_network_counts.size() < local_counts.size()) {
|
||||
return -20;
|
||||
}
|
||||
for (const auto& [net, count] : m_network_counts) {
|
||||
if (local_counts[net].n_new != count.n_new || local_counts[net].n_tried != count.n_tried) {
|
||||
return -21;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1074,6 +1118,15 @@ size_t AddrManImpl::size() const
|
||||
return vRandom.size();
|
||||
}
|
||||
|
||||
size_t AddrManImpl::Size(std::optional<Network> net, std::optional<bool> in_new) const
|
||||
{
|
||||
LOCK(cs);
|
||||
Check();
|
||||
auto ret = Size_(net, in_new);
|
||||
Check();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool AddrManImpl::Add(const std::vector<CAddress>& vAddr, const CNetAddr& source, std::chrono::seconds time_penalty)
|
||||
{
|
||||
LOCK(cs);
|
||||
@@ -1191,6 +1244,11 @@ size_t AddrMan::size() const
|
||||
return m_impl->size();
|
||||
}
|
||||
|
||||
size_t AddrMan::Size(std::optional<Network> net, std::optional<bool> in_new) const
|
||||
{
|
||||
return m_impl->Size(net, in_new);
|
||||
}
|
||||
|
||||
bool AddrMan::Add(const std::vector<CAddress>& vAddr, const CNetAddr& source, std::chrono::seconds time_penalty)
|
||||
{
|
||||
return m_impl->Add(vAddr, source, time_penalty);
|
||||
|
||||
Reference in New Issue
Block a user