Skip to content

Commit cf27db8

Browse files
kwvgUdjinM6
authored andcommitted
partial bitcoin#21843: enable GetAddr, GetAddresses, and getnodeaddresses by network
excludes: - 6c98c09 - 3f89c0e - ce6bca8
1 parent 58bea6a commit cf27db8

File tree

10 files changed

+69
-24
lines changed

10 files changed

+69
-24
lines changed

src/addrman.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77

88
#include <hash.h>
99
#include <logging.h>
10+
#include <netaddress.h>
1011
#include <serialize.h>
1112

1213
#include <cmath>
14+
#include <optional>
1315

1416
int CAddrInfo::GetTriedBucket(const uint256& nKey, const std::vector<bool> &asmap) const
1517
{
@@ -532,7 +534,7 @@ int CAddrMan::Check_()
532534
}
533535
#endif
534536

535-
void CAddrMan::GetAddr_(std::vector<CAddress>& vAddr, size_t max_addresses, size_t max_pct)
537+
void CAddrMan::GetAddr_(std::vector<CAddress>& vAddr, size_t max_addresses, size_t max_pct, std::optional<Network> network)
536538
{
537539
size_t nNodes = vRandom.size();
538540
if (max_pct != 0) {
@@ -543,6 +545,7 @@ void CAddrMan::GetAddr_(std::vector<CAddress>& vAddr, size_t max_addresses, size
543545
}
544546

545547
// gather a list of random nodes, skipping those of low quality
548+
const int64_t now{GetAdjustedTime()};
546549
for (unsigned int n = 0; n < vRandom.size(); n++) {
547550
if (vAddr.size() >= nNodes)
548551
break;
@@ -552,8 +555,14 @@ void CAddrMan::GetAddr_(std::vector<CAddress>& vAddr, size_t max_addresses, size
552555
assert(mapInfo.count(vRandom[n]) == 1);
553556

554557
const CAddrInfo& ai = mapInfo[vRandom[n]];
555-
if (!ai.IsTerrible())
556-
vAddr.push_back(ai);
558+
559+
// Filter by network (optional)
560+
if (network != std::nullopt && ai.GetNetClass() != network) continue;
561+
562+
// Filter for quality
563+
if (ai.IsTerrible(now)) continue;
564+
565+
vAddr.push_back(ai);
557566
}
558567
}
559568

src/addrman.h

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <hash.h>
2121
#include <iostream>
2222
#include <map>
23+
#include <optional>
2324
#include <set>
2425
#include <stdint.h>
2526
#include <streams.h>
@@ -602,14 +603,20 @@ class CAddrMan
602603
return addrRet;
603604
}
604605

605-
//! Return a bunch of addresses, selected at random.
606-
std::vector<CAddress> GetAddr(size_t max_addresses, size_t max_pct)
606+
/**
607+
* Return all or many randomly selected addresses, optionally by network.
608+
*
609+
* @param[in] max_addresses Maximum number of addresses to return (0 = all).
610+
* @param[in] max_pct Maximum percentage of addresses to return (0 = all).
611+
* @param[in] network Select only addresses of this network (nullopt = all).
612+
*/
613+
std::vector<CAddress> GetAddr(size_t max_addresses, size_t max_pct, std::optional<Network> network)
607614
{
608615
Check();
609616
std::vector<CAddress> vAddr;
610617
{
611618
LOCK(cs);
612-
GetAddr_(vAddr, max_addresses, max_pct);
619+
GetAddr_(vAddr, max_addresses, max_pct, network);
613620
}
614621
Check();
615622
return vAddr;
@@ -750,8 +757,15 @@ class CAddrMan
750757
int Check_() EXCLUSIVE_LOCKS_REQUIRED(cs);
751758
#endif
752759

753-
//! Select several addresses at once.
754-
void GetAddr_(std::vector<CAddress> &vAddr, size_t max_addresses, size_t max_pct) EXCLUSIVE_LOCKS_REQUIRED(cs);
760+
/**
761+
* Return all or many randomly selected addresses, optionally by network.
762+
*
763+
* @param[out] vAddr Vector of randomly selected addresses from vRandom.
764+
* @param[in] max_addresses Maximum number of addresses to return (0 = all).
765+
* @param[in] max_pct Maximum percentage of addresses to return (0 = all).
766+
* @param[in] network Select only addresses of this network (nullopt = all).
767+
*/
768+
void GetAddr_(std::vector<CAddress>& vAddr, size_t max_addresses, size_t max_pct, std::optional<Network> network) EXCLUSIVE_LOCKS_REQUIRED(cs);
755769

756770
/** We have successfully connected to this peer. Calling this function
757771
* updates the CAddress's nTime, which is used in our IsTerrible()

src/bench/addrman.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <random.h>
88
#include <util/time.h>
99

10+
#include <optional>
1011
#include <vector>
1112

1213
/* 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)
9899
FillAddrMan(addrman);
99100

100101
bench.run([&] {
101-
const auto& addresses = addrman.GetAddr(2500, 23);
102+
const auto& addresses = addrman.GetAddr(/* max_addresses */ 2500, /* max_pct */ 23, /* network */ std::nullopt);
102103
assert(addresses.size() > 0);
103104
});
104105
}

