DNS seeds: wait for 5m instead of 11s if 1000+ peers are known
If 1000 potential peers are known, wait for 5m before querying DNS seeds for more peers, since eventually the addresses we already know should get us connected. Also check every 11s whether we've got enough active outbounds that DNS seeds aren't worth querying, and exit the dnsseed thread early if so.
This commit is contained in:
parent
646f0ada02
commit
fa5894f7f5
1 changed files with 52 additions and 16 deletions
68
src/net.cpp
68
src/net.cpp
|
@ -51,6 +51,12 @@ static constexpr int DUMP_PEERS_INTERVAL = 15 * 60;
|
||||||
/** Number of DNS seeds to query when the number of connections is low. */
|
/** Number of DNS seeds to query when the number of connections is low. */
|
||||||
static constexpr int DNSSEEDS_TO_QUERY_AT_ONCE = 3;
|
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.
|
// We add a random period time (0 to 1 seconds) to feeler connections to prevent synchronization.
|
||||||
#define FEELER_SLEEP_WINDOW 1
|
#define FEELER_SLEEP_WINDOW 1
|
||||||
|
|
||||||
|
@ -1573,31 +1579,61 @@ void CConnman::ThreadDNSAddressSeed()
|
||||||
if (gArgs.GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED)) {
|
if (gArgs.GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED)) {
|
||||||
// When -forcednsseed is provided, query all.
|
// When -forcednsseed is provided, query all.
|
||||||
seeds_right_now = seeds.size();
|
seeds_right_now = seeds.size();
|
||||||
|
} else if (addrman.size() == 0) {
|
||||||
|
// If we have no known peers, query all.
|
||||||
|
seeds_right_now = seeds.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const std::string& seed : seeds) {
|
// goal: only query DNS seed if address need is acute
|
||||||
// goal: only query DNS seed if address need is acute
|
// * If we have a reasonable number of peers in addrman, spend
|
||||||
// Avoiding DNS seeds when we don't need them improves user privacy by
|
// some time trying them first. This improves user privacy by
|
||||||
// creating fewer identifying DNS requests, reduces trust by giving seeds
|
// creating fewer identifying DNS requests, reduces trust by
|
||||||
// less influence on the network topology, and reduces traffic to the seeds.
|
// giving seeds less influence on the network topology, and
|
||||||
if (addrman.size() > 0 && seeds_right_now == 0) {
|
// reduces traffic to the seeds.
|
||||||
if (!interruptNet.sleep_for(std::chrono::seconds(11))) return;
|
// * 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);
|
||||||
|
|
||||||
LOCK(cs_vNodes);
|
for (const std::string& seed : seeds) {
|
||||||
int nRelevant = 0;
|
if (seeds_right_now == 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;
|
|
||||||
}
|
|
||||||
seeds_right_now += DNSSEEDS_TO_QUERY_AT_ONCE;
|
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) {
|
if (interruptNet) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogPrintf("Loading addresses from DNS seed %s\n", seed);
|
LogPrintf("Loading addresses from DNS seed %s\n", seed);
|
||||||
if (HaveNameProxy()) {
|
if (HaveNameProxy()) {
|
||||||
AddOneShot(seed);
|
AddOneShot(seed);
|
||||||
|
|
Loading…
Reference in a new issue