mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-10 20:03:34 -03:00
Merge #16939: p2p: Delay querying DNS seeds
96954d1794
DNS seeds: don't query DNS while network is inactive (Anthony Towns)fa5894f7f5
DNS seeds: wait for 5m instead of 11s if 1000+ peers are known (Anthony Towns) Pull request description: Changes the logic for querying DNS seeds: after this PR, if there's less than 1000 entries in addrman, it will still usually query DNS seeds after 11s (unless the first few peers tried mostly succeed), but if there's more than 1000 entries it won't try DNS seeds until 5 minutes have passed without getting multiple outbound peers. (If there's 0 entries in addrman, it will still immediately query the DNS seeds). Additionally, delays querying DNS seeds while the p2p network is not active. Fixes #15434 ACKs for top commit: fanquake: ACK96954d1794
- Ran some tests of different scenarios. More documentation is being added in #19084. ariard: Tested ACK96954d1
, on Debian 9.1. Both MANY_PEERS/FEW_PEERS cases work. Sjors: tACK96954d1
(rebased on master) on macOS 10.15.4. It found it useful to run with `-debug=addrman` and change `DNSSEEDS_DELAY_MANY_PEERS` to something lower to test the behaviour, as well as renaming `peers.dat` to test the peer threshold. naumenkogs: utACK96954d1794
Tree-SHA512: 73693db3da73bf8e76c3df9e9c82f0a7fb08049187356eac2575c4ffa455f76548dd1c86a11fc6beea8a3baf0ba020e047bebe927883c731383ec72442356005
This commit is contained in:
commit
73407ff65c
1 changed files with 60 additions and 18 deletions
78
src/net.cpp
78
src/net.cpp
|
@ -52,6 +52,12 @@ static constexpr std::chrono::minutes DUMP_PEERS_INTERVAL{15};
|
|||
/** Number of DNS seeds to query when the number of connections is low. */
|
||||
static constexpr int DNSSEEDS_TO_QUERY_AT_ONCE = 3;
|
||||
|
||||
/** How long to delay before querying DNS seeds
|
||||
*/
|
||||
static constexpr std::chrono::seconds DNSSEEDS_DELAY_FEW_PEERS{11}; // 11sec
|
||||
static constexpr std::chrono::seconds DNSSEEDS_DELAY_MANY_PEERS{300}; // 5min
|
||||
static constexpr int DNSSEEDS_DELAY_PEER_THRESHOLD = 1000; // "many" vs "few" peers -- you should only get this many if you've been on the live network
|
||||
|
||||
// We add a random period time (0 to 1 seconds) to feeler connections to prevent synchronization.
|
||||
#define FEELER_SLEEP_WINDOW 1
|
||||
|
||||
|
@ -1587,31 +1593,67 @@ 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) {
|
||||
// If we have no known peers, query all.
|
||||
seeds_right_now = seeds.size();
|
||||
}
|
||||
|
||||
// goal: only query DNS seed if address need is acute
|
||||
// * If we have a reasonable number of peers in addrman, spend
|
||||
// some time trying them first. This improves user privacy by
|
||||
// creating fewer identifying DNS requests, reduces trust by
|
||||
// giving seeds less influence on the network topology, and
|
||||
// reduces traffic to the seeds.
|
||||
// * When querying DNS seeds query a few at once, this ensures
|
||||
// that we don't give DNS seeds the ability to eclipse nodes
|
||||
// that query them.
|
||||
// * 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);
|
||||
|
||||
for (const std::string& seed : seeds) {
|
||||
// goal: only query DNS seed if address need is acute
|
||||
// Avoiding DNS seeds when we don't need them improves user privacy by
|
||||
// creating fewer identifying DNS requests, reduces trust by giving seeds
|
||||
// less influence on the network topology, and reduces traffic to the seeds.
|
||||
if (addrman.size() > 0 && seeds_right_now == 0) {
|
||||
if (!interruptNet.sleep_for(std::chrono::seconds(11))) return;
|
||||
|
||||
LOCK(cs_vNodes);
|
||||
int nRelevant = 0;
|
||||
for (const CNode* pnode : vNodes) {
|
||||
nRelevant += pnode->fSuccessfullyConnected && !pnode->fFeeler && !pnode->fOneShot && !pnode->m_manual_connection && !pnode->fInbound;
|
||||
}
|
||||
if (nRelevant >= 2) {
|
||||
LogPrintf("P2P peers available. Skipped DNS seeding.\n");
|
||||
return;
|
||||
}
|
||||
if (seeds_right_now == 0) {
|
||||
seeds_right_now += DNSSEEDS_TO_QUERY_AT_ONCE;
|
||||
|
||||
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) {
|
||||
std::chrono::seconds w = std::min(DNSSEEDS_DELAY_FEW_PEERS, to_wait);
|
||||
if (!interruptNet.sleep_for(w)) return;
|
||||
to_wait -= w;
|
||||
|
||||
int nRelevant = 0;
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
for (const CNode* pnode : vNodes) {
|
||||
nRelevant += pnode->fSuccessfullyConnected && !pnode->fFeeler && !pnode->fOneShot && !pnode->m_manual_connection && !pnode->fInbound;
|
||||
}
|
||||
}
|
||||
if (nRelevant >= 2) {
|
||||
if (found > 0) {
|
||||
LogPrintf("%d addresses found from DNS seeds\n", found);
|
||||
LogPrintf("P2P peers available. Finished DNS seeding.\n");
|
||||
} else {
|
||||
LogPrintf("P2P peers available. Skipped DNS seeding.\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (interruptNet) {
|
||||
return;
|
||||
if (interruptNet) return;
|
||||
|
||||
// hold off on querying seeds if p2p network deactivated
|
||||
if (!fNetworkActive) {
|
||||
LogPrintf("Waiting for network to be reactivated before querying DNS seeds.\n");
|
||||
do {
|
||||
if (!interruptNet.sleep_for(std::chrono::seconds{1})) return;
|
||||
} while (!fNetworkActive);
|
||||
}
|
||||
|
||||
LogPrintf("Loading addresses from DNS seed %s\n", seed);
|
||||
if (HaveNameProxy()) {
|
||||
AddOneShot(seed);
|
||||
|
|
Loading…
Reference in a new issue