src/net.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <consensus/consensus.h>
1717
#include <crypto/sha256.h>
1818
#include <net_permissions.h>
19+
#include <netaddress.h>
1920
#include <netbase.h>
2021
#include <random.h>
2122
#include <scheduler.h>
@@ -3351,9 +3352,9 @@ CConnman::~CConnman()
33513352
Stop();
33523353
}
33533354

3354-
std::vector<CAddress> CConnman::GetAddresses(size_t max_addresses, size_t max_pct)
3355+
std::vector<CAddress> CConnman::GetAddresses(size_t max_addresses, size_t max_pct, std::optional<Network> network)
33553356
{
3356-
std::vector<CAddress> addresses = addrman.GetAddr(max_addresses, max_pct);
3357+
std::vector<CAddress> addresses = addrman.GetAddr(max_addresses, max_pct, network);
33573358
if (m_banman) {
33583359
addresses.erase(std::remove_if(addresses.begin(), addresses.end(),
33593360
[this](const CAddress& addr){return m_banman->IsDiscouraged(addr) || m_banman->IsBanned(addr);}),
@@ -3375,7 +3376,7 @@ std::vector<CAddress> CConnman::GetAddresses(CNode& requestor, size_t max_addres
33753376
auto r = m_addr_response_caches.emplace(cache_id, CachedAddrResponse{});
33763377
CachedAddrResponse& cache_entry = r.first->second;
33773378
if (cache_entry.m_cache_entry_expiration < current_time) { // If emplace() added new one it has expiration 0.
3378-
cache_entry.m_addrs_response_cache = GetAddresses(max_addresses, max_pct);
3379+
cache_entry.m_addrs_response_cache = GetAddresses(max_addresses, max_pct, /* network */ std::nullopt);
33793380
// Choosing a proper cache lifetime is a trade-off between the privacy leak minimization
33803381
// and the usefulness of ADDR responses to honest users.
33813382
//

src/net.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,15 @@ friend class CNode;
397397
void RelayInvFiltered(CInv &inv, const uint256 &relatedTxHash, const int minProtoVersion = MIN_PEER_PROTO_VERSION);
398398

399399
// Addrman functions
400-
std::vector<CAddress> GetAddresses(size_t max_addresses, size_t max_pct);
400+
/**
401+
* Return all or many randomly selected addresses, optionally by network.
402+
*
403+
* @param[in] max_addresses Maximum number of addresses to return (0 = all).
404+
* @param[in] max_pct Maximum percentage of addresses to return (0 = all).
405+
* @param[in] network Select only addresses of this network (nullopt = all).
406+
*/
407+
std::vector<CAddress> GetAddresses(size_t max_addresses, size_t max_pct, std::optional<Network> network);
408+
401409
/**
402410
* Cache is used to minimize topology leaks, so it should
403411
* be used for all non-trusted calls, for example, p2p.

src/net_processing.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4058,7 +4058,7 @@ void PeerManagerImpl::ProcessMessage(
40584058
pfrom.vAddrToSend.clear();
40594059
std::vector<CAddress> vAddr;
40604060
if (pfrom.HasPermission(PF_ADDR)) {
4061-
vAddr = m_connman.GetAddresses(MAX_ADDR_TO_SEND, MAX_PCT_ADDR_TO_SEND);
4061+
vAddr = m_connman.GetAddresses(MAX_ADDR_TO_SEND, MAX_PCT_ADDR_TO_SEND, /* network */ std::nullopt);
40624062
} else {
40634063
vAddr = m_connman.GetAddresses(pfrom, MAX_ADDR_TO_SEND, MAX_PCT_ADDR_TO_SEND);
40644064
}

src/rpc/net.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
#include <version.h>
2828
#include <warnings.h>
2929

30+
#include <optional>
31+
3032
#include <univalue.h>
3133

3234
static UniValue getconnectioncount(const JSONRPCRequest& request)
@@ -820,7 +822,7 @@ static UniValue getnodeaddresses(const JSONRPCRequest& request)
820822
}
821823
}
822824
// returns a shuffled list of CAddress
823-
std::vector<CAddress> vAddr = node.connman->GetAddresses(count, /* max_pct */ 0);
825+
std::vector<CAddress> vAddr = node.connman->GetAddresses(count, /* max_pct */ 0, /* network */ std::nullopt);
824826
UniValue ret(UniValue::VARR);
825827

826828
for (const CAddress& addr : vAddr) {

src/test/addrman_tests.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <test/data/asmap.raw.h>
1111
#include <test/util/setup_common.h>
1212

13+
#include <optional>
1314
#include <string>
1415

1516
#include <boost/test/unit_test.hpp>
@@ -393,7 +394,7 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr)
393394
// Test: Sanity check, GetAddr should never return anything if addrman
394395
// is empty.
395396
BOOST_CHECK_EQUAL(addrman.size(), 0U);
396-
std::vector<CAddress> vAddr1 = addrman.GetAddr(/* max_addresses */ 0, /* max_pct */0);
397+
std::vector<CAddress> vAddr1 = addrman.GetAddr(/* max_addresses */ 0, /* max_pct */ 0, /* network */ std::nullopt);
397398
BOOST_CHECK_EQUAL(vAddr1.size(), 0U);
398399

399400
CAddress addr1 = CAddress(ResolveService("250.250.2.1", 8333), NODE_NONE);
@@ -416,15 +417,15 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr)
416417
BOOST_CHECK(addrman.Add(addr4, source2));
417418
BOOST_CHECK(addrman.Add(addr5, source1));
418419

