diff --git a/configure.ac b/configure.ac index a440c33732..8115ca67b3 100644 --- a/configure.ac +++ b/configure.ac @@ -307,13 +307,6 @@ AC_ARG_ENABLE([gprof], [enable_gprof=$enableval], [enable_gprof=no]) -dnl Pass compiler & linker flags that make builds deterministic -AC_ARG_ENABLE([determinism], - [AS_HELP_STRING([--enable-determinism], - [Enable compilation flags that make builds deterministic (default is no)])], - [enable_determinism=$enableval], - [enable_determinism=no]) - dnl Turn warnings into errors AC_ARG_ENABLE([werror], [AS_HELP_STRING([--enable-werror], @@ -482,7 +475,9 @@ if test "x$CXXFLAGS_overridden" = "xno"; then AX_CHECK_COMPILE_FLAG([-Wself-assign],[NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-self-assign"],,[[$CXXFLAG_WERROR]]) AX_CHECK_COMPILE_FLAG([-Wunused-local-typedef],[NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-unused-local-typedef"],,[[$CXXFLAG_WERROR]]) AX_CHECK_COMPILE_FLAG([-Wimplicit-fallthrough],[NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-implicit-fallthrough"],,[[$CXXFLAG_WERROR]]) - AX_CHECK_COMPILE_FLAG([-Wdeprecated-copy],[NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-deprecated-copy"],,[[$CXXFLAG_WERROR]]) + if test x$suppress_external_warnings != xyes ; then + AX_CHECK_COMPILE_FLAG([-Wdeprecated-copy],[NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-deprecated-copy"],,[[$CXXFLAG_WERROR]]) + fi fi dnl Don't allow extended (non-ASCII) symbols in identifiers. This is easier for code review. @@ -964,12 +959,6 @@ if test x$TARGET_OS = xdarwin; then AX_CHECK_LINK_FLAG([[-Wl,-bind_at_load]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,-bind_at_load"],, [[$LDFLAG_WERROR]]) fi -if test x$enable_determinism = xyes; then - if test x$TARGET_OS = xwindows; then - AX_CHECK_LINK_FLAG([[-Wl,--no-insert-timestamp]], [LDFLAGS="$LDFLAGS -Wl,--no-insert-timestamp"],, [[$LDFLAG_WERROR]]) - fi -fi - AC_CHECK_HEADERS([endian.h sys/endian.h byteswap.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h sys/sysctl.h vm/vm_param.h sys/vmmeter.h sys/resources.h]) AC_CHECK_DECLS([getifaddrs, freeifaddrs],[CHECK_SOCKET],, @@ -981,6 +970,8 @@ AC_CHECK_DECLS([strnlen]) dnl Check for daemon(3), unrelated to --with-daemon (although used by it) AC_CHECK_DECLS([daemon]) +AC_CHECK_DECLS([pipe2]) + AC_CHECK_DECLS([le16toh, le32toh, le64toh, htole16, htole32, htole64, be16toh, be32toh, be64toh, htobe16, htobe32, htobe64],,, [#if HAVE_ENDIAN_H #include @@ -1185,6 +1176,7 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [ AC_MSG_RESULT(yes); HAVE_O_CLOEXEC=1 ], [ AC_MSG_RESULT(no); HAVE_O_CLOEXEC=0 ] ) +AC_DEFINE_UNQUOTED([HAVE_O_CLOEXEC], [$HAVE_O_CLOEXEC], [Define to 1 if O_CLOEXEC flag is available.]) dnl crc32c platform checks AC_MSG_CHECKING(for __builtin_prefetch) @@ -1348,13 +1340,15 @@ if test x$enable_wallet != xno; then fi if test x$use_ebpf != xno; then - AC_CHECK_HEADER([sys/sdt.h], [have_sdt=yes], [have_sdt=no]) -else - have_sdt=no -fi - -if test x$have_sdt = xyes; then - AC_DEFINE([ENABLE_TRACING], [1], [Define to 1 to enable eBPF user static defined tracepoints]) + AC_MSG_CHECKING([whether eBPF tracepoints are supported]) + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM( + [#include ], + [DTRACE_PROBE("context", "event");] + )], + [AC_MSG_RESULT(yes); have_sdt=yes; AC_DEFINE([ENABLE_TRACING], [1], [Define to 1 to enable eBPF user static defined tracepoints])], + [AC_MSG_RESULT(no); have_sdt=no;] + ) fi dnl Check for libminiupnpc (optional) diff --git a/depends/packages/native_mac_alias.mk b/depends/packages/native_mac_alias.mk index 5fe027fb8a..783f87ca7c 100644 --- a/depends/packages/native_mac_alias.mk +++ b/depends/packages/native_mac_alias.mk @@ -1,8 +1,8 @@ package=native_mac_alias -$(package)_version=2.1.1 +$(package)_version=2.2.0 $(package)_download_path=https://github.com/al45tair/mac_alias/archive/ $(package)_file_name=v$($(package)_version).tar.gz -$(package)_sha256_hash=c0ffceee14f7d04a6eb323fb7b8217dc3f373b346198d2ca42300a8362db7efa +$(package)_sha256_hash=421e6d7586d1f155c7db3e7da01ca0dacc9649a509a253ad7077b70174426499 $(package)_install_libdir=$(build_prefix)/lib/python3/dist-packages define $(package)_build_cmds diff --git a/src/coins.cpp b/src/coins.cpp index c67bc7d5ed..b81cf409ff 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -13,7 +13,7 @@ bool CCoinsView::GetCoin(const COutPoint &outpoint, Coin &coin) const { return f uint256 CCoinsView::GetBestBlock() const { return uint256(); } std::vector CCoinsView::GetHeadBlocks() const { return std::vector(); } bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return false; } -CCoinsViewCursor *CCoinsView::Cursor() const { return nullptr; } +std::unique_ptr CCoinsView::Cursor() const { return nullptr; } bool CCoinsView::HaveCoin(const COutPoint &outpoint) const { @@ -28,7 +28,7 @@ uint256 CCoinsViewBacked::GetBestBlock() const { return base->GetBestBlock(); } std::vector CCoinsViewBacked::GetHeadBlocks() const { return base->GetHeadBlocks(); } void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; } bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); } -CCoinsViewCursor *CCoinsViewBacked::Cursor() const { return base->Cursor(); } +std::unique_ptr CCoinsViewBacked::Cursor() const { return base->Cursor(); } size_t CCoinsViewBacked::EstimateSize() const { return base->EstimateSize(); } CCoinsViewCache::CCoinsViewCache(CCoinsView *baseIn) : CCoinsViewBacked(baseIn), cachedCoinsUsage(0) {} diff --git a/src/coins.h b/src/coins.h index 816b4864a3..3151a260d9 100644 --- a/src/coins.h +++ b/src/coins.h @@ -180,7 +180,7 @@ public: virtual bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock); //! Get a cursor to iterate over the whole state - virtual CCoinsViewCursor *Cursor() const; + virtual std::unique_ptr Cursor() const; //! As we use CCoinsViews polymorphically, have a virtual destructor virtual ~CCoinsView() {} @@ -204,7 +204,7 @@ public: std::vector GetHeadBlocks() const override; void SetBackend(CCoinsView &viewIn); bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) override; - CCoinsViewCursor *Cursor() const override; + std::unique_ptr Cursor() const override; size_t EstimateSize() const override; }; @@ -237,7 +237,7 @@ public: uint256 GetBestBlock() const override; void SetBestBlock(const uint256 &hashBlock); bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) override; - CCoinsViewCursor* Cursor() const override { + std::unique_ptr Cursor() const override { throw std::logic_error("CCoinsViewCache cursor iteration not supported."); } diff --git a/src/flatfile.cpp b/src/flatfile.cpp index 11cf357f3d..151f1a38f1 100644 --- a/src/flatfile.cpp +++ b/src/flatfile.cpp @@ -66,7 +66,7 @@ size_t FlatFileSeq::Allocate(const FlatFilePos& pos, size_t add_size, bool& out_ if (CheckDiskSpace(m_dir, inc_size)) { FILE *file = Open(pos); if (file) { - LogPrintf("Pre-allocating up to position 0x%x in %s%05u.dat\n", new_size, m_prefix, pos.nFile); + LogPrint(BCLog::VALIDATION, "Pre-allocating up to position 0x%x in %s%05u.dat\n", new_size, m_prefix, pos.nFile); AllocateFileRange(file, pos.nPos, inc_size); fclose(file); return inc_size; diff --git a/src/net.cpp b/src/net.cpp index 2a54dd2ae5..cda7491009 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -62,6 +62,7 @@ #include #include +#include #include #include @@ -2865,7 +2866,7 @@ void CConnman::ThreadI2PAcceptIncoming() } if (!advertising_listen_addr) { - AddLocal(conn.me, LOCAL_BIND); + AddLocal(conn.me, LOCAL_MANUAL); advertising_listen_addr = true; } @@ -3049,8 +3050,9 @@ NodeId CConnman::GetNewNodeId() bool CConnman::Bind(const CService &addr, unsigned int flags, NetPermissionFlags permissions) { - if (!(flags & BF_EXPLICIT) && !IsReachable(addr)) + if (!(flags & BF_EXPLICIT) && !IsReachable(addr)) { return false; + } bilingual_str strError; if (!BindListenPort(addr, strError, permissions)) { if ((flags & BF_REPORT_ERROR) && clientInterface) { @@ -3059,7 +3061,7 @@ bool CConnman::Bind(const CService &addr, unsigned int flags, NetPermissionFlags return false; } - if (addr.IsRoutable() && fDiscover && !(flags & BF_DONT_ADVERTISE) && !(permissions & PF_NOBAN)) { + if (addr.IsRoutable() && fDiscover && !(flags & BF_DONT_ADVERTISE) && !NetPermissions::HasFlag(permissions, NetPermissionFlags::PF_NOBAN)) { AddLocal(addr, LOCAL_BIND); } diff --git a/src/net_permissions.h b/src/net_permissions.h index ab8f513626..b1c11a3308 100644 --- a/src/net_permissions.h +++ b/src/net_permissions.h @@ -50,8 +50,14 @@ public: { flags = static_cast(flags | f); } + //! ClearFlag is only called with `f` == NetPermissionFlags::PF_ISIMPLICIT. + //! If that should change in the future, be aware that ClearFlag should not + //! be called with a subflag of a multiflag, e.g. NetPermissionFlags::PF_RELAY + //! or NetPermissionFlags::PF_DOWNLOAD, as that would leave `flags` in an + //! invalid state corresponding to none of the existing flags. static inline void ClearFlag(NetPermissionFlags& flags, NetPermissionFlags f) { + assert(f == NetPermissionFlags::PF_ISIMPLICIT); flags = static_cast(flags & ~f); } }; diff --git a/src/net_processing.cpp b/src/net_processing.cpp old mode 100755 new mode 100644 diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 5da6234d34..6a0a1e2d38 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -30,6 +30,7 @@ #include #endif +#include #include #include #include @@ -903,6 +904,7 @@ void BitcoinGUI::removeWallet(WalletModel* walletModel) m_wallet_selector->removeItem(index); if (m_wallet_selector->count() == 0) { setWalletActionsEnabled(false); + overviewButton->setChecked(true); } else if (m_wallet_selector->count() == 1) { m_wallet_selector_action->setVisible(false); } @@ -1924,7 +1926,6 @@ void BitcoinGUI::showProgress(const QString &title, int nProgress) progressDialog = new QProgressDialog(title, QString(), 0, 100, this); GUIUtil::PolishProgressDialog(progressDialog); progressDialog->setWindowModality(Qt::ApplicationModal); - progressDialog->setMinimumDuration(0); progressDialog->setAutoClose(false); progressDialog->setValue(0); } else if (nProgress == 100) { diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 8491b64170..08a494ca1f 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index f7aca14f0c..59bf223cd8 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -1726,8 +1726,11 @@ void updateButtonGroupShortcuts(QButtonGroup* buttonGroup) void setClipboard(const QString& str) { - QApplication::clipboard()->setText(str, QClipboard::Clipboard); - QApplication::clipboard()->setText(str, QClipboard::Selection); + QClipboard* clipboard = QApplication::clipboard(); + clipboard->setText(str, QClipboard::Clipboard); + if (clipboard->supportsSelection()) { + clipboard->setText(str, QClipboard::Selection); + } } fs::path qstringToBoostPath(const QString &path) @@ -1871,10 +1874,12 @@ void PolishProgressDialog(QProgressDialog* dialog) // Workaround for macOS-only Qt bug; see: QTBUG-65750, QTBUG-70357. const int margin = TextWidth(dialog->fontMetrics(), ("X")); dialog->resize(dialog->width() + 2 * margin, dialog->height()); - dialog->show(); -#else - Q_UNUSED(dialog); #endif + // QProgressDialog estimates the time the operation will take (based on time + // for steps), and only shows itself if that estimate is beyond minimumDuration. + // The default minimumDuration value is 4 seconds, and it could make users + // think that the GUI is frozen. + dialog->setMinimumDuration(0); } int TextWidth(const QFontMetrics& fm, const QString& text) diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 7c423b5163..1d5eb60953 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -469,6 +469,8 @@ RPCConsole::RPCConsole(interfaces::Node& node, QWidget* parent, Qt::WindowFlags move(QGuiApplication::primaryScreen()->availableGeometry().center() - frameGeometry().center()); } + ui->splitter->restoreState(settings.value("PeersTabSplitterSizes").toByteArray()); + QChar nonbreaking_hyphen(8209); ui->dataDir->setToolTip(ui->dataDir->toolTip().arg(QString(nonbreaking_hyphen) + "datadir")); ui->blocksDir->setToolTip(ui->blocksDir->toolTip().arg(QString(nonbreaking_hyphen) + "blocksdir")); @@ -531,6 +533,7 @@ RPCConsole::~RPCConsole() { QSettings settings; settings.setValue("RPCConsoleWindowGeometry", saveGeometry()); + settings.setValue("PeersTabSplitterSizes", ui->splitter->saveState()); m_node.rpcUnsetTimerInterface(rpcTimerInterface); delete rpcTimerInterface; delete pageButtons; diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index 43f84f79e5..70cca5cfd1 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -22,6 +22,8 @@ #include #include +#include + #include #include #include diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp index f237b70d2b..b2f65f4f58 100644 --- a/src/qt/test/test_main.cpp +++ b/src/qt/test/test_main.cpp @@ -56,6 +56,13 @@ int main(int argc, char* argv[]) NodeContext node_context; std::unique_ptr node = interfaces::MakeNode(&node_context); + gArgs.ForceSetArg("-listen", "0"); + gArgs.ForceSetArg("-listenonion", "0"); + gArgs.ForceSetArg("-discover", "0"); + gArgs.ForceSetArg("-dnsseed", "0"); + gArgs.ForceSetArg("-fixedseeds", "0"); + gArgs.ForceSetArg("-upnp", "0"); + gArgs.ForceSetArg("-natpmp", "0"); bool fInvalid = false; diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 9dc74a7ed7..9ea562c048 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include diff --git a/src/qt/walletcontroller.cpp b/src/qt/walletcontroller.cpp index 0afbf282e0..9b6aed8fbf 100644 --- a/src/qt/walletcontroller.cpp +++ b/src/qt/walletcontroller.cpp @@ -178,6 +178,9 @@ void WalletControllerActivity::showProgressDialog(const QString& label_text) m_progress_dialog->setCancelButton(nullptr); m_progress_dialog->setWindowModality(Qt::ApplicationModal); GUIUtil::PolishProgressDialog(m_progress_dialog); + // The setValue call forces QProgressDialog to start the internal duration estimation. + // See details in https://bugreports.qt.io/browse/QTBUG-47042. + m_progress_dialog->setValue(0); } void WalletControllerActivity::destroyProgressDialog() diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index b1896ef887..d7c11f1327 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -30,6 +30,7 @@ #include #include +#include #include #include diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index de7bbf819e..019581ab77 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -462,7 +462,6 @@ void WalletView::showProgress(const QString &title, int nProgress) progressDialog = new QProgressDialog(title, tr("Cancel"), 0, 100, this); GUIUtil::PolishProgressDialog(progressDialog); progressDialog->setWindowModality(Qt::ApplicationModal); - progressDialog->setMinimumDuration(0); progressDialog->setAutoClose(false); progressDialog->setValue(0); } else if (nProgress == 100) { diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 25e396b777..3e83a14c95 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -2734,7 +2734,7 @@ UniValue scantxoutset(const JSONRPCRequest& request) LOCK(cs_main); CChainState& active_chainstate = chainman.ActiveChainstate(); active_chainstate.ForceFlushStateToDisk(); - pcursor = std::unique_ptr(active_chainstate.CoinsDB().Cursor()); + pcursor = active_chainstate.CoinsDB().Cursor(); CHECK_NONFATAL(pcursor); tip = active_chainstate.m_chain.Tip(); CHECK_NONFATAL(tip); @@ -2923,7 +2923,7 @@ UniValue CreateUTXOSnapshot(NodeContext& node, CChainState& chainstate, CAutoFil throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set"); } - pcursor = std::unique_ptr(chainstate.CoinsDB().Cursor()); + pcursor = chainstate.CoinsDB().Cursor(); tip = chainstate.m_blockman.LookupBlockIndex(stats.hashBlock); CHECK_NONFATAL(tip); } diff --git a/src/scheduler.cpp b/src/scheduler.cpp index ede58adff7..38f202361e 100644 --- a/src/scheduler.cpp +++ b/src/scheduler.cpp @@ -8,6 +8,7 @@ #include #include +#include #include CScheduler::CScheduler() diff --git a/src/shutdown.cpp b/src/shutdown.cpp index f835833f38..ea6bf9119f 100644 --- a/src/shutdown.cpp +++ b/src/shutdown.cpp @@ -50,7 +50,7 @@ static int g_shutdown_pipe[2] = {-1, -1}; bool InitShutdownState() { #ifndef WIN32 -#if HAVE_O_CLOEXEC +#if HAVE_O_CLOEXEC && HAVE_DECL_PIPE2 // If we can, make sure that the file descriptors are closed on exec() // to prevent interference. if (pipe2(g_shutdown_pipe, O_CLOEXEC) != 0) { diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp index 00e3160048..cb118a9952 100644 --- a/src/test/bip32_tests.cpp +++ b/src/test/bip32_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2013-2020 The Bitcoin Core developers +// Copyright (c) 2013-2021 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -87,6 +87,18 @@ TestVector test3 = "xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L", 0); +TestVector test4 = + TestVector("3ddd5602285899a946114506157c7997e5444528f3003f6134712147db19b678") + ("xpub661MyMwAqRbcGczjuMoRm6dXaLDEhW1u34gKenbeYqAix21mdUKJyuyu5F1rzYGVxyL6tmgBUAEPrEz92mBXjByMRiJdba9wpnN37RLLAXa", + "xprv9s21ZrQH143K48vGoLGRPxgo2JNkJ3J3fqkirQC2zVdk5Dgd5w14S7fRDyHH4dWNHUgkvsvNDCkvAwcSHNAQwhwgNMgZhLtQC63zxwhQmRv", + 0x80000000) + ("xpub69AUMk3qDBi3uW1sXgjCmVjJ2G6WQoYSnNHyzkmdCHEhSZ4tBok37xfFEqHd2AddP56Tqp4o56AePAgCjYdvpW2PU2jbUPFKsav5ut6Ch1m", + "xprv9vB7xEWwNp9kh1wQRfCCQMnZUEG21LpbR9NPCNN1dwhiZkjjeGRnaALmPXCX7SgjFTiCTT6bXes17boXtjq3xLpcDjzEuGLQBM5ohqkao9G", + 0x80000001) + ("xpub6BJA1jSqiukeaesWfxe6sNK9CCGaujFFSJLomWHprUL9DePQ4JDkM5d88n49sMGJxrhpjazuXYWdMf17C9T5XnxkopaeS7jGk1GyyVziaMt", + "xprv9xJocDuwtYCMNAo3Zw76WENQeAS6WGXQ55RCy7tDJ8oALr4FWkuVoHJeHVAcAqiZLE7Je3vZJHxspZdFHfnBEjHqU5hG1Jaj32dVoS6XLT1", + 0); + static void RunTest(const TestVector &test) { std::vector seed = ParseHex(test.strHexMaster); CExtKey key; @@ -135,4 +147,8 @@ BOOST_AUTO_TEST_CASE(bip32_test3) { RunTest(test3); } +BOOST_AUTO_TEST_CASE(bip32_test4) { + RunTest(test4); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/fuzz/addrman.cpp b/src/test/fuzz/addrman.cpp index ce871642f4..cf91434f8e 100644 --- a/src/test/fuzz/addrman.cpp +++ b/src/test/fuzz/addrman.cpp @@ -118,7 +118,7 @@ FUZZ_TARGET_INIT(addrman, initialize_addrman) [&] { const std::optional opt_service = ConsumeDeserializable(fuzzed_data_provider); if (opt_service) { - addr_man.SetServices(*opt_service, ServiceFlags{fuzzed_data_provider.ConsumeIntegral()}); + addr_man.SetServices(*opt_service, ConsumeWeakEnum(fuzzed_data_provider, ALL_SERVICE_FLAGS)); } }); } diff --git a/src/test/fuzz/coins_view.cpp b/src/test/fuzz/coins_view.cpp index db5e0ddb8c..da96d2fae0 100644 --- a/src/test/fuzz/coins_view.cpp +++ b/src/test/fuzz/coins_view.cpp @@ -180,8 +180,8 @@ FUZZ_TARGET_INIT(coins_view, initialize_coins_view) } { - const CCoinsViewCursor* coins_view_cursor = backend_coins_view.Cursor(); - assert(coins_view_cursor == nullptr); + std::unique_ptr coins_view_cursor = backend_coins_view.Cursor(); + assert(!coins_view_cursor); (void)backend_coins_view.EstimateSize(); (void)backend_coins_view.GetBestBlock(); (void)backend_coins_view.GetHeadBlocks(); diff --git a/src/test/fuzz/i2p.cpp b/src/test/fuzz/i2p.cpp index 345d68502a..e0d62fb493 100644 --- a/src/test/fuzz/i2p.cpp +++ b/src/test/fuzz/i2p.cpp @@ -37,7 +37,7 @@ FUZZ_TARGET_INIT(i2p, initialize_i2p) if (sess.Listen(conn)) { if (sess.Accept(conn)) { try { - conn.sock->RecvUntilTerminator('\n', 10ms, interrupt, i2p::sam::MAX_MSG_SIZE); + (void)conn.sock->RecvUntilTerminator('\n', 10ms, interrupt, i2p::sam::MAX_MSG_SIZE); } catch (const std::runtime_error&) { } } diff --git a/src/test/fuzz/net_permissions.cpp b/src/test/fuzz/net_permissions.cpp index 544a33047b..6fdf4b653c 100644 --- a/src/test/fuzz/net_permissions.cpp +++ b/src/test/fuzz/net_permissions.cpp @@ -25,7 +25,7 @@ FUZZ_TARGET(net_permissions) (void)NetPermissions::ToStrings(net_whitebind_permissions.m_flags); (void)NetPermissions::AddFlag(net_whitebind_permissions.m_flags, net_permission_flags); assert(NetPermissions::HasFlag(net_whitebind_permissions.m_flags, net_permission_flags)); - (void)NetPermissions::ClearFlag(net_whitebind_permissions.m_flags, net_permission_flags); + (void)NetPermissions::ClearFlag(net_whitebind_permissions.m_flags, NetPermissionFlags::PF_ISIMPLICIT); (void)NetPermissions::ToStrings(net_whitebind_permissions.m_flags); } @@ -35,7 +35,7 @@ FUZZ_TARGET(net_permissions) (void)NetPermissions::ToStrings(net_whitelist_permissions.m_flags); (void)NetPermissions::AddFlag(net_whitelist_permissions.m_flags, net_permission_flags); assert(NetPermissions::HasFlag(net_whitelist_permissions.m_flags, net_permission_flags)); - (void)NetPermissions::ClearFlag(net_whitelist_permissions.m_flags, net_permission_flags); + (void)NetPermissions::ClearFlag(net_whitelist_permissions.m_flags, NetPermissionFlags::PF_ISIMPLICIT); (void)NetPermissions::ToStrings(net_whitelist_permissions.m_flags); } } diff --git a/src/test/fuzz/script.cpp b/src/test/fuzz/script.cpp index d9bb7b8fb4..619c4911b0 100644 --- a/src/test/fuzz/script.cpp +++ b/src/test/fuzz/script.cpp @@ -65,7 +65,15 @@ FUZZ_TARGET_INIT(script, initialize_script) (void)IsSolvable(signing_provider, script); TxoutType which_type; - (void)IsStandard(script, which_type); + bool is_standard_ret = IsStandard(script, which_type); + if (!is_standard_ret) { + assert(which_type == TxoutType::NONSTANDARD || + which_type == TxoutType::NULL_DATA || + which_type == TxoutType::MULTISIG); + } + if (which_type == TxoutType::NONSTANDARD) { + assert(!is_standard_ret); + } if (which_type == TxoutType::NULL_DATA) { assert(script.IsUnspendable()); } diff --git a/src/test/fuzz/socks5.cpp b/src/test/fuzz/socks5.cpp index 3da03f1dea..1bcadcd710 100644 --- a/src/test/fuzz/socks5.cpp +++ b/src/test/fuzz/socks5.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2020 The Bitcoin Core developers +// Copyright (c) 2020-2021 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -7,6 +7,7 @@ #include #include #include +#include #include #include diff --git a/src/test/fuzz/torcontrol.cpp b/src/test/fuzz/torcontrol.cpp index b7a42ea7f4..a97d3962bf 100644 --- a/src/test/fuzz/torcontrol.cpp +++ b/src/test/fuzz/torcontrol.cpp @@ -1,10 +1,11 @@ -// Copyright (c) 2020 The Bitcoin Core developers +// Copyright (c) 2020-2021 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include #include #include +#include #include #include diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp index 13e7337e90..f487c4f37a 100644 --- a/src/test/key_tests.cpp +++ b/src/test/key_tests.cpp @@ -172,20 +172,30 @@ BOOST_AUTO_TEST_CASE(key_signature_tests) } BOOST_CHECK(found); - // When entropy is not specified, we should always see low R signatures that are less than 70 bytes in 256 tries + // When entropy is not specified, we should always see low R signatures that are less than or equal to 70 bytes in 256 tries + // The low R signatures should always have the value of their "length of R" byte less than or equal to 32 // We should see at least one signature that is less than 70 bytes. - found = true; bool found_small = false; + bool found_big = false; + bool bad_sign = false; for (int i = 0; i < 256; ++i) { sig.clear(); std::string msg = "A message to be signed" + ToString(i); msg_hash = Hash(msg); - BOOST_CHECK(key.Sign(msg_hash, sig)); - found = sig[3] == 0x20; - BOOST_CHECK(sig.size() <= 70); + if (!key.Sign(msg_hash, sig)) { + bad_sign = true; + break; + } + // sig.size() > 70 implies sig[3] > 32, because S is always low. + // But check both conditions anyway, just in case this implication is broken for some reason + if (sig[3] > 32 || sig.size() > 70) { + found_big = true; + break; + } found_small |= sig.size() < 70; } - BOOST_CHECK(found); + BOOST_CHECK(!bad_sign); + BOOST_CHECK(!found_big); BOOST_CHECK(found_small); } diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp index a0d04aec49..8187fb58d5 100644 --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -351,6 +351,60 @@ BOOST_AUTO_TEST_CASE(cnetaddr_basic) BOOST_CHECK(!addr.SetSpecial("totally bogus")); } +BOOST_AUTO_TEST_CASE(cnetaddr_tostring_canonical_ipv6) +{ + // Test that CNetAddr::ToString formats IPv6 addresses with zero compression as described in + // RFC 5952 ("A Recommendation for IPv6 Address Text Representation"). + const std::map canonical_representations_ipv6{ + {"0000:0000:0000:0000:0000:0000:0000:0000", "::"}, + {"000:0000:000:00:0:00:000:0000", "::"}, + {"000:000:000:000:000:000:000:000", "::"}, + {"00:00:00:00:00:00:00:00", "::"}, + {"0:0:0:0:0:0:0:0", "::"}, + {"0:0:0:0:0:0:0:1", "::1"}, + {"2001:0:0:1:0:0:0:1", "2001:0:0:1::1"}, + {"2001:0db8:0:0:1:0:0:1", "2001:db8::1:0:0:1"}, + {"2001:0db8:85a3:0000:0000:8a2e:0370:7334", "2001:db8:85a3::8a2e:370:7334"}, + {"2001:0db8::0001", "2001:db8::1"}, + {"2001:0db8::0001:0000", "2001:db8::1:0"}, + {"2001:0db8::1:0:0:1", "2001:db8::1:0:0:1"}, + {"2001:db8:0000:0:1::1", "2001:db8::1:0:0:1"}, + {"2001:db8:0000:1:1:1:1:1", "2001:db8:0:1:1:1:1:1"}, + {"2001:db8:0:0:0:0:2:1", "2001:db8::2:1"}, + {"2001:db8:0:0:0::1", "2001:db8::1"}, + {"2001:db8:0:0:1:0:0:1", "2001:db8::1:0:0:1"}, + {"2001:db8:0:0:1::1", "2001:db8::1:0:0:1"}, + {"2001:DB8:0:0:1::1", "2001:db8::1:0:0:1"}, + {"2001:db8:0:0::1", "2001:db8::1"}, + {"2001:db8:0:0:aaaa::1", "2001:db8::aaaa:0:0:1"}, + {"2001:db8:0:1:1:1:1:1", "2001:db8:0:1:1:1:1:1"}, + {"2001:db8:0::1", "2001:db8::1"}, + {"2001:db8:85a3:0:0:8a2e:370:7334", "2001:db8:85a3::8a2e:370:7334"}, + {"2001:db8::0:1", "2001:db8::1"}, + {"2001:db8::0:1:0:0:1", "2001:db8::1:0:0:1"}, + {"2001:DB8::1", "2001:db8::1"}, + {"2001:db8::1", "2001:db8::1"}, + {"2001:db8::1:0:0:1", "2001:db8::1:0:0:1"}, + {"2001:db8::1:1:1:1:1", "2001:db8:0:1:1:1:1:1"}, + {"2001:db8::aaaa:0:0:1", "2001:db8::aaaa:0:0:1"}, + {"2001:db8:aaaa:bbbb:cccc:dddd:0:1", "2001:db8:aaaa:bbbb:cccc:dddd:0:1"}, + {"2001:db8:aaaa:bbbb:cccc:dddd::1", "2001:db8:aaaa:bbbb:cccc:dddd:0:1"}, + {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:0001", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:1"}, + {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:001", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:1"}, + {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:01", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:1"}, + {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:1", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:1"}, + {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:aaaa", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:aaaa"}, + {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:AAAA", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:aaaa"}, + {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:AaAa", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:aaaa"}, + }; + for (const auto& [input_address, expected_canonical_representation_output] : canonical_representations_ipv6) { + CNetAddr net_addr; + BOOST_REQUIRE(LookupHost(input_address, net_addr, false)); + BOOST_REQUIRE(net_addr.IsIPv6()); + BOOST_CHECK_EQUAL(net_addr.ToString(), expected_canonical_representation_output); + } +} + BOOST_AUTO_TEST_CASE(cnetaddr_serialize_v1) { CNetAddr addr; diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp index fcb11b7a0b..77250c6bb9 100644 --- a/src/test/netbase_tests.cpp +++ b/src/test/netbase_tests.cpp @@ -483,6 +483,28 @@ BOOST_AUTO_TEST_CASE(netpermissions_test) BOOST_CHECK(NetWhitebindPermissions::TryParse("@1.2.3.4:32", whitebindPermissions, error)); BOOST_CHECK_EQUAL(whitebindPermissions.m_flags, PF_NONE); + NetWhitebindPermissions noban, noban_download, download_noban, download; + + // "noban" implies "download" + BOOST_REQUIRE(NetWhitebindPermissions::TryParse("noban@1.2.3.4:32", noban, error)); + BOOST_CHECK_EQUAL(noban.m_flags, NetPermissionFlags::PF_NOBAN); + BOOST_CHECK(NetPermissions::HasFlag(noban.m_flags, NetPermissionFlags::PF_DOWNLOAD)); + BOOST_CHECK(NetPermissions::HasFlag(noban.m_flags, NetPermissionFlags::PF_NOBAN)); + + // "noban,download" is equivalent to "noban" + BOOST_REQUIRE(NetWhitebindPermissions::TryParse("noban,download@1.2.3.4:32", noban_download, error)); + BOOST_CHECK_EQUAL(noban_download.m_flags, noban.m_flags); + + // "download,noban" is equivalent to "noban" + BOOST_REQUIRE(NetWhitebindPermissions::TryParse("download,noban@1.2.3.4:32", download_noban, error)); + BOOST_CHECK_EQUAL(download_noban.m_flags, noban.m_flags); + + // "download" excludes (does not imply) "noban" + BOOST_REQUIRE(NetWhitebindPermissions::TryParse("download@1.2.3.4:32", download, error)); + BOOST_CHECK_EQUAL(download.m_flags, NetPermissionFlags::PF_DOWNLOAD); + BOOST_CHECK(NetPermissions::HasFlag(download.m_flags, NetPermissionFlags::PF_DOWNLOAD)); + BOOST_CHECK(!NetPermissions::HasFlag(download.m_flags, NetPermissionFlags::PF_NOBAN)); + // Happy path, can parse flags BOOST_CHECK(NetWhitebindPermissions::TryParse("bloom,forcerelay@1.2.3.4:32", whitebindPermissions, error)); // forcerelay should also activate the relay permission @@ -495,7 +517,7 @@ BOOST_AUTO_TEST_CASE(netpermissions_test) // Allow dups BOOST_CHECK(NetWhitebindPermissions::TryParse("bloom,relay,noban,noban@1.2.3.4:32", whitebindPermissions, error)); - BOOST_CHECK_EQUAL(whitebindPermissions.m_flags, PF_BLOOMFILTER | PF_RELAY | PF_NOBAN); + BOOST_CHECK_EQUAL(whitebindPermissions.m_flags, PF_BLOOMFILTER | PF_RELAY | PF_NOBAN | PF_DOWNLOAD); // "noban" implies "download" // Allow empty BOOST_CHECK(NetWhitebindPermissions::TryParse("bloom,relay,,noban@1.2.3.4:32", whitebindPermissions, error)); @@ -516,6 +538,8 @@ BOOST_AUTO_TEST_CASE(netpermissions_test) // Happy path for whitelist parsing BOOST_CHECK(NetWhitelistPermissions::TryParse("noban@1.2.3.4", whitelistPermissions, error)); BOOST_CHECK_EQUAL(whitelistPermissions.m_flags, PF_NOBAN); + BOOST_CHECK(NetPermissions::HasFlag(whitelistPermissions.m_flags, NetPermissionFlags::PF_NOBAN)); + BOOST_CHECK(NetWhitelistPermissions::TryParse("bloom,forcerelay,noban,relay@1.2.3.4/32", whitelistPermissions, error)); BOOST_CHECK_EQUAL(whitelistPermissions.m_flags, PF_BLOOMFILTER | PF_FORCERELAY | PF_NOBAN | PF_RELAY); BOOST_CHECK(error.empty()); diff --git a/src/test/scheduler_tests.cpp b/src/test/scheduler_tests.cpp index c100a2bd29..67ee05c78c 100644 --- a/src/test/scheduler_tests.cpp +++ b/src/test/scheduler_tests.cpp @@ -8,6 +8,7 @@ #include +#include #include #include #include diff --git a/src/test/sock_tests.cpp b/src/test/sock_tests.cpp index 400de875b7..9e98f4f0b1 100644 --- a/src/test/sock_tests.cpp +++ b/src/test/sock_tests.cpp @@ -139,7 +139,7 @@ BOOST_AUTO_TEST_CASE(wait) Sock sock0(s[0]); Sock sock1(s[1]); - std::thread waiter([&sock0]() { sock0.Wait(24h, Sock::RECV); }); + std::thread waiter([&sock0]() { (void)sock0.Wait(24h, Sock::RECV); }); BOOST_REQUIRE_EQUAL(sock1.Send("a", 1, 0), 1); @@ -162,7 +162,7 @@ BOOST_AUTO_TEST_CASE(recv_until_terminator_limit) // BOOST_CHECK_EXCEPTION() writes to some variables shared with the main thread which // creates a data race. So mimic it manually. try { - sock_recv.RecvUntilTerminator('\n', timeout, interrupt, max_data); + (void)sock_recv.RecvUntilTerminator('\n', timeout, interrupt, max_data); } catch (const std::runtime_error& e) { threw_as_expected = HasReason("too many bytes without a terminator")(e); } diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 9885459f0a..96f0f36953 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include diff --git a/src/test/versionbits_tests.cpp b/src/test/versionbits_tests.cpp index f71a73866a..d98ae13250 100644 --- a/src/test/versionbits_tests.cpp +++ b/src/test/versionbits_tests.cpp @@ -15,6 +15,18 @@ /* Define a virtual block time, one block per 10 minutes after Nov 14 2014, 0:55:36am */ static int32_t TestTime(int nHeight) { return 1415926536 + 600 * nHeight; } +static const std::string StateName(ThresholdState state) +{ + switch (state) { + case ThresholdState::DEFINED: return "DEFINED"; + case ThresholdState::STARTED: return "STARTED"; + case ThresholdState::LOCKED_IN: return "LOCKED_IN"; + case ThresholdState::ACTIVE: return "ACTIVE"; + case ThresholdState::FAILED: return "FAILED"; + } // no default case, so the compiler can warn about missing cases + return ""; +} + static const Consensus::Params paramsDummy = Consensus::Params(); class TestConditionChecker : public AbstractThresholdConditionChecker @@ -40,6 +52,13 @@ public: int64_t BeginTime(const Consensus::Params& params) const override { return Consensus::BIP9Deployment::ALWAYS_ACTIVE; } }; +class TestNeverActiveConditionChecker : public TestConditionChecker +{ +public: + int64_t BeginTime(const Consensus::Params& params) const override { return 0; } + int64_t EndTime(const Consensus::Params& params) const override { return 1230768000; } +}; + #define CHECKERS 6 class VersionBitsTester @@ -53,6 +72,8 @@ class VersionBitsTester TestConditionChecker checker[CHECKERS]; // Another 6 that assume always active activation TestAlwaysActiveConditionChecker checker_always[CHECKERS]; + // Another 6 that assume never active activation + TestNeverActiveConditionChecker checker_never[CHECKERS]; // Test counter (to identify failures) int num; @@ -67,6 +88,7 @@ public: for (unsigned int i = 0; i < CHECKERS; i++) { checker[i] = TestConditionChecker(); checker_always[i] = TestAlwaysActiveConditionChecker(); + checker_never[i] = TestNeverActiveConditionChecker(); } vpblock.clear(); return *this; @@ -94,66 +116,40 @@ public: if (InsecureRandBits(i) == 0) { BOOST_CHECK_MESSAGE(checker[i].GetStateSinceHeightFor(vpblock.empty() ? nullptr : vpblock.back()) == height, strprintf("Test %i for StateSinceHeight", num)); BOOST_CHECK_MESSAGE(checker_always[i].GetStateSinceHeightFor(vpblock.empty() ? nullptr : vpblock.back()) == 0, strprintf("Test %i for StateSinceHeight (always active)", num)); + + // never active may go from DEFINED -> FAILED at the first period + const auto never_height = checker_never[i].GetStateSinceHeightFor(vpblock.empty() ? nullptr : vpblock.back()); + BOOST_CHECK_MESSAGE(never_height == 0 || never_height == checker_never[i].Period(paramsDummy), strprintf("Test %i for StateSinceHeight (never active)", num)); } } num++; return *this; } - VersionBitsTester& TestDefined() { + VersionBitsTester& TestState(ThresholdState exp) { for (int i = 0; i < CHECKERS; i++) { if (InsecureRandBits(i) == 0) { - BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == ThresholdState::DEFINED, strprintf("Test %i for DEFINED", num)); - BOOST_CHECK_MESSAGE(checker_always[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == ThresholdState::ACTIVE, strprintf("Test %i for ACTIVE (always active)", num)); + const CBlockIndex* pindex = vpblock.empty() ? nullptr : vpblock.back(); + ThresholdState got = checker[i].GetStateFor(pindex); + ThresholdState got_always = checker_always[i].GetStateFor(pindex); + ThresholdState got_never = checker_never[i].GetStateFor(pindex); + // nHeight of the next block. If vpblock is empty, the next (ie first) + // block should be the genesis block with nHeight == 0. + int height = pindex == nullptr ? 0 : pindex->nHeight + 1; + BOOST_CHECK_MESSAGE(got == exp, strprintf("Test %i for %s height %d (got %s)", num, StateName(exp), height, StateName(got))); + BOOST_CHECK_MESSAGE(got_always == ThresholdState::ACTIVE, strprintf("Test %i for ACTIVE height %d (got %s; always active case)", num, height, StateName(got_always))); + BOOST_CHECK_MESSAGE(got_never == ThresholdState::DEFINED|| got_never == ThresholdState::FAILED, strprintf("Test %i for DEFINED/FAILED height %d (got %s; never active case)", num, height, StateName(got_never))); } } num++; return *this; } - VersionBitsTester& TestStarted() { - for (int i = 0; i < CHECKERS; i++) { - if (InsecureRandBits(i) == 0) { - BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == ThresholdState::STARTED, strprintf("Test %i for STARTED", num)); - BOOST_CHECK_MESSAGE(checker_always[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == ThresholdState::ACTIVE, strprintf("Test %i for ACTIVE (always active)", num)); - } - } - num++; - return *this; - } - - VersionBitsTester& TestLockedIn() { - for (int i = 0; i < CHECKERS; i++) { - if (InsecureRandBits(i) == 0) { - BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == ThresholdState::LOCKED_IN, strprintf("Test %i for LOCKED_IN", num)); - BOOST_CHECK_MESSAGE(checker_always[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == ThresholdState::ACTIVE, strprintf("Test %i for ACTIVE (always active)", num)); - } - } - num++; - return *this; - } - - VersionBitsTester& TestActive() { - for (int i = 0; i < CHECKERS; i++) { - if (InsecureRandBits(i) == 0) { - BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == ThresholdState::ACTIVE, strprintf("Test %i for ACTIVE", num)); - BOOST_CHECK_MESSAGE(checker_always[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == ThresholdState::ACTIVE, strprintf("Test %i for ACTIVE (always active)", num)); - } - } - num++; - return *this; - } - - VersionBitsTester& TestFailed() { - for (int i = 0; i < CHECKERS; i++) { - if (InsecureRandBits(i) == 0) { - BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == ThresholdState::FAILED, strprintf("Test %i for FAILED", num)); - BOOST_CHECK_MESSAGE(checker_always[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == ThresholdState::ACTIVE, strprintf("Test %i for ACTIVE (always active)", num)); - } - } - num++; - return *this; - } + VersionBitsTester& TestDefined() { return TestState(ThresholdState::DEFINED); } + VersionBitsTester& TestStarted() { return TestState(ThresholdState::STARTED); } + VersionBitsTester& TestLockedIn() { return TestState(ThresholdState::LOCKED_IN); } + VersionBitsTester& TestActive() { return TestState(ThresholdState::ACTIVE); } + VersionBitsTester& TestFailed() { return TestState(ThresholdState::FAILED); } CBlockIndex * Tip() { return vpblock.size() ? vpblock.back() : nullptr; } }; diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 80f192732a..ae600cd556 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -18,10 +18,11 @@ #include #include -#include #include +#include #include #include +#include #include diff --git a/src/txdb.cpp b/src/txdb.cpp index 1775204924..646ef850fd 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -172,9 +172,34 @@ bool CBlockTreeDB::ReadLastBlockFile(int &nFile) { return Read(DB_LAST_BLOCK, nFile); } -CCoinsViewCursor *CCoinsViewDB::Cursor() const +/** Specialization of CCoinsViewCursor to iterate over a CCoinsViewDB */ +class CCoinsViewDBCursor: public CCoinsViewCursor { - CCoinsViewDBCursor *i = new CCoinsViewDBCursor(const_cast(*m_db).NewIterator(), GetBestBlock()); +public: + // Prefer using CCoinsViewDB::Cursor() since we want to perform some + // cache warmup on instantiation. + CCoinsViewDBCursor(CDBIterator* pcursorIn, const uint256&hashBlockIn): + CCoinsViewCursor(hashBlockIn), pcursor(pcursorIn) {} + ~CCoinsViewDBCursor() {} + + bool GetKey(COutPoint &key) const override; + bool GetValue(Coin &coin) const override; + unsigned int GetValueSize() const override; + + bool Valid() const override; + void Next() override; + +private: + std::unique_ptr pcursor; + std::pair keyTmp; + + friend class CCoinsViewDB; +}; + +std::unique_ptr CCoinsViewDB::Cursor() const +{ + auto i = std::make_unique( + const_cast(*m_db).NewIterator(), GetBestBlock()); /* It seems that there are no "const iterators" for LevelDB. Since we only need read operations on it, use a const-cast to get around that restriction. */ diff --git a/src/txdb.h b/src/txdb.h index 48f440bad5..c2627aa079 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -63,7 +63,7 @@ public: uint256 GetBestBlock() const override; std::vector GetHeadBlocks() const override; bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) override; - CCoinsViewCursor *Cursor() const override; + std::unique_ptr Cursor() const override; //! Attempt to update from an older database format. Returns whether an error occurred. bool Upgrade(); @@ -73,28 +73,6 @@ public: void ResizeCache(size_t new_cache_size) EXCLUSIVE_LOCKS_REQUIRED(cs_main); }; -/** Specialization of CCoinsViewCursor to iterate over a CCoinsViewDB */ -class CCoinsViewDBCursor: public CCoinsViewCursor -{ -public: - ~CCoinsViewDBCursor() {} - - bool GetKey(COutPoint &key) const override; - bool GetValue(Coin &coin) const override; - unsigned int GetValueSize() const override; - - bool Valid() const override; - void Next() override; - -private: - CCoinsViewDBCursor(CDBIterator* pcursorIn, const uint256 &hashBlockIn): - CCoinsViewCursor(hashBlockIn), pcursor(pcursorIn) {} - std::unique_ptr pcursor; - std::pair keyTmp; - - friend class CCoinsViewDB; -}; - /** Access to the block database (blocks/index/) */ class CBlockTreeDB : public CDBWrapper { diff --git a/src/util/sock.cpp b/src/util/sock.cpp index 0bc9795db3..b6c2a47434 100644 --- a/src/util/sock.cpp +++ b/src/util/sock.cpp @@ -179,7 +179,7 @@ void Sock::SendComplete(const std::string& data, // Wait for a short while (or the socket to become ready for sending) before retrying // if nothing was sent. const auto wait_time = std::min(deadline - now, std::chrono::milliseconds{MAX_WAIT_FOR_IO}); - Wait(wait_time, SEND); + (void)Wait(wait_time, SEND); } } @@ -262,7 +262,7 @@ std::string Sock::RecvUntilTerminator(uint8_t terminator, // Wait for a short while (or the socket to become ready for reading) before retrying. const auto wait_time = std::min(deadline - now, std::chrono::milliseconds{MAX_WAIT_FOR_IO}); - Wait(wait_time, RECV); + (void)Wait(wait_time, RECV); } } diff --git a/src/util/sock.h b/src/util/sock.h index c4ad0cbc43..8099c702a1 100644 --- a/src/util/sock.h +++ b/src/util/sock.h @@ -64,7 +64,7 @@ public: * Get the value of the contained socket. * @return socket or INVALID_SOCKET if empty */ - virtual SOCKET Get() const; + [[nodiscard]] virtual SOCKET Get() const; /** * Get the value of the contained socket and drop ownership. It will not be closed by the @@ -82,26 +82,29 @@ public: * send(2) wrapper. Equivalent to `send(this->Get(), data, len, flags);`. Code that uses this * wrapper can be unit tested if this method is overridden by a mock Sock implementation. */ - virtual ssize_t Send(const void* data, size_t len, int flags) const; + [[nodiscard]] virtual ssize_t Send(const void* data, size_t len, int flags) const; /** * recv(2) wrapper. Equivalent to `recv(this->Get(), buf, len, flags);`. Code that uses this * wrapper can be unit tested if this method is overridden by a mock Sock implementation. */ - virtual ssize_t Recv(void* buf, size_t len, int flags) const; + [[nodiscard]] virtual ssize_t Recv(void* buf, size_t len, int flags) const; /** * connect(2) wrapper. Equivalent to `connect(this->Get(), addr, addrlen)`. Code that uses this * wrapper can be unit tested if this method is overridden by a mock Sock implementation. */ - virtual int Connect(const sockaddr* addr, socklen_t addr_len) const; + [[nodiscard]] virtual int Connect(const sockaddr* addr, socklen_t addr_len) const; /** * getsockopt(2) wrapper. Equivalent to * `getsockopt(this->Get(), level, opt_name, opt_val, opt_len)`. Code that uses this * wrapper can be unit tested if this method is overridden by a mock Sock implementation. */ - virtual int GetSockOpt(int level, int opt_name, void* opt_val, socklen_t* opt_len) const; + [[nodiscard]] virtual int GetSockOpt(int level, + int opt_name, + void* opt_val, + socklen_t* opt_len) const; using Event = uint8_t; @@ -124,9 +127,9 @@ public: * value of `true` and `occurred` being set to 0. * @return true on success and false otherwise */ - virtual bool Wait(std::chrono::milliseconds timeout, - Event requested, - Event* occurred = nullptr) const; + [[nodiscard]] virtual bool Wait(std::chrono::milliseconds timeout, + Event requested, + Event* occurred = nullptr) const; /* Higher level, convenience, methods. These may throw. */ @@ -154,17 +157,17 @@ public: * @throws std::runtime_error if the operation cannot be completed. In this case some bytes may * have been consumed from the socket. */ - virtual std::string RecvUntilTerminator(uint8_t terminator, - std::chrono::milliseconds timeout, - CThreadInterrupt& interrupt, - size_t max_data) const; + [[nodiscard]] virtual std::string RecvUntilTerminator(uint8_t terminator, + std::chrono::milliseconds timeout, + CThreadInterrupt& interrupt, + size_t max_data) const; /** * Check if still connected. * @param[out] err The error string, if the socket has been disconnected. * @return true if connected */ - virtual bool IsConnected(std::string& errmsg) const; + [[nodiscard]] virtual bool IsConnected(std::string& errmsg) const; protected: /** diff --git a/src/validation.cpp b/src/validation.cpp index 7858f944ff..d05bed342e 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -3675,7 +3675,7 @@ bool FindBlockPos(FlatFilePos& pos, unsigned int nAddSize, unsigned int nHeight, if ((int)nFile != nLastBlockFile) { if (!fKnown) { - LogPrintf("Leaving block file %i: %s\n", nLastBlockFile, vinfoBlockFile[nLastBlockFile].ToString()); + LogPrint(BCLog::VALIDATION, "Leaving block file %i: %s\n", nLastBlockFile, vinfoBlockFile[nLastBlockFile].ToString()); } FlushBlockFile(!fKnown, finalize_undo); nLastBlockFile = nFile; diff --git a/test/functional/feature_coinstatsindex.py b/test/functional/feature_coinstatsindex.py index 1f247f3d98..70e5aa1389 100755 --- a/test/functional/feature_coinstatsindex.py +++ b/test/functional/feature_coinstatsindex.py @@ -286,6 +286,7 @@ class CoinStatsIndexTest(BitcoinTestFramework): # Add another block, so we don't depend on reconsiderblock remembering which # blocks were touched by invalidateblock index_node.generate(1) + self.sync_all() # Ensure that removing and re-adding blocks yields consistent results block = index_node.getblockhash(99) diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py index 2342ce78fc..28de022a6c 100755 --- a/test/functional/test_framework/test_framework.py +++ b/test/functional/test_framework/test_framework.py @@ -22,6 +22,7 @@ import tempfile import time from concurrent.futures import ThreadPoolExecutor +from typing import List from .authproxy import JSONRPCException from test_framework.blocktools import TIME_GENESIS_BLOCK from . import coverage @@ -113,9 +114,9 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass): def __init__(self): """Sets test framework defaults. Do not override this method. Instead, override the set_test_params() method""" - self.chain = 'regtest' - self.setup_clean_chain = False - self.nodes = [] + self.chain: str = 'regtest' + self.setup_clean_chain: bool = False + self.nodes: List[TestNode] = [] self.network_thread = None self.mocktime = 0 self.rpc_timeout = 60 # Wait for up to 60 seconds for the RPC server to respond