diff --git a/src/addrman.h b/src/addrman.h index cf059478a59..eaedfd318cc 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -287,7 +287,7 @@ protected: * @param[in] max_pct Maximum percentage of addresses to return (0 = all). * @param[in] network Select only addresses of this network (nullopt = all). */ - void GetAddr_(std::vector& vAddr, size_t max_addresses, size_t max_pct, std::optional network = std::nullopt) EXCLUSIVE_LOCKS_REQUIRED(cs); + void GetAddr_(std::vector& vAddr, size_t max_addresses, size_t max_pct, std::optional network) EXCLUSIVE_LOCKS_REQUIRED(cs); /** We have successfully connected to this peer. Calling this function * updates the CAddress's nTime, which is used in our IsTerrible() @@ -723,14 +723,20 @@ public: return addrRet; } - //! Return a bunch of addresses, selected at random. - std::vector GetAddr(size_t max_addresses, size_t max_pct) + /** + * Return all or many randomly selected addresses, optionally by network. + * + * @param[in] max_addresses Maximum number of addresses to return (0 = all). + * @param[in] max_pct Maximum percentage of addresses to return (0 = all). + * @param[in] network Select only addresses of this network (nullopt = all). + */ + std::vector GetAddr(size_t max_addresses, size_t max_pct, std::optional network) { Check(); std::vector vAddr; { LOCK(cs); - GetAddr_(vAddr, max_addresses, max_pct); + GetAddr_(vAddr, max_addresses, max_pct, network); } Check(); return vAddr; diff --git a/src/bench/addrman.cpp b/src/bench/addrman.cpp index ebdad5a4b8f..b7bd8a32612 100644 --- a/src/bench/addrman.cpp +++ b/src/bench/addrman.cpp @@ -7,6 +7,7 @@ #include #include +#include #include /* A "source" is a source address from which we have received a bunch of other addresses. */ @@ -98,7 +99,7 @@ static void AddrManGetAddr(benchmark::Bench& bench) FillAddrMan(addrman); bench.run([&] { - const auto& addresses = addrman.GetAddr(2500, 23); + const auto& addresses = addrman.GetAddr(/* max_addresses */ 2500, /* max_pct */ 23, /* network */ std::nullopt); assert(addresses.size() > 0); }); } diff --git a/src/net.cpp b/src/net.cpp index 909b7622e38..dfdf9eb8fab 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2671,7 +2671,7 @@ CConnman::~CConnman() std::vector CConnman::GetAddresses(size_t max_addresses, size_t max_pct) const { - std::vector addresses = addrman.GetAddr(max_addresses, max_pct); + std::vector addresses = addrman.GetAddr(max_addresses, max_pct, /* network */ std::nullopt); if (m_banman) { addresses.erase(std::remove_if(addresses.begin(), addresses.end(), [this](const CAddress& addr){return m_banman->IsDiscouraged(addr) || m_banman->IsBanned(addr);}), diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp index d438537606a..49b40924e02 100644 --- a/src/test/addrman_tests.cpp +++ b/src/test/addrman_tests.cpp @@ -12,6 +12,7 @@ #include +#include #include class CAddrManTest : public CAddrMan @@ -392,7 +393,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); - std::vector vAddr1 = addrman.GetAddr(/* max_addresses */ 0, /* max_pct */0); + std::vector vAddr1 = addrman.GetAddr(/* max_addresses */ 0, /* max_pct */ 0, /* network */ std::nullopt); BOOST_CHECK_EQUAL(vAddr1.size(), 0U); CAddress addr1 = CAddress(ResolveService("250.250.2.1", 8333), NODE_NONE); @@ -415,15 +416,15 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) BOOST_CHECK(addrman.Add(addr4, source2)); BOOST_CHECK(addrman.Add(addr5, source1)); - BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 0, /* max_pct */ 0).size(), 5U); + BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 0, /* max_pct */ 0, /* network */ std::nullopt).size(), 5U); // Net processing asks for 23% of addresses. 23% of 5 is 1 rounded down. - BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 2500, /* max_pct */ 23).size(), 1U); + BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 2500, /* max_pct */ 23, /* network */ std::nullopt).size(), 1U); // Test: Ensure GetAddr works with new and tried addresses. addrman.Good(CAddress(addr1, NODE_NONE)); addrman.Good(CAddress(addr2, NODE_NONE)); - BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 0, /* max_pct */ 0).size(), 5U); - BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 2500, /* max_pct */ 23).size(), 1U); + BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 0, /* max_pct */ 0, /* network */ std::nullopt).size(), 5U); + BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 2500, /* max_pct */ 23, /* network */ std::nullopt).size(), 1U); // Test: Ensure GetAddr still returns 23% when addrman has many addrs. for (unsigned int i = 1; i < (8 * 256); i++) { @@ -438,7 +439,7 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) if (i % 8 == 0) addrman.Good(addr); } - std::vector vAddr = addrman.GetAddr(/* max_addresses */ 2500, /* max_pct */ 23); + std::vector vAddr = addrman.GetAddr(/* max_addresses */ 2500, /* max_pct */ 23, /* network */ std::nullopt); size_t percent23 = (addrman.size() * 23) / 100; BOOST_CHECK_EQUAL(vAddr.size(), percent23); diff --git a/src/test/fuzz/addrman.cpp b/src/test/fuzz/addrman.cpp index 0baf30aef6f..98ae32a8d0a 100644 --- a/src/test/fuzz/addrman.cpp +++ b/src/test/fuzz/addrman.cpp @@ -60,7 +60,10 @@ FUZZ_TARGET_INIT(addrman, initialize_addrman) (void)addr_man.Select(fuzzed_data_provider.ConsumeBool()); }, [&] { - (void)addr_man.GetAddr(fuzzed_data_provider.ConsumeIntegralInRange(0, 4096), fuzzed_data_provider.ConsumeIntegralInRange(0, 4096)); + (void)addr_man.GetAddr( + /* max_addresses */ fuzzed_data_provider.ConsumeIntegralInRange(0, 4096), + /* max_pct */ fuzzed_data_provider.ConsumeIntegralInRange(0, 4096), + /* network */ std::nullopt); }, [&] { const std::optional opt_address = ConsumeDeserializable(fuzzed_data_provider);