419-
BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 0, /* max_pct */ 0).size(), 5U);
420+
BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 0, /* max_pct */ 0, /* network */ std::nullopt).size(), 5U);
420421
// Net processing asks for 23% of addresses. 23% of 5 is 1 rounded down.
421-
BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 2500, /* max_pct */ 23).size(), 1U);
422+
BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 2500, /* max_pct */ 23, /* network */ std::nullopt).size(), 1U);
422423

423424
// Test: Ensure GetAddr works with new and tried addresses.
424425
addrman.Good(CAddress(addr1, NODE_NONE));
425426
addrman.Good(CAddress(addr2, NODE_NONE));
426-
BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 0, /* max_pct */ 0).size(), 5U);
427-
BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 2500, /* max_pct */ 23).size(), 1U);
427+
BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 0, /* max_pct */ 0, /* network */ std::nullopt).size(), 5U);
428+
BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 2500, /* max_pct */ 23, /* network */ std::nullopt).size(), 1U);
428429

429430
// Test: Ensure GetAddr still returns 23% when addrman has many addrs.
430431
for (unsigned int i = 1; i < (8 * 256); i++) {
@@ -439,7 +440,7 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr)
439440
if (i % 8 == 0)
440441
addrman.Good(addr);
441442
}
442-
std::vector<CAddress> vAddr = addrman.GetAddr(/* max_addresses */ 2500, /* max_pct */ 23);
443+
std::vector<CAddress> vAddr = addrman.GetAddr(/* max_addresses */ 2500, /* max_pct */ 23, /* network */ std::nullopt);
443444

444445
size_t percent23 = (addrman.size() * 23) / 100;
445446
BOOST_CHECK_EQUAL(vAddr.size(), percent23);

src/test/fuzz/addrman.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,10 @@ FUZZ_TARGET_INIT(addrman, initialize_addrman)
6161
(void)addr_man.Select(fuzzed_data_provider.ConsumeBool());
6262
},
6363
[&] {
64-
(void)addr_man.GetAddr(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
64+
(void)addr_man.GetAddr(
65+
/* max_addresses */ fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096),
66+
/* max_pct */ fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096),
67+
/* network */ std::nullopt);
6568
},
6669
[&] {
6770
const std::optional<CAddress> opt_address = ConsumeDeserializable<CAddress>(fuzzed_data_provider);

src/test/fuzz/connman.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,16 @@ FUZZ_TARGET_INIT(connman, initialize_connman)
6969
(void)connman.ForNode(fuzzed_data_provider.ConsumeIntegral<NodeId>(), [&](auto) { return fuzzed_data_provider.ConsumeBool(); });
7070
},
7171
[&] {
72-
(void)connman.GetAddresses(fuzzed_data_provider.ConsumeIntegral<size_t>(), fuzzed_data_provider.ConsumeIntegral<size_t>());
72+
(void)connman.GetAddresses(
73+
/* max_addresses */ fuzzed_data_provider.ConsumeIntegral<size_t>(),
74+
/* max_pct */ fuzzed_data_provider.ConsumeIntegral<size_t>(),
75+
/* network */ std::nullopt);
7376
},
7477
[&] {
75-
(void)connman.GetAddresses(random_node, fuzzed_data_provider.ConsumeIntegral<size_t>(), fuzzed_data_provider.ConsumeIntegral<size_t>());
78+
(void)connman.GetAddresses(
79+
/* requestor */ random_node,
80+
/* max_addresses */ fuzzed_data_provider.ConsumeIntegral<size_t>(),
81+
/* max_pct */ fuzzed_data_provider.ConsumeIntegral<size_t>());
7682
},
7783
[&] {
7884
(void)connman.GetDeterministicRandomizer(fuzzed_data_provider.ConsumeIntegral<uint64_t>());

0 commit comments

Comments
 (0)