diff options
-rw-r--r-- | .cirrus.yml | 2 | ||||
-rw-r--r-- | .travis.yml | 1 | ||||
-rw-r--r-- | doc/Doxyfile.in | 4 | ||||
-rw-r--r-- | doc/README_doxygen.md | 15 | ||||
-rw-r--r-- | src/bitcoind.cpp | 18 | ||||
-rw-r--r-- | src/net.cpp | 61 | ||||
-rw-r--r-- | test/functional/README.md | 2 | ||||
-rw-r--r-- | test/functional/test_framework/util.py | 5 |
8 files changed, 58 insertions, 50 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index 1e6e6937da..9464ec1685 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -9,6 +9,7 @@ task: MAKEJOBS: "-j9" CONFIGURE_OPTS: "--disable-dependency-tracking" GOAL: "install" + TEST_RUNNER_PORT_MIN: "14000" # Must be larger than 12321, which is used for the http cache. See https://cirrus-ci.org/guide/writing-tasks/#http-cache CCACHE_SIZE: "200M" CCACHE_COMPRESS: 1 CCACHE_DIR: "/tmp/ccache_dir" @@ -37,6 +38,7 @@ task: env: MAKEJOBS: "-j9" RUN_CI_ON_HOST: "1" + TEST_RUNNER_PORT_MIN: "14000" # Must be larger than 12321, which is used for the http cache. See https://cirrus-ci.org/guide/writing-tasks/#http-cache CCACHE_SIZE: "200M" CCACHE_DIR: "/tmp/ccache_dir" ccache_cache: diff --git a/.travis.yml b/.travis.yml index ec08ab2efb..e93f6ca0dc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -117,6 +117,7 @@ jobs: name: 'x86_64 Linux [GOAL: install] [xenial] [no depends, only system libs, sanitizers: thread (TSan), no wallet]' env: >- FILE_ENV="./ci/test/00_setup_env_amd64_tsan.sh" + TEST_RUNNER_EXTRA="--exclude feature_block" # Not enough memory on travis machines - stage: test name: 'x86_64 Linux [GOAL: install] [bionic] [no depends, only system libs, sanitizers: address/leak (ASan + LSan) + undefined (UBSan) + integer]' diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index 399d54eb85..cd7ccf80ab 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -790,7 +790,7 @@ WARN_LOGFILE = # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. -INPUT = src +INPUT = src doc/README_doxygen.md # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses @@ -974,7 +974,7 @@ FILTER_SOURCE_PATTERNS = # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the doxygen output. -USE_MDFILE_AS_MAINPAGE = +USE_MDFILE_AS_MAINPAGE = doc/README_doxygen.md #--------------------------------------------------------------------------- # Configuration options related to source browsing diff --git a/doc/README_doxygen.md b/doc/README_doxygen.md new file mode 100644 index 0000000000..6888383a98 --- /dev/null +++ b/doc/README_doxygen.md @@ -0,0 +1,15 @@ +\mainpage notitle + +\section intro_sec Introduction + +This is the developer documentation of the reference client for an experimental new digital currency called Bitcoin, +which enables instant payments to anyone, anywhere in the world. Bitcoin uses peer-to-peer technology to operate +with no central authority: managing transactions and issuing money are carried out collectively by the network. + +The software is a community-driven open source project, released under the MIT license. + +See https://github.com/bitcoin/bitcoin and https://bitcoincore.org/ for further information about the project. + +\section Navigation +Use <a href="modules.html"><code>Modules</code></a>, <a href="namespaces.html"><code>Namespaces</code></a>, <a href="classes.html"><code>Classes</code></a>, or <a href="files.html"><code>Files</code></a> at the top of the page to start navigating the code. + diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index 83de684a2b..615b955f6e 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -25,24 +25,6 @@ const std::function<std::string(const char*)> G_TRANSLATION_FUN = nullptr; -/* Introduction text for doxygen: */ - -/*! \mainpage Developer documentation - * - * \section intro_sec Introduction - * - * This is the developer documentation of the reference client for an experimental new digital currency called Bitcoin, - * which enables instant payments to anyone, anywhere in the world. Bitcoin uses peer-to-peer technology to operate - * with no central authority: managing transactions and issuing money are carried out collectively by the network. - * - * The software is a community-driven open source project, released under the MIT license. - * - * See https://github.com/bitcoin/bitcoin and https://bitcoincore.org/ for further information about the project. - * - * \section Navigation - * Use the buttons <code>Namespaces</code>, <code>Classes</code> or <code>Files</code> at the top of the page to start navigating the code. - */ - static void WaitForShutdown() { while (!ShutdownRequested()) diff --git a/src/net.cpp b/src/net.cpp index 89f82aa3d2..63b7833822 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -50,6 +50,9 @@ static_assert(MINIUPNPC_API_VERSION >= 10, "miniUPnPc API version >= 10 assumed" // Dump addresses to peers.dat every 15 minutes (900s) static constexpr int DUMP_PEERS_INTERVAL = 15 * 60; +/** Number of DNS seeds to query when the number of connections is low. */ +static constexpr int DNSSEEDS_TO_QUERY_AT_ONCE = 3; + // We add a random period time (0 to 1 seconds) to feeler connections to prevent synchronization. #define FEELER_SLEEP_WINDOW 1 @@ -1535,35 +1538,41 @@ void StopMapPort() void CConnman::ThreadDNSAddressSeed() { - // goal: only query DNS seeds 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) && - (!gArgs.GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED))) { - if (!interruptNet.sleep_for(std::chrono::seconds(11))) - return; + FastRandomContext rng; + std::vector<std::string> seeds = Params().DNSSeeds(); + Shuffle(seeds.begin(), seeds.end(), rng); + int seeds_right_now = 0; // Number of seeds left before testing if we have enough connections + int found = 0; - 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 (gArgs.GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED)) { + // When -forcednsseed is provided, query all. + seeds_right_now = seeds.size(); } - const std::vector<std::string> &vSeeds = Params().DNSSeeds(); - int found = 0; + 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; - LogPrintf("Loading addresses from DNS seeds (could take a while)\n"); + 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; + } + seeds_right_now += DNSSEEDS_TO_QUERY_AT_ONCE; + } - for (const std::string &seed : vSeeds) { if (interruptNet) { return; } + LogPrintf("Loading addresses from DNS seed %s\n", seed); if (HaveNameProxy()) { AddOneShot(seed); } else { @@ -1576,13 +1585,11 @@ void CConnman::ThreadDNSAddressSeed() continue; } unsigned int nMaxIPs = 256; // Limits number of IPs learned from a DNS seed - if (LookupHost(host.c_str(), vIPs, nMaxIPs, true)) - { - for (const CNetAddr& ip : vIPs) - { + if (LookupHost(host.c_str(), vIPs, nMaxIPs, true)) { + for (const CNetAddr& ip : vIPs) { int nOneDay = 24*3600; CAddress addr = CAddress(CService(ip, Params().GetDefaultPort()), requiredServiceBits); - addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old + addr.nTime = GetTime() - 3*nOneDay - rng.randrange(4*nOneDay); // use a random age between 3 and 7 days old vAdd.push_back(addr); found++; } @@ -1593,8 +1600,8 @@ void CConnman::ThreadDNSAddressSeed() AddOneShot(seed); } } + --seeds_right_now; } - LogPrintf("%d addresses found from DNS seeds\n", found); } diff --git a/test/functional/README.md b/test/functional/README.md index 5e3009e6af..197c2afbe4 100644 --- a/test/functional/README.md +++ b/test/functional/README.md @@ -116,7 +116,7 @@ Basic code to support P2P connectivity to a bitcoind. Utilities for manipulating transaction scripts (originally from python-bitcoinlib) #### [test_framework/key.py](test_framework/key.py) -Wrapper around OpenSSL EC_Key (originally from python-bitcoinlib) +Test-only secp256k1 elliptic curve implementation #### [test_framework/bignum.py](test_framework/bignum.py) Helpers for script.py diff --git a/test/functional/test_framework/util.py b/test/functional/test_framework/util.py index 1c254b6755..598e87558b 100644 --- a/test/functional/test_framework/util.py +++ b/test/functional/test_framework/util.py @@ -7,13 +7,13 @@ from base64 import b64encode from binascii import unhexlify from decimal import Decimal, ROUND_DOWN +from subprocess import CalledProcessError import inspect import json import logging import os import random import re -from subprocess import CalledProcessError import time from . import coverage @@ -235,10 +235,11 @@ def wait_until(predicate, *, attempts=float('inf'), timeout=float('inf'), lock=N # The maximum number of nodes a single test can spawn MAX_NODES = 12 # Don't assign rpc or p2p ports lower than this -PORT_MIN = 11000 +PORT_MIN = int(os.getenv('TEST_RUNNER_PORT_MIN', default=11000)) # The number of ports to "reserve" for p2p and rpc, each PORT_RANGE = 5000 + class PortSeed: # Must be initialized with a unique integer for each process n = None |