diff options
58 files changed, 394 insertions, 243 deletions
diff --git a/.travis/test_06_script.sh b/.travis/test_06_script.sh index e5fea81187..59cc110db5 100755 --- a/.travis/test_06_script.sh +++ b/.travis/test_06_script.sh @@ -57,7 +57,7 @@ if [ "$RUN_BENCH" = "true" ]; then fi if [ "$TRAVIS_EVENT_TYPE" = "cron" ]; then - extended="--extended --exclude feature_pruning,feature_dbcrash" + extended="--extended --exclude feature_pruning" fi if [ "$RUN_FUNCTIONAL_TESTS" = "true" ]; then diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index d5fd1f39ab..c9068e83a5 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -1,8 +1,8 @@ package=zeromq -$(package)_version=4.2.3 +$(package)_version=4.2.5 $(package)_download_path=https://github.com/zeromq/libzmq/releases/download/v$($(package)_version)/ $(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=8f1e2b2aade4dbfde98d82366d61baef2f62e812530160d2e6d0a5bb24e40bc0 +$(package)_sha256_hash=cc9090ba35713d59bb2f7d7965f877036c49c5558ea0c290b0dcc6f2a17e489f $(package)_patches=0001-fix-build-with-older-mingw64.patch 0002-disable-pthread_set_name_np.patch define $(package)_set_vars diff --git a/depends/patches/zeromq/0001-fix-build-with-older-mingw64.patch b/depends/patches/zeromq/0001-fix-build-with-older-mingw64.patch index a6c508fb8a..b911ac5672 100644 --- a/depends/patches/zeromq/0001-fix-build-with-older-mingw64.patch +++ b/depends/patches/zeromq/0001-fix-build-with-older-mingw64.patch @@ -1,6 +1,6 @@ -From 1a159c128c69a42d90819375c06a39994f3fbfc1 Mon Sep 17 00:00:00 2001 -From: Cory Fields <cory-nospam-@coryfields.com> -Date: Tue, 28 Nov 2017 20:33:25 -0500 +From f6866b0f166ad168618aae64c7fbee8775d3eb23 Mon Sep 17 00:00:00 2001 +From: mruddy <6440430+mruddy@users.noreply.github.com> +Date: Sat, 30 Jun 2018 09:44:58 -0400 Subject: [PATCH] fix build with older mingw64 --- @@ -8,10 +8,10 @@ Subject: [PATCH] fix build with older mingw64 1 file changed, 7 insertions(+) diff --git a/src/windows.hpp b/src/windows.hpp -index 99e889d..e69038e 100644 +index 6c3839fd..2c32ec79 100644 --- a/src/windows.hpp +++ b/src/windows.hpp -@@ -55,6 +55,13 @@ +@@ -58,6 +58,13 @@ #include <winsock2.h> #include <windows.h> #include <mswsock.h> @@ -23,8 +23,8 @@ index 99e889d..e69038e 100644 +#include <ws2ipdef.h> +#endif #include <iphlpapi.h> - + #if !defined __MINGW32__ --- -2.7.4 +-- +2.17.1 diff --git a/depends/patches/zeromq/0002-disable-pthread_set_name_np.patch b/depends/patches/zeromq/0002-disable-pthread_set_name_np.patch index d220b54f3e..022e311977 100644 --- a/depends/patches/zeromq/0002-disable-pthread_set_name_np.patch +++ b/depends/patches/zeromq/0002-disable-pthread_set_name_np.patch @@ -1,6 +1,6 @@ -From 6e6b47d5ab381c3df3b30bb0b0a6cf210dfb1eba Mon Sep 17 00:00:00 2001 -From: Cory Fields <cory-nospam-@coryfields.com> -Date: Mon, 5 Mar 2018 14:22:05 -0500 +From c9bbdd6581d07acfe8971e4bcebe278a3676cf03 Mon Sep 17 00:00:00 2001 +From: mruddy <6440430+mruddy@users.noreply.github.com> +Date: Sat, 30 Jun 2018 09:57:18 -0400 Subject: [PATCH] disable pthread_set_name_np pthread_set_name_np adds a Glibc requirement on >= 2.12. @@ -9,21 +9,21 @@ pthread_set_name_np adds a Glibc requirement on >= 2.12. 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/thread.cpp b/src/thread.cpp -index 4fc59c3e..c3fdfd46 100644 +index a1086b0c..9943f354 100644 --- a/src/thread.cpp +++ b/src/thread.cpp -@@ -220,7 +220,7 @@ void zmq::thread_t::setThreadName(const char *name_) +@@ -307,7 +307,7 @@ void zmq::thread_t::setThreadName (const char *name_) */ if (!name_) return; - +#if 0 #if defined(ZMQ_HAVE_PTHREAD_SETNAME_1) - int rc = pthread_setname_np(name_); - if(rc) return; -@@ -233,6 +233,8 @@ void zmq::thread_t::setThreadName(const char *name_) + int rc = pthread_setname_np (name_); + if (rc) +@@ -323,6 +323,8 @@ void zmq::thread_t::setThreadName (const char *name_) #elif defined(ZMQ_HAVE_PTHREAD_SET_NAME) - pthread_set_name_np(descriptor, name_); + pthread_set_name_np (descriptor, name_); #endif +#endif + return; @@ -31,5 +31,5 @@ index 4fc59c3e..c3fdfd46 100644 #endif -- -2.11.1 +2.17.1 diff --git a/doc/build-unix.md b/doc/build-unix.md index 337de12b8d..3f8848abf2 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -47,7 +47,7 @@ Optional dependencies: protobuf | Payments in GUI | Data interchange format used for payment protocol (only needed when GUI enabled) libqrencode | QR codes in GUI | Optional for generating QR codes (only needed when GUI enabled) univalue | Utility | JSON parsing and encoding (bundled version will be used unless --with-system-univalue passed to configure) - libzmq3 | ZMQ notification | Optional, allows generating ZMQ notifications (requires ZMQ version >= 4.x) + libzmq3 | ZMQ notification | Optional, allows generating ZMQ notifications (requires ZMQ version >= 4.0.0) For the versions used, see [dependencies.md](dependencies.md) @@ -93,7 +93,7 @@ Optional (see --with-miniupnpc and --enable-upnp-default): sudo apt-get install libminiupnpc-dev -ZMQ dependencies (provides ZMQ API 4.x): +ZMQ dependencies (provides ZMQ API): sudo apt-get install libzmq3-dev @@ -278,6 +278,7 @@ To build executables for ARM: cd depends make HOST=arm-linux-gnueabihf NO_QT=1 cd .. + ./autogen.sh ./configure --prefix=$PWD/depends/arm-linux-gnueabihf --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++ make diff --git a/doc/dependencies.md b/doc/dependencies.md index 3fc7aecba8..d777aaf66f 100644 --- a/doc/dependencies.md +++ b/doc/dependencies.md @@ -26,5 +26,5 @@ These are the dependencies currently used by Bitcoin Core. You can find instruct | Qt | [5.9.6](https://download.qt.io/official_releases/qt/) | 5.x | No | | | | XCB | | | | | [Yes](https://github.com/bitcoin/bitcoin/blob/master/depends/packages/qt.mk#L87) (Linux only) | | xkbcommon | | | | | [Yes](https://github.com/bitcoin/bitcoin/blob/master/depends/packages/qt.mk#L86) (Linux only) | -| ZeroMQ | [4.2.3](https://github.com/zeromq/libzmq/releases) | | No | | | +| ZeroMQ | [4.2.5](https://github.com/zeromq/libzmq/releases) | 4.0.0 | No | | | | zlib | [1.2.11](https://zlib.net/) | | | | No | diff --git a/doc/release-notes-13152.md b/doc/release-notes-13152.md new file mode 100644 index 0000000000..72526f5355 --- /dev/null +++ b/doc/release-notes-13152.md @@ -0,0 +1,4 @@ +New RPC methods +------------ + +- `getnodeaddresses` returns peer addresses known to this node. It may be used to connect to nodes over TCP without using the DNS seeds.
\ No newline at end of file diff --git a/doc/release-notes/release-notes-0.16.3.md b/doc/release-notes/release-notes-0.16.3.md new file mode 100644 index 0000000000..2e52d309c2 --- /dev/null +++ b/doc/release-notes/release-notes-0.16.3.md @@ -0,0 +1,88 @@ +Bitcoin Core version 0.16.3 is now available from: + + <https://bitcoincore.org/bin/bitcoin-core-0.16.3/> + +This is a new minor version release, with various bugfixes. + +Please report bugs using the issue tracker at GitHub: + + <https://github.com/bitcoin/bitcoin/issues> + +To receive security and update notifications, please subscribe to: + + <https://bitcoincore.org/en/list/announcements/join/> + +How to Upgrade +============== + +If you are running an older version, shut it down. Wait until it has completely +shut down (which might take a few minutes for older versions), then run the +installer (on Windows) or just copy over `/Applications/Bitcoin-Qt` (on Mac) +or `bitcoind`/`bitcoin-qt` (on Linux). + +The first time you run version 0.15.0 or newer, your chainstate database will be converted to a +new format, which will take anywhere from a few minutes to half an hour, +depending on the speed of your machine. + +Note that the block database format also changed in version 0.8.0 and there is no +automatic upgrade code from before version 0.8 to version 0.15.0 or higher. Upgrading +directly from 0.7.x and earlier without re-downloading the blockchain is not supported. +However, as usual, old wallet versions are still supported. + +Downgrading warning +------------------- + +Wallets created in 0.16 and later are not compatible with versions prior to 0.16 +and will not work if you try to use newly created wallets in older versions. Existing +wallets that were created with older versions are not affected by this. + +Compatibility +============== + +Bitcoin Core is extensively tested on multiple operating systems using +the Linux kernel, macOS 10.8+, and Windows Vista and later. Windows XP is not supported. + +Bitcoin Core should also work on most other Unix-like systems but is not +frequently tested on them. + +Notable changes +=============== + +Denial-of-Service vulnerability +------------------------------- + +A denial-of-service vulnerability (CVE-2018-17144) exploitable by miners has +been discovered in Bitcoin Core versions 0.14.0 up to 0.16.2. It is recommended +to upgrade any of the vulnerable versions to 0.16.3 as soon as possible. + +0.16.3 change log +------------------ + +### Consensus +- #14249 `696b936` Fix crash bug with duplicate inputs within a transaction (TheBlueMatt, sdaftuar) + +### RPC and other APIs +- #13547 `212ef1f` Make `signrawtransaction*` give an error when amount is needed but missing (ajtowns) + +### Miscellaneous +- #13655 `1cdbea7` bitcoinconsensus: invalid flags error should be set to `bitcoinconsensus_err` (afk11) + +### Documentation +- #13844 `11b9dbb` correct the help output for -prune (hebasto) + +Credits +======= + +Thanks to everyone who directly contributed to this release: + +- Anthony Towns +- Hennadii Stepanov +- Matt Corallo +- Suhas Daftuar +- Thomas Kerin +- Wladimir J. van der Laan + +And to those that reported security issues: + +- (anonymous reporter) + diff --git a/doc/zmq.md b/doc/zmq.md index 5d67df9d22..a1a506f2e7 100644 --- a/doc/zmq.md +++ b/doc/zmq.md @@ -33,8 +33,10 @@ buffering or reassembly. ## Prerequisites -The ZeroMQ feature in Bitcoin Core requires ZeroMQ API version 4.x or -newer. Typically, it is packaged by distributions as something like +The ZeroMQ feature in Bitcoin Core requires the ZeroMQ API >= 4.0.0 +[libzmq](https://github.com/zeromq/libzmq/releases). +For version information, see [dependencies.md](dependencies.md). +Typically, it is packaged by distributions as something like *libzmq3-dev*. The C++ wrapper for ZeroMQ is *not* needed. In order to run the example Python client scripts in contrib/ one must diff --git a/src/Makefile.am b/src/Makefile.am index 159812e847..f7d7a5d377 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -467,7 +467,7 @@ bitcoind_LDADD = \ $(LIBMEMENV) \ $(LIBSECP256K1) -bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS) +bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS) # bitcoin-cli binary # bitcoin_cli_SOURCES = bitcoin-cli.cpp @@ -485,7 +485,7 @@ bitcoin_cli_LDADD = \ $(LIBBITCOIN_UTIL) \ $(LIBBITCOIN_CRYPTO) -bitcoin_cli_LDADD += $(BOOST_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(EVENT_LIBS) +bitcoin_cli_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS) $(EVENT_LIBS) # # bitcoin-tx binary # diff --git a/src/Makefile.bench.include b/src/Makefile.bench.include index 76177630ab..544092520f 100644 --- a/src/Makefile.bench.include +++ b/src/Makefile.bench.include @@ -56,7 +56,7 @@ if ENABLE_WALLET bench_bench_bitcoin_SOURCES += bench/coin_selection.cpp endif -bench_bench_bitcoin_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) +bench_bench_bitcoin_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) bench_bench_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) CLEAN_BITCOIN_BENCH = bench/*.gcda bench/*.gcno $(GENERATED_BENCH_FILES) diff --git a/src/Makefile.test.include b/src/Makefile.test.include index c4ee5f5fcc..269a6ff805 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -128,7 +128,7 @@ test_test_bitcoin_LDADD += $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_C $(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(EVENT_LIBS) $(EVENT_PTHREADS_LIBS) test_test_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) -test_test_bitcoin_LDADD += $(LIBBITCOIN_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(RAPIDCHECK_LIBS) +test_test_bitcoin_LDADD += $(LIBBITCOIN_CONSENSUS) $(BDB_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(RAPIDCHECK_LIBS) test_test_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static if ENABLE_ZMQ diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 53c3821ce5..09507fd249 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -139,11 +139,6 @@ static int AppInitRPC(int argc, char* argv[]) fprintf(stderr, "Error: %s\n", e.what()); return EXIT_FAILURE; } - if (gArgs.GetBoolArg("-rpcssl", false)) - { - fprintf(stderr, "Error: SSL mode for RPC (-rpcssl) is no longer supported.\n"); - return EXIT_FAILURE; - } return CONTINUE_EXECUTION; } diff --git a/src/httpserver.cpp b/src/httpserver.cpp index e176746207..c29f7a4375 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -352,13 +352,6 @@ bool InitHTTPServer() if (!InitHTTPAllowList()) return false; - if (gArgs.GetBoolArg("-rpcssl", false)) { - uiInterface.ThreadSafeMessageBox( - "SSL mode for RPC (-rpcssl) is no longer supported.", - "", CClientUIInterface::MSG_ERROR); - return false; - } - // Redirect libevent's logging to our own log event_set_log_callback(&libevent_log_cb); // Update libevent's log handling. Returns false if our version of diff --git a/src/init.cpp b/src/init.cpp index 326e71c8bb..d10edbd8b6 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -322,8 +322,8 @@ void SetupServerArgs() const auto regtestChainParams = CreateChainParams(CBaseChainParams::REGTEST); // Hidden Options - std::vector<std::string> hidden_args = {"-rpcssl", "-benchmark", "-h", "-help", "-socks", "-tor", "-debugnet", "-whitelistalwaysrelay", - "-prematurewitness", "-walletprematurewitness", "-promiscuousmempoolflags", "-blockminsize", "-dbcrashratio", "-forcecompactdb", "-usehd", + std::vector<std::string> hidden_args = {"-h", "-help", + "-dbcrashratio", "-forcecompactdb", "-usehd", // GUI args. These will be overwritten by SetupUIArgs for the GUI "-allowselfsignedrootcertificates", "-choosedatadir", "-lang=<lang>", "-min", "-resetguisettings", "-rootcertificates=<file>", "-splash", "-uiplatform"}; @@ -426,7 +426,14 @@ void SetupServerArgs() #endif gArgs.AddArg("-checkblocks=<n>", strprintf("How many blocks to check at startup (default: %u, 0 = all)", DEFAULT_CHECKBLOCKS), true, OptionsCategory::DEBUG_TEST); - gArgs.AddArg("-checklevel=<n>", strprintf("How thorough the block verification of -checkblocks is (0-4, default: %u)", DEFAULT_CHECKLEVEL), true, OptionsCategory::DEBUG_TEST); + gArgs.AddArg("-checklevel=<n>", strprintf("How thorough the block verification of -checkblocks is: " + "level 0 reads the blocks from disk, " + "level 1 verifies block validity, " + "level 2 verifies undo data, " + "level 3 checks disconnection of tip blocks, " + "and level 4 tries to reconnect the blocks, " + "each level includes the checks of the previous levels " + "(0-4, default: %u)", DEFAULT_CHECKLEVEL), true, OptionsCategory::DEBUG_TEST); gArgs.AddArg("-checkblockindex", strprintf("Do a full consistency check for mapBlockIndex, setBlockIndexCandidates, chainActive and mapBlocksUnlinked occasionally. (default: %u, regtest: %u)", defaultChainParams->DefaultConsistencyChecks(), regtestChainParams->DefaultConsistencyChecks()), true, OptionsCategory::DEBUG_TEST); gArgs.AddArg("-checkmempool=<n>", strprintf("Run checks every <n> transactions (default: %u, regtest: %u)", defaultChainParams->DefaultConsistencyChecks(), regtestChainParams->DefaultConsistencyChecks()), true, OptionsCategory::DEBUG_TEST); gArgs.AddArg("-checkpoints", strprintf("Disable expensive verification for known chain history (default: %u)", DEFAULT_CHECKPOINTS_ENABLED), true, OptionsCategory::DEBUG_TEST); @@ -954,25 +961,6 @@ bool AppInitParameterInteraction() } } - // Check for -debugnet - if (gArgs.GetBoolArg("-debugnet", false)) - InitWarning(_("Unsupported argument -debugnet ignored, use -debug=net.")); - // Check for -socks - as this is a privacy risk to continue, exit here - if (gArgs.IsArgSet("-socks")) - return InitError(_("Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.")); - // Check for -tor - as this is a privacy risk to continue, exit here - if (gArgs.GetBoolArg("-tor", false)) - return InitError(_("Unsupported argument -tor found, use -onion.")); - - if (gArgs.GetBoolArg("-benchmark", false)) - InitWarning(_("Unsupported argument -benchmark ignored, use -debug=bench.")); - - if (gArgs.GetBoolArg("-whitelistalwaysrelay", false)) - InitWarning(_("Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay.")); - - if (gArgs.IsArgSet("-blockminsize")) - InitWarning("Unsupported argument -blockminsize ignored."); - // Checkmempool and checkblockindex default to true in regtest mode int ratio = std::min<int>(std::max<int>(gArgs.GetArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0), 1000000); if (ratio != 0) { diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index 673f63a19b..a0270daf99 100644 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -123,16 +123,15 @@ void AskPassphraseDialog::accept() { QMessageBox::warning(this, tr("Wallet encrypted"), "<qt>" + - tr("%1 will close now to finish the encryption process. " + tr("Your wallet is now encrypted. " "Remember that encrypting your wallet cannot fully protect " - "your bitcoins from being stolen by malware infecting your computer.").arg(tr(PACKAGE_NAME)) + + "your bitcoins from being stolen by malware infecting your computer.") + "<br><br><b>" + tr("IMPORTANT: Any previous backups you have made of your wallet file " "should be replaced with the newly generated, encrypted wallet file. " "For security reasons, previous backups of the unencrypted wallet file " "will become useless as soon as you start using the new, encrypted wallet.") + "</b></qt>"); - QApplication::quit(); } else { diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index f4d44fc809..649e222c39 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -163,6 +163,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "rescanblockchain", 0, "start_height"}, { "rescanblockchain", 1, "stop_height"}, { "createwallet", 1, "disable_private_keys"}, + { "getnodeaddresses", 0, "count"}, }; // clang-format on diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 099a7cf1da..846d90cd0a 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -626,6 +626,58 @@ static UniValue setnetworkactive(const JSONRPCRequest& request) return g_connman->GetNetworkActive(); } +static UniValue getnodeaddresses(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() > 1) { + throw std::runtime_error( + "getnodeaddresses ( count )\n" + "\nReturn known addresses which can potentially be used to find new nodes in the network\n" + "\nArguments:\n" + "1. \"count\" (numeric, optional) How many addresses to return. Limited to the smaller of " + std::to_string(ADDRMAN_GETADDR_MAX) + + " or " + std::to_string(ADDRMAN_GETADDR_MAX_PCT) + "% of all known addresses. (default = 1)\n" + "\nResult:\n" + "[\n" + " {\n" + " \"time\": ttt, (numeric) Timestamp in seconds since epoch (Jan 1 1970 GMT) keeping track of when the node was last seen\n" + " \"services\": n, (numeric) The services offered\n" + " \"address\": \"host\", (string) The address of the node\n" + " \"port\": n (numeric) The port of the node\n" + " }\n" + " ,....\n" + "]\n" + "\nExamples:\n" + + HelpExampleCli("getnodeaddresses", "8") + + HelpExampleRpc("getnodeaddresses", "8") + ); + } + if (!g_connman) { + throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); + } + + int count = 1; + if (!request.params[0].isNull()) { + count = request.params[0].get_int(); + if (count <= 0) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Address count out of range"); + } + } + // returns a shuffled list of CAddress + std::vector<CAddress> vAddr = g_connman->GetAddresses(); + UniValue ret(UniValue::VARR); + + int address_return_count = std::min<int>(count, vAddr.size()); + for (int i = 0; i < address_return_count; ++i) { + UniValue obj(UniValue::VOBJ); + const CAddress& addr = vAddr[i]; + obj.pushKV("time", (int)addr.nTime); + obj.pushKV("services", (uint64_t)addr.nServices); + obj.pushKV("address", addr.ToStringIP()); + obj.pushKV("port", addr.GetPort()); + ret.push_back(obj); + } + return ret; +} + // clang-format off static const CRPCCommand commands[] = { // category name actor (function) argNames @@ -642,6 +694,7 @@ static const CRPCCommand commands[] = { "network", "listbanned", &listbanned, {} }, { "network", "clearbanned", &clearbanned, {} }, { "network", "setnetworkactive", &setnetworkactive, {"state"} }, + { "network", "getnodeaddresses", &getnodeaddresses, {"count"} }, }; // clang-format on diff --git a/src/validation.cpp b/src/validation.cpp index cb617ae6a5..458458d85d 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -3122,7 +3122,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P // Check transactions for (const auto& tx : block.vtx) - if (!CheckTransaction(*tx, state, false)) + if (!CheckTransaction(*tx, state, true)) return state.Invalid(false, state.GetRejectCode(), state.GetRejectReason(), strprintf("Transaction check failed (tx hash %s) %s", tx->GetHash().ToString(), state.GetDebugMessage())); diff --git a/src/validation.h b/src/validation.h index 3df6456eca..1034ba4665 100644 --- a/src/validation.h +++ b/src/validation.h @@ -53,9 +53,9 @@ static const bool DEFAULT_WHITELISTFORCERELAY = true; /** Default for -minrelaytxfee, minimum relay fee for transactions */ static const unsigned int DEFAULT_MIN_RELAY_TX_FEE = 1000; //! -maxtxfee default -static const CAmount DEFAULT_TRANSACTION_MAXFEE = 0.1 * COIN; +static const CAmount DEFAULT_TRANSACTION_MAXFEE = COIN / 10; //! Discourage users to set fees higher than this amount (in satoshis) per kB -static const CAmount HIGH_TX_FEE_PER_KB = 0.01 * COIN; +static const CAmount HIGH_TX_FEE_PER_KB = COIN / 100; //! -maxtxfee will warn if called with a higher fee than this amount (in satoshis) static const CAmount HIGH_MAX_TX_FEE = 100 * HIGH_TX_FEE_PER_KB; /** Default for -limitancestorcount, max number of in-mempool ancestors */ diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index 025ae29753..a7bf89c572 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -556,6 +556,7 @@ void BerkeleyBatch::Close() LOCK(cs_db); --env->mapFileUseCount[strFile]; } + env->m_db_in_use.notify_all(); } void BerkeleyEnvironment::CloseDb(const std::string& strFile) @@ -572,6 +573,32 @@ void BerkeleyEnvironment::CloseDb(const std::string& strFile) } } +void BerkeleyEnvironment::ReloadDbEnv() +{ + // Make sure that no Db's are in use + AssertLockNotHeld(cs_db); + std::unique_lock<CCriticalSection> lock(cs_db); + m_db_in_use.wait(lock, [this](){ + for (auto& count : mapFileUseCount) { + if (count.second > 0) return false; + } + return true; + }); + + std::vector<std::string> filenames; + for (auto it : mapDb) { + filenames.push_back(it.first); + } + // Close the individual Db's + for (const std::string& filename : filenames) { + CloseDb(filename); + } + // Reset the environment + Flush(true); // This will flush and close the environment + Reset(); + Open(true); +} + bool BerkeleyBatch::Rewrite(BerkeleyDatabase& database, const char* pszSkip) { if (database.IsDummy()) { @@ -697,7 +724,6 @@ void BerkeleyEnvironment::Flush(bool fShutdown) if (!fMockDb) { fs::remove_all(fs::path(strPath) / "database"); } - g_dbenvs.erase(strPath); } } } @@ -796,6 +822,17 @@ void BerkeleyDatabase::Flush(bool shutdown) { if (!IsDummy()) { env->Flush(shutdown); - if (shutdown) env = nullptr; + if (shutdown) { + LOCK(cs_db); + g_dbenvs.erase(env->Directory().string()); + env = nullptr; + } + } +} + +void BerkeleyDatabase::ReloadDbEnv() +{ + if (!IsDummy()) { + env->ReloadDbEnv(); } } diff --git a/src/wallet/db.h b/src/wallet/db.h index b078edab7b..467ed13b45 100644 --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -38,6 +38,7 @@ public: std::unique_ptr<DbEnv> dbenv; std::map<std::string, int> mapFileUseCount; std::map<std::string, Db*> mapDb; + std::condition_variable_any m_db_in_use; BerkeleyEnvironment(const fs::path& env_directory); ~BerkeleyEnvironment(); @@ -75,6 +76,7 @@ public: void CheckpointLSN(const std::string& strFile); void CloseDb(const std::string& strFile); + void ReloadDbEnv(); DbTxn* TxnBegin(int flags = DB_TXN_WRITE_NOSYNC) { @@ -145,6 +147,8 @@ public: void IncrementUpdateCounter(); + void ReloadDbEnv(); + std::atomic<unsigned int> nUpdateCounter; unsigned int nLastSeen; unsigned int nLastFlushed; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 15f3e5947e..1a2dff9a96 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2121,7 +2121,6 @@ static UniValue encryptwallet(const JSONRPCRequest& request) "will require the passphrase to be set prior the making these calls.\n" "Use the walletpassphrase call for this, and then walletlock call.\n" "If the wallet is already encrypted, use the walletpassphrasechange call.\n" - "Note that this will shutdown the server.\n" "\nArguments:\n" "1. \"passphrase\" (string) The pass phrase to encrypt the wallet with. It must be at least 1 character, but should be long.\n" "\nExamples:\n" @@ -2159,11 +2158,7 @@ static UniValue encryptwallet(const JSONRPCRequest& request) throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Error: Failed to encrypt the wallet."); } - // BDB seems to have a bad habit of writing old data into - // slack space in .dat files; that is bad if the old data is - // unencrypted private keys. So: - StartShutdown(); - return "wallet encrypted; Bitcoin server stopping, restart to run with encrypted wallet. The keypool has been flushed and a new HD seed was generated (if you are using HD). You need to make a new backup."; + return "wallet encrypted; The keypool has been flushed and a new HD seed was generated (if you are using HD). You need to make a new backup."; } static UniValue lockunspent(const JSONRPCRequest& request) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index f3d6d0056d..7f7a88e986 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -722,6 +722,11 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) // bits of the unencrypted private key in slack space in the database file. database->Rewrite(); + // BDB seems to have a bad habit of writing old data into + // slack space in .dat files; that is bad if the old data is + // unencrypted private keys. So: + database->ReloadDbEnv(); + } NotifyStatusChanged(this); diff --git a/src/zmq/zmqnotificationinterface.cpp b/src/zmq/zmqnotificationinterface.cpp index 8cbc969972..1d9f86d450 100644 --- a/src/zmq/zmqnotificationinterface.cpp +++ b/src/zmq/zmqnotificationinterface.cpp @@ -81,10 +81,14 @@ CZMQNotificationInterface* CZMQNotificationInterface::Create() // Called at startup to conditionally set up ZMQ socket(s) bool CZMQNotificationInterface::Initialize() { + int major = 0, minor = 0, patch = 0; + zmq_version(&major, &minor, &patch); + LogPrint(BCLog::ZMQ, "zmq: version %d.%d.%d\n", major, minor, patch); + LogPrint(BCLog::ZMQ, "zmq: Initialize notification interface\n"); assert(!pcontext); - pcontext = zmq_init(1); + pcontext = zmq_ctx_new(); if (!pcontext) { @@ -127,7 +131,7 @@ void CZMQNotificationInterface::Shutdown() LogPrint(BCLog::ZMQ, " Shutdown notifier %s at %s\n", notifier->GetType(), notifier->GetAddress()); notifier->Shutdown(); } - zmq_ctx_destroy(pcontext); + zmq_ctx_term(pcontext); pcontext = nullptr; } diff --git a/test/functional/example_test.py b/test/functional/example_test.py index 4c9d60b337..3f15367a75 100755 --- a/test/functional/example_test.py +++ b/test/functional/example_test.py @@ -85,6 +85,8 @@ class ExampleTest(BitcoinTestFramework): # self.log.info("I've finished set_test_params") # Oops! Can't run self.log before run_test() + # Use skip_test_if_missing_module() to skip the test if your test requires certain modules to be present. + # This test uses generate which requires wallet to be compiled def skip_test_if_missing_module(self): self.skip_if_no_wallet() @@ -115,7 +117,7 @@ class ExampleTest(BitcoinTestFramework): # sync_all() should not include node2, since we're not expecting it to # sync. connect_nodes(self.nodes[0], 1) - self.sync_all([self.nodes[0:1]]) + self.sync_all([self.nodes[0:2]]) # Use setup_nodes() to customize the node start behaviour (for example if # you don't want to start all nodes at the start of the test). @@ -139,7 +141,7 @@ class ExampleTest(BitcoinTestFramework): # Generating a block on one of the nodes will get us out of IBD blocks = [int(self.nodes[0].generate(nblocks=1)[0], 16)] - self.sync_all([self.nodes[0:1]]) + self.sync_all([self.nodes[0:2]]) # Notice above how we called an RPC by calling a method with the same # name on the node object. Notice also how we used a keyword argument diff --git a/test/functional/feature_block.py b/test/functional/feature_block.py index 6e36ea5601..71c3a396c1 100755 --- a/test/functional/feature_block.py +++ b/test/functional/feature_block.py @@ -75,9 +75,6 @@ class FullBlockTest(BitcoinTestFramework): self.setup_clean_chain = True self.extra_args = [[]] - def skip_test_if_missing_module(self): - self.skip_if_no_wallet() - def run_test(self): node = self.nodes[0] # convenience reference to the node diff --git a/test/functional/feature_blocksdir.py b/test/functional/feature_blocksdir.py index 824f0d7e09..c170f510c8 100755 --- a/test/functional/feature_blocksdir.py +++ b/test/functional/feature_blocksdir.py @@ -16,9 +16,6 @@ class BlocksdirTest(BitcoinTestFramework): self.setup_clean_chain = True self.num_nodes = 1 - def skip_test_if_missing_module(self): - self.skip_if_no_wallet() - def run_test(self): self.stop_node(0) shutil.rmtree(self.nodes[0].datadir) @@ -30,7 +27,7 @@ class BlocksdirTest(BitcoinTestFramework): self.log.info("Starting with existing blocksdir ...") self.start_node(0, ["-blocksdir=" + blocksdir_path]) self.log.info("mining blocks..") - self.nodes[0].generate(10) + self.nodes[0].generatetoaddress(10, self.nodes[0].get_deterministic_priv_key().address) assert os.path.isfile(os.path.join(blocksdir_path, "regtest", "blocks", "blk00000.dat")) assert os.path.isdir(os.path.join(self.nodes[0].datadir, "regtest", "blocks", "index")) diff --git a/test/functional/feature_logging.py b/test/functional/feature_logging.py index a74c413440..8bb7e02695 100755 --- a/test/functional/feature_logging.py +++ b/test/functional/feature_logging.py @@ -15,9 +15,6 @@ class LoggingTest(BitcoinTestFramework): self.num_nodes = 1 self.setup_clean_chain = True - def skip_test_if_missing_module(self): - self.skip_if_no_wallet() - def relative_log_path(self, name): return os.path.join(self.nodes[0].datadir, "regtest", name) diff --git a/test/functional/feature_minchainwork.py b/test/functional/feature_minchainwork.py index 5d180c2244..dbff6f15f2 100755 --- a/test/functional/feature_minchainwork.py +++ b/test/functional/feature_minchainwork.py @@ -31,9 +31,6 @@ class MinimumChainWorkTest(BitcoinTestFramework): self.extra_args = [[], ["-minimumchainwork=0x65"], ["-minimumchainwork=0x65"]] self.node_min_work = [0, 101, 101] - def skip_test_if_missing_module(self): - self.skip_if_no_wallet() - def setup_network(self): # This test relies on the chain setup being: # node0 <- node1 <- node2 @@ -54,7 +51,8 @@ class MinimumChainWorkTest(BitcoinTestFramework): num_blocks_to_generate = int((self.node_min_work[1] - starting_chain_work) / REGTEST_WORK_PER_BLOCK) self.log.info("Generating %d blocks on node0", num_blocks_to_generate) - hashes = self.nodes[0].generate(num_blocks_to_generate) + hashes = self.nodes[0].generatetoaddress(num_blocks_to_generate, + self.nodes[0].get_deterministic_priv_key().address) self.log.info("Node0 current chain work: %s", self.nodes[0].getblockheader(hashes[-1])['chainwork']) @@ -75,7 +73,7 @@ class MinimumChainWorkTest(BitcoinTestFramework): assert_equal(self.nodes[2].getblockcount(), starting_blockcount) self.log.info("Generating one more block") - self.nodes[0].generate(1) + self.nodes[0].generatetoaddress(1, self.nodes[0].get_deterministic_priv_key().address) self.log.info("Verifying nodes are all synced") diff --git a/test/functional/feature_reindex.py b/test/functional/feature_reindex.py index 3727eeaeae..940b403f9c 100755 --- a/test/functional/feature_reindex.py +++ b/test/functional/feature_reindex.py @@ -18,11 +18,8 @@ class ReindexTest(BitcoinTestFramework): self.setup_clean_chain = True self.num_nodes = 1 - def skip_test_if_missing_module(self): - self.skip_if_no_wallet() - def reindex(self, justchainstate=False): - self.nodes[0].generate(3) + self.nodes[0].generatetoaddress(3, self.nodes[0].get_deterministic_priv_key().address) blockcount = self.nodes[0].getblockcount() self.stop_nodes() extra_args = [["-reindex-chainstate" if justchainstate else "-reindex"]] diff --git a/test/functional/feature_versionbits_warning.py b/test/functional/feature_versionbits_warning.py index cf77720437..88df61cabc 100755 --- a/test/functional/feature_versionbits_warning.py +++ b/test/functional/feature_versionbits_warning.py @@ -31,9 +31,6 @@ class VersionBitsWarningTest(BitcoinTestFramework): self.setup_clean_chain = True self.num_nodes = 1 - def skip_test_if_missing_module(self): - self.skip_if_no_wallet() - def setup_network(self): self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt") # Open and close to create zero-length file @@ -68,13 +65,14 @@ class VersionBitsWarningTest(BitcoinTestFramework): node = self.nodes[0] node.add_p2p_connection(P2PInterface()) + node_deterministic_address = node.get_deterministic_priv_key().address # Mine one period worth of blocks - node.generate(VB_PERIOD) + node.generatetoaddress(VB_PERIOD, node_deterministic_address) self.log.info("Check that there is no warning if previous VB_BLOCKS have <VB_THRESHOLD blocks with unknown versionbits version.") # Build one period of blocks with < VB_THRESHOLD blocks signaling some unknown bit self.send_blocks_with_version(node.p2p, VB_THRESHOLD - 1, VB_UNKNOWN_VERSION) - node.generate(VB_PERIOD - VB_THRESHOLD + 1) + node.generatetoaddress(VB_PERIOD - VB_THRESHOLD + 1, node_deterministic_address) # Check that we're not getting any versionbit-related errors in get*info() assert(not VB_PATTERN.match(node.getmininginfo()["warnings"])) @@ -83,7 +81,7 @@ class VersionBitsWarningTest(BitcoinTestFramework): self.log.info("Check that there is a warning if >50 blocks in the last 100 were an unknown version") # Build one period of blocks with VB_THRESHOLD blocks signaling some unknown bit self.send_blocks_with_version(node.p2p, VB_THRESHOLD, VB_UNKNOWN_VERSION) - node.generate(VB_PERIOD - VB_THRESHOLD) + node.generatetoaddress(VB_PERIOD - VB_THRESHOLD, node_deterministic_address) # Check that get*info() shows the 51/100 unknown block version error. assert(WARN_UNKNOWN_RULES_MINED in node.getmininginfo()["warnings"]) @@ -92,16 +90,16 @@ class VersionBitsWarningTest(BitcoinTestFramework): self.log.info("Check that there is a warning if previous VB_BLOCKS have >=VB_THRESHOLD blocks with unknown versionbits version.") # Mine a period worth of expected blocks so the generic block-version warning # is cleared. This will move the versionbit state to ACTIVE. - node.generate(VB_PERIOD) + node.generatetoaddress(VB_PERIOD, node_deterministic_address) # Stop-start the node. This is required because bitcoind will only warn once about unknown versions or unknown rules activating. self.restart_node(0) # Generating one block guarantees that we'll get out of IBD - node.generate(1) + node.generatetoaddress(1, node_deterministic_address) wait_until(lambda: not node.getblockchaininfo()['initialblockdownload'], timeout=10, lock=mininode_lock) # Generating one more block will be enough to generate an error. - node.generate(1) + node.generatetoaddress(1, node_deterministic_address) # Check that get*info() shows the versionbits unknown rules warning assert(WARN_UNKNOWN_RULES_ACTIVE in node.getmininginfo()["warnings"]) assert(WARN_UNKNOWN_RULES_ACTIVE in node.getnetworkinfo()["warnings"]) diff --git a/test/functional/interface_zmq.py b/test/functional/interface_zmq.py index c853ba7e3f..1c518eab75 100755 --- a/test/functional/interface_zmq.py +++ b/test/functional/interface_zmq.py @@ -44,12 +44,6 @@ class ZMQTest (BitcoinTestFramework): self.skip_if_no_wallet() def setup_nodes(self): - # Import keys - self.add_nodes(self.num_nodes) - self.start_nodes() - super().import_deterministic_coinbase_privkeys() - self.stop_nodes() - import zmq # Initialize ZMQ context and socket. @@ -69,12 +63,13 @@ class ZMQTest (BitcoinTestFramework): self.rawblock = ZMQSubscriber(socket, b"rawblock") self.rawtx = ZMQSubscriber(socket, b"rawtx") - self.nodes[0].extra_args = ["-zmqpub%s=%s" % (sub.topic.decode(), address) for sub in [self.hashblock, self.hashtx, self.rawblock, self.rawtx]] + self.extra_args = [ + ["-zmqpub%s=%s" % (sub.topic.decode(), address) for sub in [self.hashblock, self.hashtx, self.rawblock, self.rawtx]], + [], + ] + self.add_nodes(self.num_nodes, self.extra_args) self.start_nodes() - def import_deterministic_coinbase_privkeys(self): - pass - def run_test(self): try: self._zmq_test() diff --git a/test/functional/mining_basic.py b/test/functional/mining_basic.py index f95ad31e7c..ff55ea5528 100755 --- a/test/functional/mining_basic.py +++ b/test/functional/mining_basic.py @@ -38,9 +38,6 @@ class MiningTest(BitcoinTestFramework): self.num_nodes = 2 self.setup_clean_chain = False - def skip_test_if_missing_module(self): - self.skip_if_no_wallet() - def run_test(self): node = self.nodes[0] @@ -61,7 +58,7 @@ class MiningTest(BitcoinTestFramework): assert_equal(mining_info['pooledtx'], 0) # Mine a block to leave initial block download - node.generate(1) + node.generatetoaddress(1, node.get_deterministic_priv_key().address) tmpl = node.getblocktemplate() self.log.info("getblocktemplate: Test capability advertised") assert 'proposal' in tmpl['capabilities'] @@ -212,7 +209,7 @@ class MiningTest(BitcoinTestFramework): assert chain_tip(block.hash, status='active', branchlen=0) in node.getchaintips() # Building a few blocks should give the same results - node.generate(10) + node.generatetoaddress(10, node.get_deterministic_priv_key().address) assert_raises_rpc_error(-25, 'time-too-old', lambda: node.submitheader(hexdata=b2x(CBlockHeader(bad_block_time).serialize()))) assert_raises_rpc_error(-25, 'bad-prevblk', lambda: node.submitheader(hexdata=b2x(CBlockHeader(bad_block2).serialize()))) node.submitheader(hexdata=b2x(CBlockHeader(block).serialize())) diff --git a/test/functional/p2p_fingerprint.py b/test/functional/p2p_fingerprint.py index 884fb4b063..fab0887197 100755 --- a/test/functional/p2p_fingerprint.py +++ b/test/functional/p2p_fingerprint.py @@ -30,9 +30,6 @@ class P2PFingerprintTest(BitcoinTestFramework): self.setup_clean_chain = True self.num_nodes = 1 - def skip_test_if_missing_module(self): - self.skip_if_no_wallet() - # Build a chain of blocks on top of given one def build_chain(self, nblocks, prev_hash, prev_height, prev_median_time): blocks = [] @@ -83,7 +80,7 @@ class P2PFingerprintTest(BitcoinTestFramework): self.nodes[0].setmocktime(int(time.time()) - 60 * 24 * 60 * 60) # Generating a chain of 10 blocks - block_hashes = self.nodes[0].generate(nblocks=10) + block_hashes = self.nodes[0].generatetoaddress(10, self.nodes[0].get_deterministic_priv_key().address) # Create longer chain starting 2 blocks before current tip height = len(block_hashes) - 2 @@ -114,7 +111,7 @@ class P2PFingerprintTest(BitcoinTestFramework): # Longest chain is extended so stale is much older than chain tip self.nodes[0].setmocktime(0) - tip = self.nodes[0].generate(nblocks=1)[0] + tip = self.nodes[0].generatetoaddress(1, self.nodes[0].get_deterministic_priv_key().address)[0] assert_equal(self.nodes[0].getblockcount(), 14) # Send getdata & getheaders to refresh last received getheader message diff --git a/test/functional/p2p_invalid_block.py b/test/functional/p2p_invalid_block.py index fd6b84f8b2..0678b1a651 100755 --- a/test/functional/p2p_invalid_block.py +++ b/test/functional/p2p_invalid_block.py @@ -24,9 +24,6 @@ class InvalidBlockRequestTest(BitcoinTestFramework): self.setup_clean_chain = True self.extra_args = [["-whitelist=127.0.0.1"]] - def skip_test_if_missing_module(self): - self.skip_if_no_wallet() - def run_test(self): # Add p2p connection to node0 node = self.nodes[0] # convenience reference to the node @@ -48,7 +45,7 @@ class InvalidBlockRequestTest(BitcoinTestFramework): node.p2p.send_blocks_and_test([block1], node, success=True) self.log.info("Mature the block.") - node.generate(100) + node.generatetoaddress(100, node.get_deterministic_priv_key().address) best_block = node.getblock(node.getbestblockhash()) tip = int(node.getbestblockhash(), 16) @@ -84,6 +81,16 @@ class InvalidBlockRequestTest(BitcoinTestFramework): node.p2p.send_blocks_and_test([block2], node, success=False, request_block=False, reject_reason='bad-txns-duplicate') + # Check transactions for duplicate inputs + self.log.info("Test duplicate input block.") + + block2_orig.vtx[2].vin.append(block2_orig.vtx[2].vin[0]) + block2_orig.vtx[2].rehash() + block2_orig.hashMerkleRoot = block2_orig.calc_merkle_root() + block2_orig.rehash() + block2_orig.solve() + node.p2p.send_blocks_and_test([block2_orig], node, success=False, request_block=False, reject_reason='bad-txns-inputs-duplicate') + self.log.info("Test very broken block.") block3 = create_block(tip, create_coinbase(height), block_time) diff --git a/test/functional/p2p_invalid_locator.py b/test/functional/p2p_invalid_locator.py index 4cc43a4fa4..c8c752d1f7 100755 --- a/test/functional/p2p_invalid_locator.py +++ b/test/functional/p2p_invalid_locator.py @@ -15,12 +15,9 @@ class InvalidLocatorTest(BitcoinTestFramework): self.num_nodes = 1 self.setup_clean_chain = False - def skip_test_if_missing_module(self): - self.skip_if_no_wallet() - def run_test(self): node = self.nodes[0] # convenience reference to the node - node.generate(1) # Get node out of IBD + node.generatetoaddress(1, node.get_deterministic_priv_key().address) # Get node out of IBD self.log.info('Test max locator size') block_count = node.getblockcount() diff --git a/test/functional/p2p_invalid_tx.py b/test/functional/p2p_invalid_tx.py index 2f19b4d933..58e129b57d 100755 --- a/test/functional/p2p_invalid_tx.py +++ b/test/functional/p2p_invalid_tx.py @@ -26,9 +26,6 @@ class InvalidTxRequestTest(BitcoinTestFramework): self.num_nodes = 1 self.setup_clean_chain = True - def skip_test_if_missing_module(self): - self.skip_if_no_wallet() - def bootstrap_p2p(self, *, num_connections=1): """Add a P2P connection to the node. @@ -64,7 +61,7 @@ class InvalidTxRequestTest(BitcoinTestFramework): node.p2p.send_blocks_and_test([block], node, success=True) self.log.info("Mature the block.") - self.nodes[0].generate(100) + self.nodes[0].generatetoaddress(100, self.nodes[0].get_deterministic_priv_key().address) # b'\x64' is OP_NOTIF # Transaction will be rejected with code 16 (REJECT_INVALID) diff --git a/test/functional/p2p_leak.py b/test/functional/p2p_leak.py index 05354d17e1..336d34a81d 100755 --- a/test/functional/p2p_leak.py +++ b/test/functional/p2p_leak.py @@ -93,9 +93,6 @@ class P2PLeakTest(BitcoinTestFramework): self.num_nodes = 1 self.extra_args = [['-banscore=' + str(banscore)]] - def skip_test_if_missing_module(self): - self.skip_if_no_wallet() - def run_test(self): no_version_bannode = self.nodes[0].add_p2p_connection(CNodeNoVersionBan(), send_version=False, wait_for_verack=False) no_version_idlenode = self.nodes[0].add_p2p_connection(CNodeNoVersionIdle(), send_version=False, wait_for_verack=False) @@ -106,7 +103,7 @@ class P2PLeakTest(BitcoinTestFramework): wait_until(lambda: no_verack_idlenode.version_received, timeout=10, lock=mininode_lock) # Mine a block and make sure that it's not sent to the connected nodes - self.nodes[0].generate(1) + self.nodes[0].generatetoaddress(1, self.nodes[0].get_deterministic_priv_key().address) #Give the node enough time to possibly leak out a message time.sleep(5) diff --git a/test/functional/p2p_node_network_limited.py b/test/functional/p2p_node_network_limited.py index a16c6a1d47..ec3d336dc1 100755 --- a/test/functional/p2p_node_network_limited.py +++ b/test/functional/p2p_node_network_limited.py @@ -34,9 +34,6 @@ class NodeNetworkLimitedTest(BitcoinTestFramework): self.num_nodes = 3 self.extra_args = [['-prune=550', '-addrmantest'], [], []] - def skip_test_if_missing_module(self): - self.skip_if_no_wallet() - def disconnect_all(self): disconnect_nodes(self.nodes[0], 1) disconnect_nodes(self.nodes[1], 0) @@ -62,7 +59,7 @@ class NodeNetworkLimitedTest(BitcoinTestFramework): self.log.info("Mine enough blocks to reach the NODE_NETWORK_LIMITED range.") connect_nodes_bi(self.nodes, 0, 1) - blocks = self.nodes[1].generate(292) + blocks = self.nodes[1].generatetoaddress(292, self.nodes[1].get_deterministic_priv_key().address) sync_blocks([self.nodes[0], self.nodes[1]]) self.log.info("Make sure we can max retrieve block at tip-288.") @@ -105,7 +102,7 @@ class NodeNetworkLimitedTest(BitcoinTestFramework): self.disconnect_all() # mine 10 blocks on node 0 (pruned node) - self.nodes[0].generate(10) + self.nodes[0].generatetoaddress(10, self.nodes[0].get_deterministic_priv_key().address) # connect node1 (non pruned) with node0 (pruned) and check if the can sync connect_nodes_bi(self.nodes, 0, 1) diff --git a/test/functional/p2p_sendheaders.py b/test/functional/p2p_sendheaders.py index 9a782c0bb9..d5e8dd4721 100755 --- a/test/functional/p2p_sendheaders.py +++ b/test/functional/p2p_sendheaders.py @@ -208,15 +208,12 @@ class SendHeadersTest(BitcoinTestFramework): self.setup_clean_chain = True self.num_nodes = 2 - def skip_test_if_missing_module(self): - self.skip_if_no_wallet() - def mine_blocks(self, count): """Mine count blocks and return the new tip.""" # Clear out block announcements from each p2p listener [x.clear_block_announcements() for x in self.nodes[0].p2ps] - self.nodes[0].generate(count) + self.nodes[0].generatetoaddress(count, self.nodes[0].get_deterministic_priv_key().address) return int(self.nodes[0].getbestblockhash(), 16) def mine_reorg(self, length): @@ -226,7 +223,8 @@ class SendHeadersTest(BitcoinTestFramework): to-be-reorged-out blocks are mined, so that we don't break later tests. return the list of block hashes newly mined.""" - self.nodes[0].generate(length) # make sure all invalidated blocks are node0's + # make sure all invalidated blocks are node0's + self.nodes[0].generatetoaddress(length, self.nodes[0].get_deterministic_priv_key().address) sync_blocks(self.nodes, wait=0.1) for x in self.nodes[0].p2ps: x.wait_for_block_announcement(int(self.nodes[0].getbestblockhash(), 16)) @@ -235,7 +233,7 @@ class SendHeadersTest(BitcoinTestFramework): tip_height = self.nodes[1].getblockcount() hash_to_invalidate = self.nodes[1].getblockhash(tip_height - (length - 1)) self.nodes[1].invalidateblock(hash_to_invalidate) - all_hashes = self.nodes[1].generate(length + 1) # Must be longer than the orig chain + all_hashes = self.nodes[1].generatetoaddress(length + 1, self.nodes[1].get_deterministic_priv_key().address) # Must be longer than the orig chain sync_blocks(self.nodes, wait=0.1) return [int(x, 16) for x in all_hashes] @@ -254,7 +252,7 @@ class SendHeadersTest(BitcoinTestFramework): self.test_nonnull_locators(test_node, inv_node) def test_null_locators(self, test_node, inv_node): - tip = self.nodes[0].getblockheader(self.nodes[0].generate(1)[0]) + tip = self.nodes[0].getblockheader(self.nodes[0].generatetoaddress(1, self.nodes[0].get_deterministic_priv_key().address)[0]) tip_hash = int(tip["hash"], 16) inv_node.check_last_inv_announcement(inv=[tip_hash]) diff --git a/test/functional/p2p_unrequested_blocks.py b/test/functional/p2p_unrequested_blocks.py index 232274f59e..11299cbc00 100755 --- a/test/functional/p2p_unrequested_blocks.py +++ b/test/functional/p2p_unrequested_blocks.py @@ -66,9 +66,6 @@ class AcceptBlockTest(BitcoinTestFramework): self.num_nodes = 2 self.extra_args = [[], ["-minimumchainwork=0x10"]] - def skip_test_if_missing_module(self): - self.skip_if_no_wallet() - def setup_network(self): # Node0 will be used to test behavior of processing unrequested blocks # from peers which are not whitelisted, while Node1 will be used for @@ -85,8 +82,8 @@ class AcceptBlockTest(BitcoinTestFramework): min_work_node = self.nodes[1].add_p2p_connection(P2PInterface()) # 1. Have nodes mine a block (leave IBD) - [ n.generate(1) for n in self.nodes ] - tips = [ int("0x" + n.getbestblockhash(), 0) for n in self.nodes ] + [n.generatetoaddress(1, n.get_deterministic_priv_key().address) for n in self.nodes] + tips = [int("0x" + n.getbestblockhash(), 0) for n in self.nodes] # 2. Send one block that builds on each tip. # This should be accepted by node0 diff --git a/test/functional/rpc_blockchain.py b/test/functional/rpc_blockchain.py index 00317a2c08..f67ecc247c 100755 --- a/test/functional/rpc_blockchain.py +++ b/test/functional/rpc_blockchain.py @@ -48,9 +48,6 @@ class BlockchainTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 - def skip_test_if_missing_module(self): - self.skip_if_no_wallet() - def run_test(self): self.restart_node(0, extra_args=['-stopatheight=207', '-prune=1']) # Set extra args with pruning after rescan is complete @@ -242,12 +239,12 @@ class BlockchainTest(BitcoinTestFramework): def _test_stopatheight(self): assert_equal(self.nodes[0].getblockcount(), 200) - self.nodes[0].generate(6) + self.nodes[0].generatetoaddress(6, self.nodes[0].get_deterministic_priv_key().address) assert_equal(self.nodes[0].getblockcount(), 206) self.log.debug('Node should not stop at this height') assert_raises(subprocess.TimeoutExpired, lambda: self.nodes[0].process.wait(timeout=3)) try: - self.nodes[0].generate(1) + self.nodes[0].generatetoaddress(1, self.nodes[0].get_deterministic_priv_key().address) except (ConnectionError, http.client.BadStatusLine): pass # The node already shut down before response self.log.debug('Node should stop at this height...') diff --git a/test/functional/rpc_fundrawtransaction.py b/test/functional/rpc_fundrawtransaction.py index daa890ab15..0c61e9ab62 100755 --- a/test/functional/rpc_fundrawtransaction.py +++ b/test/functional/rpc_fundrawtransaction.py @@ -478,10 +478,8 @@ class RawTransactionsTest(BitcoinTestFramework): ############################################################ # locked wallet test - self.stop_node(0) - self.nodes[1].node_encrypt_wallet("test") - self.stop_node(2) - self.stop_node(3) + self.nodes[1].encryptwallet("test") + self.stop_nodes() self.start_nodes() # This test is not meant to test fee estimation and we'd like diff --git a/test/functional/rpc_getchaintips.py b/test/functional/rpc_getchaintips.py index bc19c60dde..c869c7262f 100755 --- a/test/functional/rpc_getchaintips.py +++ b/test/functional/rpc_getchaintips.py @@ -17,9 +17,6 @@ class GetChainTipsTest (BitcoinTestFramework): def set_test_params(self): self.num_nodes = 4 - def skip_test_if_missing_module(self): - self.skip_if_no_wallet() - def run_test(self): tips = self.nodes[0].getchaintips() assert_equal(len(tips), 1) @@ -29,8 +26,8 @@ class GetChainTipsTest (BitcoinTestFramework): # Split the network and build two chains of different lengths. self.split_network() - self.nodes[0].generate(10) - self.nodes[2].generate(20) + self.nodes[0].generatetoaddress(10, self.nodes[0].get_deterministic_priv_key().address) + self.nodes[2].generatetoaddress(20, self.nodes[2].get_deterministic_priv_key().address) self.sync_all([self.nodes[:2], self.nodes[2:]]) tips = self.nodes[1].getchaintips () diff --git a/test/functional/rpc_invalidateblock.py b/test/functional/rpc_invalidateblock.py index 84f7cd05fb..d8ecdd573a 100755 --- a/test/functional/rpc_invalidateblock.py +++ b/test/functional/rpc_invalidateblock.py @@ -14,21 +14,18 @@ class InvalidateTest(BitcoinTestFramework): self.setup_clean_chain = True self.num_nodes = 3 - def skip_test_if_missing_module(self): - self.skip_if_no_wallet() - def setup_network(self): self.setup_nodes() def run_test(self): self.log.info("Make sure we repopulate setBlockIndexCandidates after InvalidateBlock:") self.log.info("Mine 4 blocks on Node 0") - self.nodes[0].generate(4) + self.nodes[0].generatetoaddress(4, self.nodes[0].get_deterministic_priv_key().address) assert(self.nodes[0].getblockcount() == 4) besthash = self.nodes[0].getbestblockhash() self.log.info("Mine competing 6 blocks on Node 1") - self.nodes[1].generate(6) + self.nodes[1].generatetoaddress(6, self.nodes[1].get_deterministic_priv_key().address) assert(self.nodes[1].getblockcount() == 6) self.log.info("Connect nodes to force a reorg") @@ -56,7 +53,7 @@ class InvalidateTest(BitcoinTestFramework): self.nodes[2].invalidateblock(self.nodes[2].getblockhash(3)) assert(self.nodes[2].getblockcount() == 2) self.log.info("..and then mine a block") - self.nodes[2].generate(1) + self.nodes[2].generatetoaddress(1, self.nodes[2].get_deterministic_priv_key().address) self.log.info("Verify all nodes are at the right height") time.sleep(5) assert_equal(self.nodes[2].getblockcount(), 3) diff --git a/test/functional/rpc_net.py b/test/functional/rpc_net.py index a46518200c..1e525214fa 100755 --- a/test/functional/rpc_net.py +++ b/test/functional/rpc_net.py @@ -13,11 +13,14 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, assert_greater_than_or_equal, + assert_greater_than, assert_raises_rpc_error, connect_nodes_bi, p2p_port, wait_until, ) +from test_framework.mininode import P2PInterface +from test_framework.messages import CAddress, msg_addr, NODE_NETWORK, NODE_WITNESS class NetTest(BitcoinTestFramework): def set_test_params(self): @@ -31,6 +34,7 @@ class NetTest(BitcoinTestFramework): self._test_getnetworkinginfo() self._test_getaddednodeinfo() self._test_getpeerinfo() + self._test_getnodeaddresses() def _test_connection_count(self): # connect_nodes_bi connects each node to the other @@ -101,5 +105,40 @@ class NetTest(BitcoinTestFramework): assert_equal(peer_info[0][0]['minfeefilter'], Decimal("0.00000500")) assert_equal(peer_info[1][0]['minfeefilter'], Decimal("0.00001000")) + def _test_getnodeaddresses(self): + self.nodes[0].add_p2p_connection(P2PInterface()) + + # send some addresses to the node via the p2p message addr + msg = msg_addr() + imported_addrs = [] + for i in range(256): + a = "123.123.123.{}".format(i) + imported_addrs.append(a) + addr = CAddress() + addr.time = 100000000 + addr.nServices = NODE_NETWORK | NODE_WITNESS + addr.ip = a + addr.port = 8333 + msg.addrs.append(addr) + self.nodes[0].p2p.send_and_ping(msg) + + # obtain addresses via rpc call and check they were ones sent in before + REQUEST_COUNT = 10 + node_addresses = self.nodes[0].getnodeaddresses(REQUEST_COUNT) + assert_equal(len(node_addresses), REQUEST_COUNT) + for a in node_addresses: + assert_greater_than(a["time"], 1527811200) # 1st June 2018 + assert_equal(a["services"], NODE_NETWORK | NODE_WITNESS) + assert a["address"] in imported_addrs + assert_equal(a["port"], 8333) + + assert_raises_rpc_error(-8, "Address count out of range", self.nodes[0].getnodeaddresses, -1) + + # addrman's size cannot be known reliably after insertion, as hash collisions may occur + # so only test that requesting a large number of addresses returns less than that + LARGE_REQUEST_COUNT = 10000 + node_addresses = self.nodes[0].getnodeaddresses(LARGE_REQUEST_COUNT) + assert_greater_than(LARGE_REQUEST_COUNT, len(node_addresses)) + if __name__ == '__main__': NetTest().main() diff --git a/test/functional/rpc_preciousblock.py b/test/functional/rpc_preciousblock.py index f383b82bb5..72e6e6329f 100755 --- a/test/functional/rpc_preciousblock.py +++ b/test/functional/rpc_preciousblock.py @@ -38,26 +38,24 @@ class PreciousTest(BitcoinTestFramework): self.setup_clean_chain = True self.num_nodes = 3 - def skip_test_if_missing_module(self): - self.skip_if_no_wallet() - def setup_network(self): self.setup_nodes() def run_test(self): self.log.info("Ensure submitblock can in principle reorg to a competing chain") - self.nodes[0].generate(1) + gen_address = lambda i: self.nodes[i].get_deterministic_priv_key().address # A non-wallet address to mine to + self.nodes[0].generatetoaddress(1, gen_address(0)) assert_equal(self.nodes[0].getblockcount(), 1) - hashZ = self.nodes[1].generate(2)[-1] + hashZ = self.nodes[1].generatetoaddress(2, gen_address(1))[-1] assert_equal(self.nodes[1].getblockcount(), 2) node_sync_via_rpc(self.nodes[0:3]) assert_equal(self.nodes[0].getbestblockhash(), hashZ) self.log.info("Mine blocks A-B-C on Node 0") - hashC = self.nodes[0].generate(3)[-1] + hashC = self.nodes[0].generatetoaddress(3, gen_address(0))[-1] assert_equal(self.nodes[0].getblockcount(), 5) self.log.info("Mine competing blocks E-F-G on Node 1") - hashG = self.nodes[1].generate(3)[-1] + hashG = self.nodes[1].generatetoaddress(3, gen_address(1))[-1] assert_equal(self.nodes[1].getblockcount(), 5) assert(hashC != hashG) self.log.info("Connect nodes and check no reorg occurs") @@ -86,7 +84,7 @@ class PreciousTest(BitcoinTestFramework): self.nodes[1].preciousblock(hashC) assert_equal(self.nodes[1].getbestblockhash(), hashC) self.log.info("Mine another block (E-F-G-)H on Node 0 and reorg Node 1") - self.nodes[0].generate(1) + self.nodes[0].generatetoaddress(1, gen_address(0)) assert_equal(self.nodes[0].getblockcount(), 6) sync_blocks(self.nodes[0:2]) hashH = self.nodes[0].getbestblockhash() @@ -95,7 +93,7 @@ class PreciousTest(BitcoinTestFramework): self.nodes[1].preciousblock(hashC) assert_equal(self.nodes[1].getbestblockhash(), hashH) self.log.info("Mine competing blocks I-J-K-L on Node 2") - self.nodes[2].generate(4) + self.nodes[2].generatetoaddress(4, gen_address(2)) assert_equal(self.nodes[2].getblockcount(), 6) hashL = self.nodes[2].getbestblockhash() self.log.info("Connect nodes and check no reorg occurs") diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py index 57c985b2a2..9a589240a8 100755 --- a/test/functional/test_framework/test_framework.py +++ b/test/functional/test_framework/test_framework.py @@ -271,7 +271,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass): assert str(e).startswith('Method not found') continue - n.importprivkey(n.get_deterministic_priv_key()[1]) + n.importprivkey(n.get_deterministic_priv_key().key) def run_test(self): """Tests must override this method to define test logic""" @@ -465,7 +465,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass): for peer in range(4): for j in range(25): set_node_times(self.nodes, block_time) - self.nodes[peer].generatetoaddress(1, self.nodes[peer].get_deterministic_priv_key()[0]) + self.nodes[peer].generatetoaddress(1, self.nodes[peer].get_deterministic_priv_key().address) block_time += 10 * 60 # Must sync before next peer starts generating blocks sync_blocks(self.nodes) diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py index 908dda94c5..7ab7fcfcb4 100755 --- a/test/functional/test_framework/test_node.py +++ b/test/functional/test_framework/test_node.py @@ -17,6 +17,7 @@ import subprocess import tempfile import time import urllib.parse +import collections from .authproxy import JSONRPCException from .util import ( @@ -99,17 +100,18 @@ class TestNode(): def get_deterministic_priv_key(self): """Return a deterministic priv key in base58, that only depends on the node's index""" + AddressKeyPair = collections.namedtuple('AddressKeyPair', ['address', 'key']) PRIV_KEYS = [ - # adress , privkey - ('mjTkW3DjgyZck4KbiRusZsqTgaYTxdSz6z', 'cVpF924EspNh8KjYsfhgY96mmxvT6DgdWiTYMtMjuM74hJaU5psW'), - ('msX6jQXvxiNhx3Q62PKeLPrhrqZQdSimTg', 'cUxsWyKyZ9MAQTaAhUQWJmBbSvHMwSmuv59KgxQV7oZQU3PXN3KE'), - ('mnonCMyH9TmAsSj3M59DsbH8H63U3RKoFP', 'cTrh7dkEAeJd6b3MRX9bZK8eRmNqVCMH3LSUkE3dSFDyzjU38QxK'), - ('mqJupas8Dt2uestQDvV2NH3RU8uZh2dqQR', 'cVuKKa7gbehEQvVq717hYcbE9Dqmq7KEBKqWgWrYBa2CKKrhtRim'), - ('msYac7Rvd5ywm6pEmkjyxhbCDKqWsVeYws', 'cQDCBuKcjanpXDpCqacNSjYfxeQj8G6CAtH1Dsk3cXyqLNC4RPuh'), - ('n2rnuUnwLgXqf9kk2kjvVm8R5BZK1yxQBi', 'cQakmfPSLSqKHyMFGwAqKHgWUiofJCagVGhiB4KCainaeCSxeyYq'), - ('myzuPxRwsf3vvGzEuzPfK9Nf2RfwauwYe6', 'cQMpDLJwA8DBe9NcQbdoSb1BhmFxVjWD5gRyrLZCtpuF9Zi3a9RK'), - ('mumwTaMtbxEPUswmLBBN3vM9oGRtGBrys8', 'cSXmRKXVcoouhNNVpcNKFfxsTsToY5pvB9DVsFksF1ENunTzRKsy'), - ('mpV7aGShMkJCZgbW7F6iZgrvuPHjZjH9qg', 'cSoXt6tm3pqy43UMabY6eUTmR3eSUYFtB2iNQDGgb3VUnRsQys2k'), + # address , privkey + AddressKeyPair('mjTkW3DjgyZck4KbiRusZsqTgaYTxdSz6z', 'cVpF924EspNh8KjYsfhgY96mmxvT6DgdWiTYMtMjuM74hJaU5psW'), + AddressKeyPair('msX6jQXvxiNhx3Q62PKeLPrhrqZQdSimTg', 'cUxsWyKyZ9MAQTaAhUQWJmBbSvHMwSmuv59KgxQV7oZQU3PXN3KE'), + AddressKeyPair('mnonCMyH9TmAsSj3M59DsbH8H63U3RKoFP', 'cTrh7dkEAeJd6b3MRX9bZK8eRmNqVCMH3LSUkE3dSFDyzjU38QxK'), + AddressKeyPair('mqJupas8Dt2uestQDvV2NH3RU8uZh2dqQR', 'cVuKKa7gbehEQvVq717hYcbE9Dqmq7KEBKqWgWrYBa2CKKrhtRim'), + AddressKeyPair('msYac7Rvd5ywm6pEmkjyxhbCDKqWsVeYws', 'cQDCBuKcjanpXDpCqacNSjYfxeQj8G6CAtH1Dsk3cXyqLNC4RPuh'), + AddressKeyPair('n2rnuUnwLgXqf9kk2kjvVm8R5BZK1yxQBi', 'cQakmfPSLSqKHyMFGwAqKHgWUiofJCagVGhiB4KCainaeCSxeyYq'), + AddressKeyPair('myzuPxRwsf3vvGzEuzPfK9Nf2RfwauwYe6', 'cQMpDLJwA8DBe9NcQbdoSb1BhmFxVjWD5gRyrLZCtpuF9Zi3a9RK'), + AddressKeyPair('mumwTaMtbxEPUswmLBBN3vM9oGRtGBrys8', 'cSXmRKXVcoouhNNVpcNKFfxsTsToY5pvB9DVsFksF1ENunTzRKsy'), + AddressKeyPair('mpV7aGShMkJCZgbW7F6iZgrvuPHjZjH9qg', 'cSoXt6tm3pqy43UMabY6eUTmR3eSUYFtB2iNQDGgb3VUnRsQys2k'), ] return PRIV_KEYS[self.index] @@ -305,14 +307,6 @@ class TestNode(): assert_msg = "bitcoind should have exited with expected error " + expected_msg self._raise_assertion_error(assert_msg) - def node_encrypt_wallet(self, passphrase): - """"Encrypts the wallet. - - This causes bitcoind to shutdown, so this method takes - care of cleaning up resources.""" - self.encryptwallet(passphrase) - self.wait_until_stopped() - def add_p2p_connection(self, p2p_conn, *, wait_for_verack=True, **kwargs): """Add a p2p connection to the node. diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index 37b378e9ca..37a3c1c602 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -58,9 +58,12 @@ TRAVIS_TIMEOUT_DURATION = 20 * 60 BASE_SCRIPTS = [ # Scripts that are run by the travis build process. # Longest test should go first, to favor running tests in parallel + 'feature_fee_estimation.py', 'wallet_hd.py', 'wallet_backup.py', # vv Tests less than 5m vv + 'mining_getblocktemplate_longpoll.py', + 'feature_maxuploadtarget.py', 'feature_block.py', 'rpc_fundrawtransaction.py', 'p2p_compactblocks.py', @@ -69,6 +72,7 @@ BASE_SCRIPTS = [ 'wallet_basic.py', 'wallet_labels.py', 'p2p_segwit.py', + 'p2p_timeouts.py', 'wallet_dump.py', 'wallet_listtransactions.py', # vv Tests less than 60s vv @@ -82,6 +86,8 @@ BASE_SCRIPTS = [ 'feature_csv_activation.py', 'rpc_rawtransaction.py', 'wallet_address_types.py', + 'feature_bip68_sequence.py', + 'p2p_feefilter.py', 'feature_reindex.py', # vv Tests less than 30s vv 'wallet_keypool_topup.py', @@ -118,6 +124,14 @@ BASE_SCRIPTS = [ 'p2p_invalid_locator.py', 'p2p_invalid_block.py', 'p2p_invalid_tx.py', + 'feature_assumevalid.py', + 'example_test.py', + 'wallet_txn_doublespend.py', + 'wallet_txn_clone.py --mineblock', + 'feature_notifications.py', + 'rpc_invalidateblock.py', + 'feature_rbf.py', + 'mempool_packages.py', 'rpc_createmultisig.py', 'feature_versionbits_warning.py', 'rpc_preciousblock.py', @@ -162,26 +176,7 @@ EXTENDED_SCRIPTS = [ # These tests are not run by the travis build process. # Longest test should go first, to favor running tests in parallel 'feature_pruning.py', - # vv Tests less than 20m vv - 'feature_fee_estimation.py', - # vv Tests less than 5m vv - 'feature_maxuploadtarget.py', - 'mempool_packages.py', 'feature_dbcrash.py', - # vv Tests less than 2m vv - 'feature_bip68_sequence.py', - 'mining_getblocktemplate_longpoll.py', - 'p2p_timeouts.py', - # vv Tests less than 60s vv - 'p2p_feefilter.py', - # vv Tests less than 30s vv - 'feature_assumevalid.py', - 'example_test.py', - 'wallet_txn_doublespend.py', - 'wallet_txn_clone.py --mineblock', - 'feature_notifications.py', - 'rpc_invalidateblock.py', - 'feature_rbf.py', ] # Place EXTENDED_SCRIPTS first since it has the 3 longest running tests diff --git a/test/functional/wallet_bumpfee.py b/test/functional/wallet_bumpfee.py index 2ea72896bb..67ee00871d 100755 --- a/test/functional/wallet_bumpfee.py +++ b/test/functional/wallet_bumpfee.py @@ -42,8 +42,7 @@ class BumpFeeTest(BitcoinTestFramework): def run_test(self): # Encrypt wallet for test_locked_wallet_fails test - self.nodes[1].node_encrypt_wallet(WALLET_PASSPHRASE) - self.start_node(1) + self.nodes[1].encryptwallet(WALLET_PASSPHRASE) self.nodes[1].walletpassphrase(WALLET_PASSPHRASE, WALLET_PASSPHRASE_TIMEOUT) connect_nodes_bi(self.nodes, 0, 1) diff --git a/test/functional/wallet_dump.py b/test/functional/wallet_dump.py index db731b2a34..b1db1e4ab9 100755 --- a/test/functional/wallet_dump.py +++ b/test/functional/wallet_dump.py @@ -34,7 +34,11 @@ def read_dump(file_name, addrs, script_addrs, hd_master_addr_old): # key = key_date_label[0] date = key_date_label[1] keytype = key_date_label[2] - if not len(comment) or date.startswith('1970'): + + imported_key = date == '1970-01-01T00:00:01Z' + if imported_key: + # Imported keys have multiple addresses, no label (keypath) and timestamp + # Skip them continue addr_keypath = comment.split(" addr=")[1] @@ -128,8 +132,7 @@ class WalletDumpTest(BitcoinTestFramework): assert_equal(witness_addr_ret, witness_addr) # p2sh-p2wsh address added to the first key #encrypt wallet, restart, unlock and dump - self.nodes[0].node_encrypt_wallet('test') - self.start_node(0) + self.nodes[0].encryptwallet('test') self.nodes[0].walletpassphrase('test', 10) # Should be a no-op: self.nodes[0].keypoolrefill() diff --git a/test/functional/wallet_encryption.py b/test/functional/wallet_encryption.py index d8c27b09d9..ab9ebed8d4 100755 --- a/test/functional/wallet_encryption.py +++ b/test/functional/wallet_encryption.py @@ -33,8 +33,7 @@ class WalletEncryptionTest(BitcoinTestFramework): assert_equal(len(privkey), 52) # Encrypt the wallet - self.nodes[0].node_encrypt_wallet(passphrase) - self.start_node(0) + self.nodes[0].encryptwallet(passphrase) # Test that the wallet is encrypted assert_raises_rpc_error(-13, "Please enter the wallet passphrase with walletpassphrase first", self.nodes[0].dumpprivkey, address) diff --git a/test/functional/wallet_import_rescan.py b/test/functional/wallet_import_rescan.py index fab415987e..f043a544fc 100755 --- a/test/functional/wallet_import_rescan.py +++ b/test/functional/wallet_import_rescan.py @@ -120,7 +120,7 @@ class ImportRescanTest(BitcoinTestFramework): self.add_nodes(self.num_nodes, extra_args=extra_args) - # Import keys + # Import keys with pruning disabled self.start_nodes(extra_args=[[]] * self.num_nodes) super().import_deterministic_coinbase_privkeys() self.stop_nodes() diff --git a/test/functional/wallet_keypool.py b/test/functional/wallet_keypool.py index acc336e4d5..51afa0cb1a 100755 --- a/test/functional/wallet_keypool.py +++ b/test/functional/wallet_keypool.py @@ -25,9 +25,7 @@ class KeyPoolTest(BitcoinTestFramework): assert(addr_before_encrypting_data['hdseedid'] == wallet_info_old['hdseedid']) # Encrypt wallet and wait to terminate - nodes[0].node_encrypt_wallet('test') - # Restart node 0 - self.start_node(0) + nodes[0].encryptwallet('test') # Keep creating keys addr = nodes[0].getnewaddress() addr_data = nodes[0].getaddressinfo(addr) diff --git a/test/lint/check-doc.py b/test/lint/check-doc.py index 0c4a603167..7b056dab32 100755 --- a/test/lint/check-doc.py +++ b/test/lint/check-doc.py @@ -22,7 +22,7 @@ CMD_ROOT_DIR = '`git rev-parse --show-toplevel`/{}'.format(FOLDER_GREP) CMD_GREP_ARGS = r"git grep --perl-regexp '{}' -- {} ':(exclude){}'".format(REGEX_ARG, CMD_ROOT_DIR, FOLDER_TEST) CMD_GREP_DOCS = r"git grep --perl-regexp '{}' {}".format(REGEX_DOC, CMD_ROOT_DIR) # list unsupported, deprecated and duplicate args as they need no documentation -SET_DOC_OPTIONAL = set(['-rpcssl', '-benchmark', '-h', '-help', '-socks', '-tor', '-debugnet', '-whitelistalwaysrelay', '-promiscuousmempoolflags', '-blockminsize', '-dbcrashratio', '-forcecompactdb', '-usehd']) +SET_DOC_OPTIONAL = set(['-h', '-help', '-dbcrashratio', '-forcecompactdb', '-usehd']) def main(): diff --git a/test/lint/lint-spelling.sh b/test/lint/lint-spelling.sh index 5d672698a7..ebeafd7d58 100755 --- a/test/lint/lint-spelling.sh +++ b/test/lint/lint-spelling.sh @@ -9,7 +9,10 @@ export LC_ALL=C +EXIT_CODE=0 IGNORE_WORDS_FILE=test/lint/lint-spelling.ignore-words.txt if ! codespell --check-filenames --disable-colors --quiet-level=7 --ignore-words=${IGNORE_WORDS_FILE} $(git ls-files -- ":(exclude)build-aux/m4/" ":(exclude)contrib/seeds/*.txt" ":(exclude)depends/" ":(exclude)doc/release-notes/" ":(exclude)src/leveldb/" ":(exclude)src/qt/locale/" ":(exclude)src/secp256k1/" ":(exclude)src/univalue/"); then echo "^ Warning: codespell identified likely spelling errors. Any false positives? Add them to the list of ignored words in ${IGNORE_WORDS_FILE}" + EXIT_CODE=1 fi +exit ${EXIT_CODE} |