mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 03:52:49 +01:00
merge bitcoin#26847: track AddrMan totals by network and table, improve precision of adding fixed seeds
This commit is contained in:
parent
79a550ec15
commit
2e9b48a910
@ -192,7 +192,7 @@ std::optional<bilingual_str> LoadAddrman(const NetGroupManager& netgroupman, con
|
||||
const auto path_addr{gArgs.GetDataDirNet() / "peers.dat"};
|
||||
try {
|
||||
DeserializeFileDB(path_addr, *addrman, CLIENT_VERSION);
|
||||
LogPrintf("Loaded %i addresses from peers.dat %dms\n", addrman->size(), GetTimeMillis() - nStart);
|
||||
LogPrintf("Loaded %i addresses from peers.dat %dms\n", addrman->Size(), GetTimeMillis() - nStart);
|
||||
} catch (const DbNotFoundError&) {
|
||||
// Addrman can be in an inconsistent state after failure, reset it
|
||||
addrman = std::make_unique<AddrMan>(netgroupman, /*deterministic=*/false, /*consistency_check_ratio=*/check_addrman);
|
||||
|
@ -282,6 +282,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;
|
||||
|
||||
@ -301,6 +302,7 @@ void AddrManImpl::Unserialize(Stream& s_)
|
||||
mapAddr[info] = nIdCount;
|
||||
vvTried[nKBucket][nKBucketPos] = nIdCount;
|
||||
nIdCount++;
|
||||
m_network_counts[info.GetNetwork()].n_tried++;
|
||||
} else {
|
||||
nLost++;
|
||||
}
|
||||
@ -414,6 +416,8 @@ AddrInfo* AddrManImpl::Create(const CAddress& addr, const CNetAddr& addrSource,
|
||||
mapAddr[addr] = nId;
|
||||
mapInfo[nId].nRandomPos = vRandom.size();
|
||||
vRandom.push_back(nId);
|
||||
nNew++;
|
||||
m_network_counts[addr.GetNetwork()].n_new++;
|
||||
if (pnId)
|
||||
*pnId = nId;
|
||||
return &mapInfo[nId];
|
||||
@ -453,6 +457,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);
|
||||
@ -493,6 +498,7 @@ void AddrManImpl::MakeTried(AddrInfo& info, int nId)
|
||||
}
|
||||
}
|
||||
nNew--;
|
||||
m_network_counts[info.GetNetwork()].n_new--;
|
||||
|
||||
assert(info.nRefCount == 0);
|
||||
|
||||
@ -511,6 +517,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);
|
||||
@ -522,6 +529,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);
|
||||
}
|
||||
@ -530,6 +538,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, int64_t nTimePenalty)
|
||||
@ -580,7 +589,6 @@ bool AddrManImpl::AddSingle(const CAddress& addr, const CNetAddr& source, int64_
|
||||
} else {
|
||||
pinfo = Create(addr, source, &nId);
|
||||
pinfo->nTime = std::max((int64_t)0, (int64_t)pinfo->nTime - nTimePenalty);
|
||||
nNew++;
|
||||
}
|
||||
|
||||
int nUBucket = pinfo->GetNewBucket(nKey, source, m_netgroupman);
|
||||
@ -965,6 +973,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);
|
||||
@ -989,6 +1019,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;
|
||||
@ -1002,12 +1033,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,13 +1098,27 @@ 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;
|
||||
}
|
||||
|
||||
size_t AddrManImpl::size() const
|
||||
size_t AddrManImpl::Size(std::optional<Network> net, std::optional<bool> in_new) const
|
||||
{
|
||||
LOCK(cs); // TODO: Cache this in an atomic to avoid this overhead
|
||||
return vRandom.size();
|
||||
LOCK(cs);
|
||||
Check();
|
||||
auto ret = Size_(net, in_new);
|
||||
Check();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool AddrManImpl::Add(const std::vector<CAddress>& vAddr, const CNetAddr& source, int64_t nTimePenalty)
|
||||
@ -1197,9 +1244,9 @@ template void AddrMan::Unserialize(CHashVerifier<CAutoFile>& s);
|
||||
template void AddrMan::Unserialize(CDataStream& s);
|
||||
template void AddrMan::Unserialize(CHashVerifier<CDataStream>& s);
|
||||
|
||||
size_t AddrMan::size() const
|
||||
size_t AddrMan::Size(std::optional<Network> net, std::optional<bool> in_new) const
|
||||
{
|
||||
return m_impl->size();
|
||||
return m_impl->Size(net, in_new);
|
||||
}
|
||||
|
||||
bool AddrMan::Add(const std::vector<CAddress>& vAddr, const CNetAddr& source, int64_t nTimePenalty)
|
||||
|
@ -110,8 +110,14 @@ public:
|
||||
template <typename Stream>
|
||||
void Unserialize(Stream& s_);
|
||||
|
||||
//! Return the number of (unique) addresses in all tables.
|
||||
size_t size() const;
|
||||
/**
|
||||
* Return size information about addrman.
|
||||
*
|
||||
* @param[in] net Select addresses only from specified network (nullopt = all)
|
||||
* @param[in] in_new Select addresses only from one table (true = new, false = tried, nullopt = both)
|
||||
* @return Number of unique addresses that match specified options.
|
||||
*/
|
||||
size_t Size(std::optional<Network> net = {}, std::optional<bool> in_new = {}) const;
|
||||
|
||||
/**
|
||||
* Attempt to add one or more addresses to addrman's new table.
|
||||
|
@ -110,7 +110,7 @@ public:
|
||||
template <typename Stream>
|
||||
void Unserialize(Stream& s_) EXCLUSIVE_LOCKS_REQUIRED(!cs);
|
||||
|
||||
size_t size() const EXCLUSIVE_LOCKS_REQUIRED(!cs);
|
||||
size_t Size(std::optional<Network> net, std::optional<bool> in_new) const EXCLUSIVE_LOCKS_REQUIRED(!cs);
|
||||
|
||||
bool Add(const std::vector<CAddress>& vAddr, const CNetAddr& source, int64_t nTimePenalty)
|
||||
EXCLUSIVE_LOCKS_REQUIRED(!cs);
|
||||
@ -216,6 +216,14 @@ private:
|
||||
/** Reference to the netgroup manager. netgroupman must be constructed before addrman and destructed after. */
|
||||
const NetGroupManager& m_netgroupman;
|
||||
|
||||
struct NewTriedCount {
|
||||
size_t n_new;
|
||||
size_t n_tried;
|
||||
};
|
||||
|
||||
/** Number of entries in addrman per network and new/tried table. */
|
||||
std::unordered_map<Network, NewTriedCount> m_network_counts GUARDED_BY(cs);
|
||||
|
||||
//! Find an entry.
|
||||
AddrInfo* Find(const CService& addr, int* pnId = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
|
||||
@ -260,6 +268,8 @@ private:
|
||||
|
||||
std::optional<AddressPosition> FindAddressEntry_(const CAddress& addr) EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
|
||||
size_t Size_(std::optional<Network> net, std::optional<bool> in_new) const EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
|
||||
//! Consistency check, taking into account m_consistency_check_ratio.
|
||||
//! Will std::abort if an inconsistency is detected.
|
||||
void Check() const EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
|
38
src/net.cpp
38
src/net.cpp
@ -2404,7 +2404,7 @@ void CConnman::ThreadDNSAddressSeed()
|
||||
if (gArgs.GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED)) {
|
||||
// When -forcednsseed is provided, query all.
|
||||
seeds_right_now = seeds.size();
|
||||
} else if (addrman.size() == 0) {
|
||||
} else if (addrman.Size() == 0) {
|
||||
// If we have no known peers, query all.
|
||||
// This will occur on the first run, or if peers.dat has been
|
||||
// deleted.
|
||||
@ -2423,13 +2423,13 @@ void CConnman::ThreadDNSAddressSeed()
|
||||
// * If we continue having problems, eventually query all the
|
||||
// DNS seeds, and if that fails too, also try the fixed seeds.
|
||||
// (done in ThreadOpenConnections)
|
||||
const std::chrono::seconds seeds_wait_time = (addrman.size() >= DNSSEEDS_DELAY_PEER_THRESHOLD ? DNSSEEDS_DELAY_MANY_PEERS : DNSSEEDS_DELAY_FEW_PEERS);
|
||||
const std::chrono::seconds seeds_wait_time = (addrman.Size() >= DNSSEEDS_DELAY_PEER_THRESHOLD ? DNSSEEDS_DELAY_MANY_PEERS : DNSSEEDS_DELAY_FEW_PEERS);
|
||||
|
||||
for (const std::string& seed : seeds) {
|
||||
if (seeds_right_now == 0) {
|
||||
seeds_right_now += DNSSEEDS_TO_QUERY_AT_ONCE;
|
||||
|
||||
if (addrman.size() > 0) {
|
||||
if (addrman.Size() > 0) {
|
||||
LogPrintf("Waiting %d seconds before querying DNS seeds.\n", seeds_wait_time.count());
|
||||
std::chrono::seconds to_wait = seeds_wait_time;
|
||||
while (to_wait.count() > 0) {
|
||||
@ -2513,7 +2513,7 @@ void CConnman::DumpAddresses()
|
||||
DumpPeerAddresses(::gArgs, addrman);
|
||||
|
||||
LogPrint(BCLog::NET, "Flushed %d addresses to peers.dat %dms\n",
|
||||
addrman.size(), GetTimeMillis() - nStart);
|
||||
addrman.Size(), GetTimeMillis() - nStart);
|
||||
}
|
||||
|
||||
void CConnman::ProcessAddrFetch()
|
||||
@ -2583,6 +2583,19 @@ int CConnman::GetExtraBlockRelayCount() const
|
||||
return std::max(block_relay_peers - m_max_outbound_block_relay, 0);
|
||||
}
|
||||
|
||||
std::unordered_set<Network> CConnman::GetReachableEmptyNetworks() const
|
||||
{
|
||||
std::unordered_set<Network> networks{};
|
||||
for (int n = 0; n < NET_MAX; n++) {
|
||||
enum Network net = (enum Network)n;
|
||||
if (net == NET_UNROUTABLE || net == NET_INTERNAL) continue;
|
||||
if (IsReachable(net) && addrman.Size(net, std::nullopt) == 0) {
|
||||
networks.insert(net);
|
||||
}
|
||||
}
|
||||
return networks;
|
||||
}
|
||||
|
||||
void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, CDeterministicMNManager& dmnman)
|
||||
{
|
||||
AssertLockNotHeld(m_unused_i2p_sessions_mutex);
|
||||
@ -2631,7 +2644,8 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, CDe
|
||||
if (interruptNet)
|
||||
return;
|
||||
|
||||
if (add_fixed_seeds && addrman.size() == 0) {
|
||||
const std::unordered_set<Network> fixed_seed_networks{GetReachableEmptyNetworks()};
|
||||
if (add_fixed_seeds && !fixed_seed_networks.empty()) {
|
||||
// When the node starts with an empty peers.dat, there are a few other sources of peers before
|
||||
// we fallback on to fixed seeds: -dnsseed, -seednode, -addnode
|
||||
// If none of those are available, we fallback on to fixed seeds immediately, else we allow
|
||||
@ -2640,7 +2654,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, CDe
|
||||
// It is cheapest to check if enough time has passed first.
|
||||
if (GetTime<std::chrono::seconds>() > start + std::chrono::minutes{1}) {
|
||||
add_fixed_seeds_now = true;
|
||||
LogPrintf("Adding fixed seeds as 60 seconds have passed and addrman is empty\n");
|
||||
LogPrintf("Adding fixed seeds as 60 seconds have passed and addrman is empty for at least one reachable network\n");
|
||||
}
|
||||
|
||||
// Checking !dnsseed is cheaper before locking 2 mutexes.
|
||||
@ -2657,14 +2671,12 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, CDe
|
||||
// We will not make outgoing connections to peers that are unreachable
|
||||
// (e.g. because of -onlynet configuration).
|
||||
// Therefore, we do not add them to addrman in the first place.
|
||||
// Note that if you change -onlynet setting from one network to another,
|
||||
// peers.dat will contain only peers of unreachable networks and
|
||||
// manual intervention will be needed (either delete peers.dat after
|
||||
// configuration change or manually add some reachable peer using addnode),
|
||||
// see <https://github.com/bitcoin/bitcoin/issues/26035> for details.
|
||||
// In case previously unreachable networks become reachable
|
||||
// (e.g. in case of -onlynet changes by the user), fixed seeds will
|
||||
// be loaded only for networks for which we have no addressses.
|
||||
seed_addrs.erase(std::remove_if(seed_addrs.begin(), seed_addrs.end(),
|
||||
[](const CAddress& addr) { return !IsReachable(addr); }),
|
||||
seed_addrs.end());
|
||||
[&fixed_seed_networks](const CAddress& addr) { return fixed_seed_networks.count(addr.GetNetwork()) == 0; }),
|
||||
seed_addrs.end());
|
||||
CNetAddr local;
|
||||
local.SetInternal("fixedseeds");
|
||||
addrman.Add(seed_addrs, local);
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include <optional>
|
||||
#include <queue>
|
||||
#include <thread>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
class CConnman;
|
||||
@ -1476,6 +1477,12 @@ private:
|
||||
void RecordBytesRecv(uint64_t bytes);
|
||||
void RecordBytesSent(uint64_t bytes) EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex);
|
||||
|
||||
/**
|
||||
Return reachable networks for which we have no addresses in addrman and therefore
|
||||
may require loading fixed seeds.
|
||||
*/
|
||||
std::unordered_set<Network> GetReachableEmptyNetworks() const;
|
||||
|
||||
/**
|
||||
* Return vector of current BLOCK_RELAY peers.
|
||||
*/
|
||||
|
@ -65,14 +65,14 @@ BOOST_AUTO_TEST_CASE(addrman_simple)
|
||||
CNetAddr source = ResolveIP("252.2.2.2");
|
||||
|
||||
// Test: Does Addrman respond correctly when empty.
|
||||
BOOST_CHECK_EQUAL(addrman->size(), 0U);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(), 0U);
|
||||
auto addr_null = addrman->Select().first;
|
||||
BOOST_CHECK_EQUAL(addr_null.ToString(), "[::]:0");
|
||||
|
||||
// Test: Does Addrman::Add work as expected.
|
||||
CService addr1 = ResolveService("250.1.1.1", 8333);
|
||||
BOOST_CHECK(addrman->Add({CAddress(addr1, NODE_NONE)}, source));
|
||||
BOOST_CHECK_EQUAL(addrman->size(), 1U);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(), 1U);
|
||||
auto addr_ret1 = addrman->Select().first;
|
||||
BOOST_CHECK_EQUAL(addr_ret1.ToString(), "250.1.1.1:8333");
|
||||
|
||||
@ -80,7 +80,7 @@ BOOST_AUTO_TEST_CASE(addrman_simple)
|
||||
// Expected dup IP should not be added.
|
||||
CService addr1_dup = ResolveService("250.1.1.1", 8333);
|
||||
BOOST_CHECK(!addrman->Add({CAddress(addr1_dup, NODE_NONE)}, source));
|
||||
BOOST_CHECK_EQUAL(addrman->size(), 1U);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(), 1U);
|
||||
|
||||
|
||||
// Test: New table has one addr and we add a diff addr we should
|
||||
@ -91,7 +91,7 @@ BOOST_AUTO_TEST_CASE(addrman_simple)
|
||||
|
||||
CService addr2 = ResolveService("250.1.1.2", 8333);
|
||||
BOOST_CHECK(addrman->Add({CAddress(addr2, NODE_NONE)}, source));
|
||||
BOOST_CHECK(addrman->size() >= 1);
|
||||
BOOST_CHECK(addrman->Size() >= 1);
|
||||
|
||||
// Test: reset addrman and test AddrMan::Add multiple addresses works as expected
|
||||
addrman = std::make_unique<AddrMan>(EMPTY_NETGROUPMAN, DETERMINISTIC, GetCheckRatio(m_node));
|
||||
@ -99,7 +99,7 @@ BOOST_AUTO_TEST_CASE(addrman_simple)
|
||||
vAddr.push_back(CAddress(ResolveService("250.1.1.3", 8333), NODE_NONE));
|
||||
vAddr.push_back(CAddress(ResolveService("250.1.1.4", 8333), NODE_NONE));
|
||||
BOOST_CHECK(addrman->Add(vAddr, source));
|
||||
BOOST_CHECK(addrman->size() >= 1);
|
||||
BOOST_CHECK(addrman->Size() >= 1);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(addrman_ports)
|
||||
@ -108,23 +108,23 @@ BOOST_AUTO_TEST_CASE(addrman_ports)
|
||||
|
||||
CNetAddr source = ResolveIP("252.2.2.2");
|
||||
|
||||
BOOST_CHECK_EQUAL(addrman->size(), 0U);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(), 0U);
|
||||
|
||||
// Test 7; Addr with same IP but diff port does not replace existing addr.
|
||||
CService addr1 = ResolveService("250.1.1.1", 8333);
|
||||
BOOST_CHECK(addrman->Add({CAddress(addr1, NODE_NONE)}, source));
|
||||
BOOST_CHECK_EQUAL(addrman->size(), 1U);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(), 1U);
|
||||
|
||||
CService addr1_port = ResolveService("250.1.1.1", 8334);
|
||||
BOOST_CHECK(addrman->Add({CAddress(addr1_port, NODE_NONE)}, source));
|
||||
BOOST_CHECK_EQUAL(addrman->size(), 2U);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(), 2U);
|
||||
auto addr_ret2 = addrman->Select().first;
|
||||
BOOST_CHECK(addr_ret2.ToString() == "250.1.1.1:8333" || addr_ret2.ToString() == "250.1.1.1:8334");
|
||||
|
||||
// Test: Add same IP but diff port to tried table; this converts the entry with
|
||||
// the specified port to tried, but not the other.
|
||||
addrman->Good(CAddress(addr1_port, NODE_NONE));
|
||||
BOOST_CHECK_EQUAL(addrman->size(), 2U);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(), 2U);
|
||||
bool newOnly = true;
|
||||
auto addr_ret3 = addrman->Select(newOnly).first;
|
||||
BOOST_CHECK_EQUAL(addr_ret3.ToString(), "250.1.1.1:8333");
|
||||
@ -139,7 +139,7 @@ BOOST_AUTO_TEST_CASE(addrman_select)
|
||||
// Test: Select from new with 1 addr in new.
|
||||
CService addr1 = ResolveService("250.1.1.1", 8333);
|
||||
BOOST_CHECK(addrman->Add({CAddress(addr1, NODE_NONE)}, source));
|
||||
BOOST_CHECK_EQUAL(addrman->size(), 1U);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(), 1U);
|
||||
|
||||
bool newOnly = true;
|
||||
auto addr_ret1 = addrman->Select(newOnly).first;
|
||||
@ -147,14 +147,14 @@ BOOST_AUTO_TEST_CASE(addrman_select)
|
||||
|
||||
// Test: move addr to tried, select from new expected nothing returned.
|
||||
BOOST_CHECK(addrman->Good(CAddress(addr1, NODE_NONE)));
|
||||
BOOST_CHECK_EQUAL(addrman->size(), 1U);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(), 1U);
|
||||
auto addr_ret2 = addrman->Select(newOnly).first;
|
||||
BOOST_CHECK_EQUAL(addr_ret2.ToString(), "[::]:0");
|
||||
|
||||
auto addr_ret3 = addrman->Select().first;
|
||||
BOOST_CHECK_EQUAL(addr_ret3.ToString(), "250.1.1.1:8333");
|
||||
|
||||
BOOST_CHECK_EQUAL(addrman->size(), 1U);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(), 1U);
|
||||
|
||||
|
||||
// Add three addresses to new table.
|
||||
@ -179,7 +179,7 @@ BOOST_AUTO_TEST_CASE(addrman_select)
|
||||
BOOST_CHECK(addrman->Good(CAddress(addr7, NODE_NONE)));
|
||||
|
||||
// Test: 6 addrs + 1 addr from last test = 7.
|
||||
BOOST_CHECK_EQUAL(addrman->size(), 7U);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(), 7U);
|
||||
|
||||
// Test: Select pulls from new and tried regardless of port number.
|
||||
std::set<uint16_t> ports;
|
||||
@ -197,25 +197,25 @@ BOOST_AUTO_TEST_CASE(addrman_new_collisions)
|
||||
|
||||
uint32_t num_addrs{0};
|
||||
|
||||
BOOST_CHECK_EQUAL(addrman->size(), num_addrs);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(), num_addrs);
|
||||
|
||||
while (num_addrs < 22) { // Magic number! 250.1.1.1 - 250.1.1.22 do not collide with deterministic key = 1
|
||||
CService addr = ResolveService("250.1.1." + ToString(++num_addrs));
|
||||
BOOST_CHECK(addrman->Add({CAddress(addr, NODE_NONE)}, source));
|
||||
|
||||
// Test: No collision in new table yet.
|
||||
BOOST_CHECK_EQUAL(addrman->size(), num_addrs);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(), num_addrs);
|
||||
}
|
||||
|
||||
// Test: new table collision!
|
||||
CService addr1 = ResolveService("250.1.1." + ToString(++num_addrs));
|
||||
uint32_t collisions{1};
|
||||
BOOST_CHECK(addrman->Add({CAddress(addr1, NODE_NONE)}, source));
|
||||
BOOST_CHECK_EQUAL(addrman->size(), num_addrs - collisions);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(), num_addrs - collisions);
|
||||
|
||||
CService addr2 = ResolveService("250.1.1." + ToString(++num_addrs));
|
||||
BOOST_CHECK(addrman->Add({CAddress(addr2, NODE_NONE)}, source));
|
||||
BOOST_CHECK_EQUAL(addrman->size(), num_addrs - collisions);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(), num_addrs - collisions);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(addrman_new_multiplicity)
|
||||
@ -233,7 +233,7 @@ BOOST_AUTO_TEST_CASE(addrman_new_multiplicity)
|
||||
}
|
||||
AddressPosition addr_pos = addrman->FindAddressEntry(addr).value();
|
||||
BOOST_CHECK_EQUAL(addr_pos.multiplicity, 1U);
|
||||
BOOST_CHECK_EQUAL(addrman->size(), 1U);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(), 1U);
|
||||
|
||||
// if nTime increases, an addr can occur in up to 8 buckets
|
||||
// The acceptance probability decreases exponentially with existing multiplicity -
|
||||
@ -247,7 +247,7 @@ BOOST_AUTO_TEST_CASE(addrman_new_multiplicity)
|
||||
AddressPosition addr_pos_multi = addrman->FindAddressEntry(addr).value();
|
||||
BOOST_CHECK_EQUAL(addr_pos_multi.multiplicity, 8U);
|
||||
// multiplicity doesn't affect size
|
||||
BOOST_CHECK_EQUAL(addrman->size(), 1U);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(), 1U);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(addrman_tried_collisions)
|
||||
@ -258,7 +258,7 @@ BOOST_AUTO_TEST_CASE(addrman_tried_collisions)
|
||||
|
||||
uint32_t num_addrs{0};
|
||||
|
||||
BOOST_CHECK_EQUAL(addrman->size(), num_addrs);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(), num_addrs);
|
||||
|
||||
while (num_addrs < 35) { // Magic number! 250.1.1.1 - 250.1.1.35 do not collide in tried with deterministic key = 1
|
||||
CService addr = ResolveService("250.1.1." + ToString(++num_addrs));
|
||||
@ -287,7 +287,7 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr)
|
||||
|
||||
// Test: Sanity check, GetAddr should never return anything if addrman
|
||||
// is empty.
|
||||
BOOST_CHECK_EQUAL(addrman->size(), 0U);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(), 0U);
|
||||
std::vector<CAddress> vAddr1 = addrman->GetAddr(/*max_addresses=*/0, /*max_pct=*/0, /*network=*/std::nullopt);
|
||||
BOOST_CHECK_EQUAL(vAddr1.size(), 0U);
|
||||
|
||||
@ -333,11 +333,11 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr)
|
||||
}
|
||||
std::vector<CAddress> vAddr = addrman->GetAddr(/*max_addresses=*/2500, /*max_pct=*/23, /*network=*/std::nullopt);
|
||||
|
||||
size_t percent23 = (addrman->size() * 23) / 100;
|
||||
size_t percent23 = (addrman->Size() * 23) / 100;
|
||||
BOOST_CHECK_EQUAL(vAddr.size(), percent23);
|
||||
BOOST_CHECK_EQUAL(vAddr.size(), 461U);
|
||||
// (Addrman.size() < number of addresses added) due to address collisions.
|
||||
BOOST_CHECK_EQUAL(addrman->size(), 2006U);
|
||||
// (addrman.Size() < number of addresses added) due to address collisions.
|
||||
BOOST_CHECK_EQUAL(addrman->Size(), 2006U);
|
||||
}
|
||||
|
||||
|
||||
@ -678,7 +678,7 @@ BOOST_AUTO_TEST_CASE(remove_invalid)
|
||||
addrman->Add({new1, tried1, new2, tried2}, CNetAddr{});
|
||||
addrman->Good(tried1);
|
||||
addrman->Good(tried2);
|
||||
BOOST_REQUIRE_EQUAL(addrman->size(), 4);
|
||||
BOOST_REQUIRE_EQUAL(addrman->Size(), 4);
|
||||
|
||||
stream << *addrman;
|
||||
|
||||
@ -701,14 +701,14 @@ BOOST_AUTO_TEST_CASE(remove_invalid)
|
||||
|
||||
addrman = std::make_unique<AddrMan>(EMPTY_NETGROUPMAN, DETERMINISTIC, GetCheckRatio(m_node));
|
||||
stream >> *addrman;
|
||||
BOOST_CHECK_EQUAL(addrman->size(), 2);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(), 2);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(addrman_selecttriedcollision)
|
||||
{
|
||||
auto addrman = std::make_unique<AddrMan>(EMPTY_NETGROUPMAN, DETERMINISTIC, GetCheckRatio(m_node));
|
||||
|
||||
BOOST_CHECK(addrman->size() == 0);
|
||||
BOOST_CHECK(addrman->Size() == 0);
|
||||
|
||||
// Empty addrman should return blank addrman info.
|
||||
BOOST_CHECK(addrman->SelectTriedCollision().first.ToString() == "[::]:0");
|
||||
@ -793,7 +793,7 @@ BOOST_AUTO_TEST_CASE(addrman_evictionworks)
|
||||
{
|
||||
auto addrman = std::make_unique<AddrMan>(EMPTY_NETGROUPMAN, DETERMINISTIC, GetCheckRatio(m_node));
|
||||
|
||||
BOOST_CHECK(addrman->size() == 0);
|
||||
BOOST_CHECK(addrman->Size() == 0);
|
||||
|
||||
// Empty addrman should return blank addrman info.
|
||||
BOOST_CHECK(addrman->SelectTriedCollision().first.ToString() == "[::]:0");
|
||||
@ -875,14 +875,14 @@ BOOST_AUTO_TEST_CASE(load_addrman)
|
||||
BOOST_CHECK(Lookup("252.5.1.1", source, 8333, false));
|
||||
std::vector<CAddress> addresses{CAddress(addr1, NODE_NONE), CAddress(addr2, NODE_NONE), CAddress(addr3, NODE_NONE)};
|
||||
BOOST_CHECK(addrman.Add(addresses, source));
|
||||
BOOST_CHECK(addrman.size() == 3);
|
||||
BOOST_CHECK(addrman.Size() == 3);
|
||||
|
||||
// Test that the de-serialization does not throw an exception.
|
||||
CDataStream ssPeers1 = AddrmanToStream(addrman);
|
||||
bool exceptionThrown = false;
|
||||
AddrMan addrman1{EMPTY_NETGROUPMAN, !DETERMINISTIC, GetCheckRatio(m_node)};
|
||||
|
||||
BOOST_CHECK(addrman1.size() == 0);
|
||||
BOOST_CHECK(addrman1.Size() == 0);
|
||||
try {
|
||||
unsigned char pchMsgTmp[4];
|
||||
ssPeers1 >> pchMsgTmp;
|
||||
@ -891,16 +891,16 @@ BOOST_AUTO_TEST_CASE(load_addrman)
|
||||
exceptionThrown = true;
|
||||
}
|
||||
|
||||
BOOST_CHECK(addrman1.size() == 3);
|
||||
BOOST_CHECK(addrman1.Size() == 3);
|
||||
BOOST_CHECK(exceptionThrown == false);
|
||||
|
||||
// Test that ReadFromStream creates an addrman with the correct number of addrs.
|
||||
CDataStream ssPeers2 = AddrmanToStream(addrman);
|
||||
|
||||
AddrMan addrman2{EMPTY_NETGROUPMAN, !DETERMINISTIC, GetCheckRatio(m_node)};
|
||||
BOOST_CHECK(addrman2.size() == 0);
|
||||
BOOST_CHECK(addrman2.Size() == 0);
|
||||
ReadFromStream(addrman2, ssPeers2);
|
||||
BOOST_CHECK(addrman2.size() == 3);
|
||||
BOOST_CHECK(addrman2.Size() == 3);
|
||||
}
|
||||
|
||||
// Produce a corrupt peers.dat that claims 20 addrs when it only has one addr.
|
||||
@ -936,7 +936,7 @@ BOOST_AUTO_TEST_CASE(load_addrman_corrupted)
|
||||
CDataStream ssPeers1 = MakeCorruptPeersDat();
|
||||
bool exceptionThrown = false;
|
||||
AddrMan addrman1{EMPTY_NETGROUPMAN, !DETERMINISTIC, GetCheckRatio(m_node)};
|
||||
BOOST_CHECK(addrman1.size() == 0);
|
||||
BOOST_CHECK(addrman1.Size() == 0);
|
||||
try {
|
||||
unsigned char pchMsgTmp[4];
|
||||
ssPeers1 >> pchMsgTmp;
|
||||
@ -945,14 +945,14 @@ BOOST_AUTO_TEST_CASE(load_addrman_corrupted)
|
||||
exceptionThrown = true;
|
||||
}
|
||||
// Even though de-serialization failed addrman is not left in a clean state.
|
||||
BOOST_CHECK(addrman1.size() == 1);
|
||||
BOOST_CHECK(addrman1.Size() == 1);
|
||||
BOOST_CHECK(exceptionThrown);
|
||||
|
||||
// Test that ReadFromStream fails if peers.dat is corrupt
|
||||
CDataStream ssPeers2 = MakeCorruptPeersDat();
|
||||
|
||||
AddrMan addrman2{EMPTY_NETGROUPMAN, !DETERMINISTIC, GetCheckRatio(m_node)};
|
||||
BOOST_CHECK(addrman2.size() == 0);
|
||||
BOOST_CHECK(addrman2.Size() == 0);
|
||||
BOOST_CHECK_THROW(ReadFromStream(addrman2, ssPeers2), std::ios_base::failure);
|
||||
}
|
||||
|
||||
@ -966,7 +966,7 @@ BOOST_AUTO_TEST_CASE(addrman_update_address)
|
||||
int64_t start_time{GetAdjustedTime() - 10000};
|
||||
addr.nTime = start_time;
|
||||
BOOST_CHECK(addrman->Add({addr}, source));
|
||||
BOOST_CHECK_EQUAL(addrman->size(), 1U);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(), 1U);
|
||||
|
||||
// Updating an addrman entry with a different port doesn't change it
|
||||
CAddress addr_diff_port{CAddress(ResolveService("250.1.1.1", 8334), NODE_NONE)};
|
||||
@ -987,4 +987,42 @@ BOOST_AUTO_TEST_CASE(addrman_update_address)
|
||||
BOOST_CHECK_EQUAL(vAddr2.at(0).nServices, NODE_NETWORK_LIMITED);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(addrman_size)
|
||||
{
|
||||
auto addrman = std::make_unique<AddrMan>(EMPTY_NETGROUPMAN, DETERMINISTIC, GetCheckRatio(m_node));
|
||||
const CNetAddr source = ResolveIP("252.2.2.2");
|
||||
|
||||
// empty addrman
|
||||
BOOST_CHECK_EQUAL(addrman->Size(/*net=*/std::nullopt, /*in_new=*/std::nullopt), 0U);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(/*net=*/NET_IPV4, /*in_new=*/std::nullopt), 0U);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(/*net=*/std::nullopt, /*in_new=*/true), 0U);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(/*net=*/NET_IPV4, /*in_new=*/false), 0U);
|
||||
|
||||
// add two ipv4 addresses, one to tried and new
|
||||
const CAddress addr1{ResolveService("250.1.1.1", 8333), NODE_NONE};
|
||||
BOOST_CHECK(addrman->Add({addr1}, source));
|
||||
BOOST_CHECK(addrman->Good(addr1));
|
||||
const CAddress addr2{ResolveService("250.1.1.2", 8333), NODE_NONE};
|
||||
BOOST_CHECK(addrman->Add({addr2}, source));
|
||||
|
||||
BOOST_CHECK_EQUAL(addrman->Size(/*net=*/std::nullopt, /*in_new=*/std::nullopt), 2U);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(/*net=*/NET_IPV4, /*in_new=*/std::nullopt), 2U);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(/*net=*/std::nullopt, /*in_new=*/true), 1U);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(/*net=*/std::nullopt, /*in_new=*/false), 1U);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(/*net=*/NET_IPV4, /*in_new=*/true), 1U);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(/*net=*/NET_IPV4, /*in_new=*/false), 1U);
|
||||
|
||||
// add one i2p address to new
|
||||
CService i2p_addr;
|
||||
i2p_addr.SetSpecial("UDHDrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna.b32.I2P");
|
||||
const CAddress addr3{i2p_addr, NODE_NONE};
|
||||
BOOST_CHECK(addrman->Add({addr3}, source));
|
||||
BOOST_CHECK_EQUAL(addrman->Size(/*net=*/std::nullopt, /*in_new=*/std::nullopt), 3U);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(/*net=*/NET_IPV4, /*in_new=*/std::nullopt), 2U);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(/*net=*/NET_I2P, /*in_new=*/std::nullopt), 1U);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(/*net=*/NET_I2P, /*in_new=*/true), 1U);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(/*net=*/std::nullopt, /*in_new=*/true), 2U);
|
||||
BOOST_CHECK_EQUAL(addrman->Size(/*net=*/std::nullopt, /*in_new=*/false), 1U);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
@ -116,7 +116,7 @@ void FillAddrman(AddrMan& addrman, FuzzedDataProvider& fuzzed_data_provider)
|
||||
const auto time_penalty = fast_random_context.randrange(100000001);
|
||||
addrman.Add({addr}, source, time_penalty);
|
||||
|
||||
if (n > 0 && addrman.size() % n == 0) {
|
||||
if (n > 0 && addrman.Size() % n == 0) {
|
||||
addrman.Good(addr, GetTime());
|
||||
}
|
||||
|
||||
@ -306,7 +306,7 @@ FUZZ_TARGET_INIT(addrman, initialize_addrman)
|
||||
}
|
||||
});
|
||||
}
|
||||
(void)addr_man.size();
|
||||
(void)addr_man.Size();
|
||||
CDataStream data_stream(SER_NETWORK, PROTOCOL_VERSION);
|
||||
data_stream << addr_man;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user