mirror of
https://github.com/dashpay/dash.git
synced 2024-12-24 19:42:46 +01:00
partial bitcoin#21843: enable GetAddr, GetAddresses, and getnodeaddresses by network
excludes: - 6c98c099918bd20e2d3aa123643d6e3594e080e4 - 3f89c0e9902338ad8a507a938dceeeb3191eece6 - ce6bca88e8c685c69686e0b8dc095ffc3e2ac34d
This commit is contained in:
parent
58bea6a498
commit
cf27db8574
@ -7,9 +7,11 @@
|
||||
|
||||
#include <hash.h>
|
||||
#include <logging.h>
|
||||
#include <netaddress.h>
|
||||
#include <serialize.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <optional>
|
||||
|
||||
int CAddrInfo::GetTriedBucket(const uint256& nKey, const std::vector<bool> &asmap) const
|
||||
{
|
||||
@ -532,7 +534,7 @@ int CAddrMan::Check_()
|
||||
}
|
||||
#endif
|
||||
|
||||
void CAddrMan::GetAddr_(std::vector<CAddress>& vAddr, size_t max_addresses, size_t max_pct)
|
||||
void CAddrMan::GetAddr_(std::vector<CAddress>& vAddr, size_t max_addresses, size_t max_pct, std::optional<Network> network)
|
||||
{
|
||||
size_t nNodes = vRandom.size();
|
||||
if (max_pct != 0) {
|
||||
@ -543,6 +545,7 @@ void CAddrMan::GetAddr_(std::vector<CAddress>& vAddr, size_t max_addresses, size
|
||||
}
|
||||
|
||||
// gather a list of random nodes, skipping those of low quality
|
||||
const int64_t now{GetAdjustedTime()};
|
||||
for (unsigned int n = 0; n < vRandom.size(); n++) {
|
||||
if (vAddr.size() >= nNodes)
|
||||
break;
|
||||
@ -552,8 +555,14 @@ void CAddrMan::GetAddr_(std::vector<CAddress>& vAddr, size_t max_addresses, size
|
||||
assert(mapInfo.count(vRandom[n]) == 1);
|
||||
|
||||
const CAddrInfo& ai = mapInfo[vRandom[n]];
|
||||
if (!ai.IsTerrible())
|
||||
vAddr.push_back(ai);
|
||||
|
||||
// Filter by network (optional)
|
||||
if (network != std::nullopt && ai.GetNetClass() != network) continue;
|
||||
|
||||
// Filter for quality
|
||||
if (ai.IsTerrible(now)) continue;
|
||||
|
||||
vAddr.push_back(ai);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <hash.h>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <stdint.h>
|
||||
#include <streams.h>
|
||||
@ -602,14 +603,20 @@ public:
|
||||
return addrRet;
|
||||
}
|
||||
|
||||
//! Return a bunch of addresses, selected at random.
|
||||
std::vector<CAddress> 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<CAddress> GetAddr(size_t max_addresses, size_t max_pct, std::optional<Network> network)
|
||||
{
|
||||
Check();
|
||||
std::vector<CAddress> vAddr;
|
||||
{
|
||||
LOCK(cs);
|
||||
GetAddr_(vAddr, max_addresses, max_pct);
|
||||
GetAddr_(vAddr, max_addresses, max_pct, network);
|
||||
}
|
||||
Check();
|
||||
return vAddr;
|
||||
@ -750,8 +757,15 @@ private:
|
||||
int Check_() EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
#endif
|
||||
|
||||
//! Select several addresses at once.
|
||||
void GetAddr_(std::vector<CAddress> &vAddr, size_t max_addresses, size_t max_pct) EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
/**
|
||||
* Return all or many randomly selected addresses, optionally by network.
|
||||
*
|
||||
* @param[out] vAddr Vector of randomly selected addresses from vRandom.
|
||||
* @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).
|
||||
*/
|
||||
void GetAddr_(std::vector<CAddress>& vAddr, size_t max_addresses, size_t max_pct, std::optional<Network> 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()
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <random.h>
|
||||
#include <util/time.h>
|
||||
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
/* 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);
|
||||
});
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <consensus/consensus.h>
|
||||
#include <crypto/sha256.h>
|
||||
#include <net_permissions.h>
|
||||
#include <netaddress.h>
|
||||
#include <netbase.h>
|
||||
#include <random.h>
|
||||
#include <scheduler.h>
|
||||
@ -3351,9 +3352,9 @@ CConnman::~CConnman()
|
||||
Stop();
|
||||
}
|
||||
|
||||
std::vector<CAddress> CConnman::GetAddresses(size_t max_addresses, size_t max_pct)
|
||||
std::vector<CAddress> CConnman::GetAddresses(size_t max_addresses, size_t max_pct, std::optional<Network> network)
|
||||
{
|
||||
std::vector<CAddress> addresses = addrman.GetAddr(max_addresses, max_pct);
|
||||
std::vector<CAddress> addresses = addrman.GetAddr(max_addresses, max_pct, network);
|
||||
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);}),
|
||||
@ -3375,7 +3376,7 @@ std::vector<CAddress> CConnman::GetAddresses(CNode& requestor, size_t max_addres
|
||||
auto r = m_addr_response_caches.emplace(cache_id, CachedAddrResponse{});
|
||||
CachedAddrResponse& cache_entry = r.first->second;
|
||||
if (cache_entry.m_cache_entry_expiration < current_time) { // If emplace() added new one it has expiration 0.
|
||||
cache_entry.m_addrs_response_cache = GetAddresses(max_addresses, max_pct);
|
||||
cache_entry.m_addrs_response_cache = GetAddresses(max_addresses, max_pct, /* network */ std::nullopt);
|
||||
// Choosing a proper cache lifetime is a trade-off between the privacy leak minimization
|
||||
// and the usefulness of ADDR responses to honest users.
|
||||
//
|
||||
|
10
src/net.h
10
src/net.h
@ -397,7 +397,15 @@ public:
|
||||
void RelayInvFiltered(CInv &inv, const uint256 &relatedTxHash, const int minProtoVersion = MIN_PEER_PROTO_VERSION);
|
||||
|
||||
// Addrman functions
|
||||
std::vector<CAddress> GetAddresses(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<CAddress> GetAddresses(size_t max_addresses, size_t max_pct, std::optional<Network> network);
|
||||
|
||||
/**
|
||||
* Cache is used to minimize topology leaks, so it should
|
||||
* be used for all non-trusted calls, for example, p2p.
|
||||
|
@ -4058,7 +4058,7 @@ void PeerManagerImpl::ProcessMessage(
|
||||
pfrom.vAddrToSend.clear();
|
||||
std::vector<CAddress> vAddr;
|
||||
if (pfrom.HasPermission(PF_ADDR)) {
|
||||
vAddr = m_connman.GetAddresses(MAX_ADDR_TO_SEND, MAX_PCT_ADDR_TO_SEND);
|
||||
vAddr = m_connman.GetAddresses(MAX_ADDR_TO_SEND, MAX_PCT_ADDR_TO_SEND, /* network */ std::nullopt);
|
||||
} else {
|
||||
vAddr = m_connman.GetAddresses(pfrom, MAX_ADDR_TO_SEND, MAX_PCT_ADDR_TO_SEND);
|
||||
}
|
||||
|
@ -27,6 +27,8 @@
|
||||
#include <version.h>
|
||||
#include <warnings.h>
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include <univalue.h>
|
||||
|
||||
static UniValue getconnectioncount(const JSONRPCRequest& request)
|
||||
@ -820,7 +822,7 @@ static UniValue getnodeaddresses(const JSONRPCRequest& request)
|
||||
}
|
||||
}
|
||||
// returns a shuffled list of CAddress
|
||||
std::vector<CAddress> vAddr = node.connman->GetAddresses(count, /* max_pct */ 0);
|
||||
std::vector<CAddress> vAddr = node.connman->GetAddresses(count, /* max_pct */ 0, /* network */ std::nullopt);
|
||||
UniValue ret(UniValue::VARR);
|
||||
|
||||
for (const CAddress& addr : vAddr) {
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <test/data/asmap.raw.h>
|
||||
#include <test/util/setup_common.h>
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
@ -393,7 +394,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<CAddress> vAddr1 = addrman.GetAddr(/* max_addresses */ 0, /* max_pct */0);
|
||||
std::vector<CAddress> 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);
|
||||
@ -416,15 +417,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++) {
|
||||
@ -439,7 +440,7 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr)
|
||||
if (i % 8 == 0)
|
||||
addrman.Good(addr);
|
||||
}
|
||||
std::vector<CAddress> vAddr = addrman.GetAddr(/* max_addresses */ 2500, /* max_pct */ 23);
|
||||
std::vector<CAddress> 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);
|
||||
|
@ -61,7 +61,10 @@ FUZZ_TARGET_INIT(addrman, initialize_addrman)
|
||||
(void)addr_man.Select(fuzzed_data_provider.ConsumeBool());
|
||||
},
|
||||
[&] {
|
||||
(void)addr_man.GetAddr(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
|
||||
(void)addr_man.GetAddr(
|
||||
/* max_addresses */ fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096),
|
||||
/* max_pct */ fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096),
|
||||
/* network */ std::nullopt);
|
||||
},
|
||||
[&] {
|
||||
const std::optional<CAddress> opt_address = ConsumeDeserializable<CAddress>(fuzzed_data_provider);
|
||||
|
@ -69,10 +69,16 @@ FUZZ_TARGET_INIT(connman, initialize_connman)
|
||||
(void)connman.ForNode(fuzzed_data_provider.ConsumeIntegral<NodeId>(), [&](auto) { return fuzzed_data_provider.ConsumeBool(); });
|
||||
},
|
||||
[&] {
|
||||
(void)connman.GetAddresses(fuzzed_data_provider.ConsumeIntegral<size_t>(), fuzzed_data_provider.ConsumeIntegral<size_t>());
|
||||
(void)connman.GetAddresses(
|
||||
/* max_addresses */ fuzzed_data_provider.ConsumeIntegral<size_t>(),
|
||||
/* max_pct */ fuzzed_data_provider.ConsumeIntegral<size_t>(),
|
||||
/* network */ std::nullopt);
|
||||
},
|
||||
[&] {
|
||||
(void)connman.GetAddresses(random_node, fuzzed_data_provider.ConsumeIntegral<size_t>(), fuzzed_data_provider.ConsumeIntegral<size_t>());
|
||||
(void)connman.GetAddresses(
|
||||
/* requestor */ random_node,
|
||||
/* max_addresses */ fuzzed_data_provider.ConsumeIntegral<size_t>(),
|
||||
/* max_pct */ fuzzed_data_provider.ConsumeIntegral<size_t>());
|
||||
},
|
||||
[&] {
|
||||
(void)connman.GetDeterministicRandomizer(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
|
||||
|
Loading…
Reference in New Issue
Block a user