From d35595a78a4a6cae72d3204c1ec3f82f77a10d56 Mon Sep 17 00:00:00 2001 From: Martin Zumsande Date: Tue, 29 Nov 2022 17:16:26 -0500 Subject: [PATCH 1/4] 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. --- src/addrman.cpp | 58 ++++++++++++++++++++++++++++++++++++++ src/addrman.h | 9 ++++++ src/addrman_impl.h | 12 ++++++++ src/test/addrman_tests.cpp | 38 +++++++++++++++++++++++++ 4 files changed, 117 insertions(+) diff --git a/src/addrman.cpp b/src/addrman.cpp index 9e859c4d67..89da34c419 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -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 AddrManImpl::FindAddressEntry_(const CAddress& ad } } +size_t AddrManImpl::Size_(std::optional net, std::optional 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 setTried; std::unordered_map mapNew; + std::unordered_map 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 net, std::optional in_new) const +{ + LOCK(cs); + Check(); + auto ret = Size_(net, in_new); + Check(); + return ret; +} + bool AddrManImpl::Add(const std::vector& 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 net, std::optional in_new) const +{ + return m_impl->Size(net, in_new); +} + bool AddrMan::Add(const std::vector& vAddr, const CNetAddr& source, std::chrono::seconds time_penalty) { return m_impl->Add(vAddr, source, time_penalty); diff --git a/src/addrman.h b/src/addrman.h index 0f1f808fa1..1c7254b5d7 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -102,6 +102,15 @@ public: //! 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 net, std::optional in_new) const; + /** * Attempt to add one or more addresses to addrman's new table. * diff --git a/src/addrman_impl.h b/src/addrman_impl.h index 39754b673e..f75cccb303 100644 --- a/src/addrman_impl.h +++ b/src/addrman_impl.h @@ -114,6 +114,8 @@ public: size_t size() const EXCLUSIVE_LOCKS_REQUIRED(!cs); + size_t Size(std::optional net, std::optional in_new) const EXCLUSIVE_LOCKS_REQUIRED(!cs); + bool Add(const std::vector& vAddr, const CNetAddr& source, std::chrono::seconds time_penalty) EXCLUSIVE_LOCKS_REQUIRED(!cs); @@ -215,6 +217,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 m_network_counts GUARDED_BY(cs); + //! Find an entry. AddrInfo* Find(const CService& addr, int* pnId = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs); @@ -257,6 +267,8 @@ private: std::optional FindAddressEntry_(const CAddress& addr) EXCLUSIVE_LOCKS_REQUIRED(cs); + size_t Size_(std::optional net, std::optional 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); diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp index b15df43e8c..da12441fe8 100644 --- a/src/test/addrman_tests.cpp +++ b/src/test/addrman_tests.cpp @@ -990,4 +990,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(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() From c77c877a8e916878e09f64b2faa12eeca7528cc8 Mon Sep 17 00:00:00 2001 From: Martin Zumsande Date: Wed, 30 Nov 2022 15:55:22 -0500 Subject: [PATCH 2/4] net: Load fixed seeds from reachable networks for which we don't have addresses Previously, we'd only load fixed seeds if we'd not know any addresses at all. This change makes it possible to change -onlynet abruptly, e.g. from -onlynet=onion to -onlynet=i2p and still find peers. --- src/net.cpp | 30 +++++++++++++++++++++--------- src/net.h | 7 +++++++ 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 960d0ee841..ac4fa678f6 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1575,6 +1575,19 @@ int CConnman::GetExtraBlockRelayCount() const return std::max(block_relay_peers - m_max_outbound_block_relay, 0); } +std::unordered_set CConnman::GetReachableEmptyNetworks() const +{ + std::unordered_set 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 connect) { SetSyscallSandboxPolicy(SyscallSandboxPolicy::NET_OPEN_CONNECTION); @@ -1624,7 +1637,8 @@ void CConnman::ThreadOpenConnections(const std::vector connect) if (interruptNet) return; - if (add_fixed_seeds && addrman.size() == 0) { + const std::unordered_set 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 @@ -1633,7 +1647,7 @@ void CConnman::ThreadOpenConnections(const std::vector connect) // It is cheapest to check if enough time has passed first. if (GetTime() > 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. @@ -1650,14 +1664,12 @@ void CConnman::ThreadOpenConnections(const std::vector connect) // 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 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); diff --git a/src/net.h b/src/net.h index 31d17ea76c..666e0f3b8a 100644 --- a/src/net.h +++ b/src/net.h @@ -39,6 +39,7 @@ #include #include #include +#include #include class AddrMan; @@ -969,6 +970,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 GetReachableEmptyNetworks() const; + /** * Return vector of current BLOCK_RELAY peers. */ From 4885d6f197736cb89fdfac250b280ec10829d903 Mon Sep 17 00:00:00 2001 From: Martin Zumsande Date: Mon, 16 Jan 2023 15:59:11 -0500 Subject: [PATCH 3/4] addrman, refactor: move count increment into Create() Create() is only called in one spot, so this doesn't change behavior. Co-authored-by: Amiti Uttarwar --- src/addrman.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/addrman.cpp b/src/addrman.cpp index 89da34c419..4ffb7617b0 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -427,6 +427,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]; @@ -598,8 +600,6 @@ bool AddrManImpl::AddSingle(const CAddress& addr, const CNetAddr& source, std::c } else { 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); From 80f39c99ef2d30e3e2d8dbc068d25cf92aa32344 Mon Sep 17 00:00:00 2001 From: Amiti Uttarwar Date: Fri, 13 Jan 2023 14:23:38 -0800 Subject: [PATCH 4/4] addrman, refactor: combine two size functions The functionality of the old size() is covered by the new Size() when no arguments are specified, so this does not change behavior. Co-authored-by: Martin Zumsande --- src/addrdb.cpp | 2 +- src/addrman.cpp | 11 ------ src/addrman.h | 5 +-- src/addrman_impl.h | 2 -- src/net.cpp | 8 ++--- src/test/addrman_tests.cpp | 74 +++++++++++++++++++------------------- src/test/fuzz/addrman.cpp | 4 +-- 7 files changed, 45 insertions(+), 61 deletions(-) diff --git a/src/addrdb.cpp b/src/addrdb.cpp index d95c07d6a8..745bce5c3b 100644 --- a/src/addrdb.cpp +++ b/src/addrdb.cpp @@ -191,7 +191,7 @@ std::optional LoadAddrman(const NetGroupManager& netgroupman, con const auto path_addr{args.GetDataDirNet() / "peers.dat"}; try { DeserializeFileDB(path_addr, *addrman, CLIENT_VERSION); - LogPrintf("Loaded %i addresses from peers.dat %dms\n", addrman->size(), Ticks(SteadyClock::now() - start)); + LogPrintf("Loaded %i addresses from peers.dat %dms\n", addrman->Size(), Ticks(SteadyClock::now() - start)); } catch (const DbNotFoundError&) { // Addrman can be in an inconsistent state after failure, reset it addrman = std::make_unique(netgroupman, /*deterministic=*/false, /*consistency_check_ratio=*/check_addrman); diff --git a/src/addrman.cpp b/src/addrman.cpp index 4ffb7617b0..01ea723dd2 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -1112,12 +1112,6 @@ int AddrManImpl::CheckAddrman() const return 0; } -size_t AddrManImpl::size() const -{ - LOCK(cs); // TODO: Cache this in an atomic to avoid this overhead - return vRandom.size(); -} - size_t AddrManImpl::Size(std::optional net, std::optional in_new) const { LOCK(cs); @@ -1239,11 +1233,6 @@ template void AddrMan::Unserialize(CHashVerifier& s); template void AddrMan::Unserialize(CDataStream& s); template void AddrMan::Unserialize(CHashVerifier& s); -size_t AddrMan::size() const -{ - return m_impl->size(); -} - size_t AddrMan::Size(std::optional net, std::optional in_new) const { return m_impl->Size(net, in_new); diff --git a/src/addrman.h b/src/addrman.h index 1c7254b5d7..2a074268be 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -99,9 +99,6 @@ public: template void Unserialize(Stream& s_); - //! Return the number of (unique) addresses in all tables. - size_t size() const; - /** * Return size information about addrman. * @@ -109,7 +106,7 @@ public: * @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 net, std::optional in_new) const; + size_t Size(std::optional net = {}, std::optional in_new = {}) const; /** * Attempt to add one or more addresses to addrman's new table. diff --git a/src/addrman_impl.h b/src/addrman_impl.h index f75cccb303..94fe81aca9 100644 --- a/src/addrman_impl.h +++ b/src/addrman_impl.h @@ -112,8 +112,6 @@ public: template void Unserialize(Stream& s_) EXCLUSIVE_LOCKS_REQUIRED(!cs); - size_t size() const EXCLUSIVE_LOCKS_REQUIRED(!cs); - size_t Size(std::optional net, std::optional in_new) const EXCLUSIVE_LOCKS_REQUIRED(!cs); bool Add(const std::vector& vAddr, const CNetAddr& source, std::chrono::seconds time_penalty) diff --git a/src/net.cpp b/src/net.cpp index ac4fa678f6..7cab662265 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1399,7 +1399,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. @@ -1418,13 +1418,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) { @@ -1504,7 +1504,7 @@ void CConnman::DumpAddresses() DumpPeerAddresses(::gArgs, addrman); LogPrint(BCLog::NET, "Flushed %d addresses to peers.dat %dms\n", - addrman.size(), Ticks(SteadyClock::now() - start)); + addrman.Size(), Ticks(SteadyClock::now() - start)); } void CConnman::ProcessAddrFetch() diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp index da12441fe8..cf7bb776cc 100644 --- a/src/test/addrman_tests.cpp +++ b/src/test/addrman_tests.cpp @@ -67,14 +67,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"); @@ -82,7 +82,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 @@ -93,7 +93,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(EMPTY_NETGROUPMAN, DETERMINISTIC, GetCheckRatio(m_node)); @@ -101,7 +101,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) @@ -110,23 +110,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"); @@ -142,7 +142,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; @@ -150,14 +150,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. @@ -182,7 +182,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 ports; @@ -200,25 +200,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) @@ -236,7 +236,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 - @@ -250,7 +250,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) @@ -261,7 +261,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)); @@ -290,7 +290,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 vAddr1 = addrman->GetAddr(/*max_addresses=*/0, /*max_pct=*/0, /*network=*/std::nullopt); BOOST_CHECK_EQUAL(vAddr1.size(), 0U); @@ -336,11 +336,11 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) } std::vector 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); } @@ -681,7 +681,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; @@ -704,14 +704,14 @@ BOOST_AUTO_TEST_CASE(remove_invalid) addrman = std::make_unique(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(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"); @@ -796,7 +796,7 @@ BOOST_AUTO_TEST_CASE(addrman_evictionworks) { auto addrman = std::make_unique(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"); @@ -878,14 +878,14 @@ BOOST_AUTO_TEST_CASE(load_addrman) BOOST_CHECK(Lookup("252.5.1.1", source, 8333, false)); std::vector 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; @@ -894,16 +894,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. @@ -939,7 +939,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; @@ -948,14 +948,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); } @@ -969,7 +969,7 @@ BOOST_AUTO_TEST_CASE(addrman_update_address) const auto start_time{Now() - 10000s}; 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)}; diff --git a/src/test/fuzz/addrman.cpp b/src/test/fuzz/addrman.cpp index 2953cf149d..a59e41dbb5 100644 --- a/src/test/fuzz/addrman.cpp +++ b/src/test/fuzz/addrman.cpp @@ -117,7 +117,7 @@ void FillAddrman(AddrMan& addrman, FuzzedDataProvider& fuzzed_data_provider) const std::chrono::seconds 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, Now()); } @@ -304,7 +304,7 @@ FUZZ_TARGET_INIT(addrman, initialize_addrman) /*max_pct=*/fuzzed_data_provider.ConsumeIntegralInRange(0, 4096), /*network=*/std::nullopt); (void)const_addr_man.Select(fuzzed_data_provider.ConsumeBool()); - (void)const_addr_man.size(); + (void)const_addr_man.Size(); CDataStream data_stream(SER_NETWORK, PROTOCOL_VERSION); data_stream << const_addr_man; }