diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 18 | ||||
-rw-r--r-- | src/Makefile.bench.include | 2 | ||||
-rw-r--r-- | src/Makefile.qt.include | 4 | ||||
-rw-r--r-- | src/Makefile.qttest.include | 2 | ||||
-rw-r--r-- | src/Makefile.test.include | 4 | ||||
-rw-r--r-- | src/Makefile.test_fuzz.include | 2 | ||||
-rw-r--r-- | src/Makefile.test_util.include | 2 | ||||
-rw-r--r-- | src/bitcoin-tx.cpp | 6 | ||||
-rw-r--r-- | src/blockfilter.cpp | 31 | ||||
-rw-r--r-- | src/init.cpp | 64 | ||||
-rw-r--r-- | src/net.cpp | 38 | ||||
-rw-r--r-- | src/net.h | 13 | ||||
-rw-r--r-- | src/net_processing.cpp | 84 | ||||
-rw-r--r-- | src/node/blockstorage.cpp | 2 | ||||
-rw-r--r-- | src/node/chainstate.cpp | 2 | ||||
-rw-r--r-- | src/node/chainstate.h | 2 | ||||
-rw-r--r-- | src/rpc/blockchain.cpp | 6 | ||||
-rw-r--r-- | src/test/fuzz/golomb_rice.cpp | 14 | ||||
-rw-r--r-- | src/test/fuzz/util.cpp | 16 | ||||
-rw-r--r-- | src/test/fuzz/util.h | 2 | ||||
-rw-r--r-- | src/test/util/net.h | 18 | ||||
-rw-r--r-- | src/test/util/setup_common.cpp | 32 | ||||
-rw-r--r-- | src/util/golombrice.h | 31 | ||||
-rw-r--r-- | src/util/sock.cpp | 27 | ||||
-rw-r--r-- | src/util/sock.h | 9 | ||||
-rw-r--r-- | src/wallet/dump.cpp | 5 |
26 files changed, 247 insertions, 189 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 994038a03b..b946a325c9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -17,7 +17,7 @@ EXTRA_LIBRARIES = BITCOIN_INCLUDES=-I$(builddir) -I$(srcdir)/$(MINISKETCH_INCLUDE_DIR_INT) -I$(srcdir)/secp256k1/include -I$(srcdir)/$(UNIVALUE_INCLUDE_DIR_INT) $(BDB_CPPFLAGS) $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) -LIBBITCOIN_SERVER=libbitcoin_server.a +LIBBITCOIN_NODE=libbitcoin_node.a LIBBITCOIN_COMMON=libbitcoin_common.a LIBBITCOIN_CONSENSUS=libbitcoin_consensus.a LIBBITCOIN_CLI=libbitcoin_cli.a @@ -61,7 +61,7 @@ EXTRA_LIBRARIES += \ $(LIBBITCOIN_UTIL) \ $(LIBBITCOIN_COMMON) \ $(LIBBITCOIN_CONSENSUS) \ - $(LIBBITCOIN_SERVER) \ + $(LIBBITCOIN_NODE) \ $(LIBBITCOIN_CLI) \ $(LIBBITCOIN_IPC) \ $(LIBBITCOIN_WALLET) \ @@ -317,9 +317,9 @@ ipc/capnp/libbitcoin_ipc_a-ipc.$(OBJEXT): $(libbitcoin_ipc_mpgen_input:=.h) # Contains code accessing mempool and chain state that is meant to be separated # from wallet and gui code (see node/README.md). Shared code should go in # libbitcoin_common or libbitcoin_util libraries, instead. -libbitcoin_server_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(MINIUPNPC_CPPFLAGS) $(NATPMP_CPPFLAGS) $(EVENT_CFLAGS) $(EVENT_PTHREADS_CFLAGS) -libbitcoin_server_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) -libbitcoin_server_a_SOURCES = \ +libbitcoin_node_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(MINIUPNPC_CPPFLAGS) $(NATPMP_CPPFLAGS) $(EVENT_CFLAGS) $(EVENT_PTHREADS_CFLAGS) +libbitcoin_node_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) +libbitcoin_node_a_SOURCES = \ addrdb.cpp \ addrman.cpp \ banman.cpp \ @@ -382,10 +382,10 @@ libbitcoin_server_a_SOURCES = \ $(BITCOIN_CORE_H) if ENABLE_WALLET -libbitcoin_server_a_SOURCES += wallet/init.cpp +libbitcoin_node_a_SOURCES += wallet/init.cpp endif if !ENABLE_WALLET -libbitcoin_server_a_SOURCES += dummywallet.cpp +libbitcoin_node_a_SOURCES += dummywallet.cpp endif if ENABLE_ZMQ @@ -670,13 +670,13 @@ bitcoind_SOURCES = $(bitcoin_daemon_sources) init/bitcoind.cpp bitcoind_CPPFLAGS = $(bitcoin_bin_cppflags) bitcoind_CXXFLAGS = $(bitcoin_bin_cxxflags) bitcoind_LDFLAGS = $(bitcoin_bin_ldflags) -bitcoind_LDADD = $(LIBBITCOIN_SERVER) $(bitcoin_bin_ldadd) +bitcoind_LDADD = $(LIBBITCOIN_NODE) $(bitcoin_bin_ldadd) bitcoin_node_SOURCES = $(bitcoin_daemon_sources) init/bitcoin-node.cpp bitcoin_node_CPPFLAGS = $(bitcoin_bin_cppflags) bitcoin_node_CXXFLAGS = $(bitcoin_bin_cxxflags) bitcoin_node_LDFLAGS = $(bitcoin_bin_ldflags) -bitcoin_node_LDADD = $(LIBBITCOIN_SERVER) $(bitcoin_bin_ldadd) $(LIBBITCOIN_IPC) $(LIBMULTIPROCESS_LIBS) +bitcoin_node_LDADD = $(LIBBITCOIN_NODE) $(bitcoin_bin_ldadd) $(LIBBITCOIN_IPC) $(LIBMULTIPROCESS_LIBS) # bitcoin-cli binary # bitcoin_cli_SOURCES = bitcoin-cli.cpp diff --git a/src/Makefile.bench.include b/src/Makefile.bench.include index 2a8e4a0aac..2feb31a9e9 100644 --- a/src/Makefile.bench.include +++ b/src/Makefile.bench.include @@ -51,7 +51,7 @@ nodist_bench_bench_bitcoin_SOURCES = $(GENERATED_BENCH_FILES) bench_bench_bitcoin_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(EVENT_CFLAGS) $(EVENT_PTHREADS_CFLAGS) -I$(builddir)/bench/ bench_bench_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) bench_bench_bitcoin_LDADD = \ - $(LIBBITCOIN_SERVER) \ + $(LIBBITCOIN_NODE) \ $(LIBBITCOIN_WALLET) \ $(LIBBITCOIN_COMMON) \ $(LIBBITCOIN_UTIL) \ diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 6c0e6f7c6f..f4d4641feb 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -323,7 +323,7 @@ bitcoin_qt_sources = qt/main.cpp if TARGET_WINDOWS bitcoin_qt_sources += $(BITCOIN_QT_RC) endif -bitcoin_qt_ldadd = qt/libbitcoinqt.a $(LIBBITCOIN_SERVER) +bitcoin_qt_ldadd = qt/libbitcoinqt.a $(LIBBITCOIN_NODE) if ENABLE_WALLET bitcoin_qt_ldadd += $(LIBBITCOIN_UTIL) $(LIBBITCOIN_WALLET) endif @@ -357,7 +357,7 @@ SECONDARY: $(QT_QM) $(srcdir)/qt/bitcoinstrings.cpp: FORCE @test -n $(XGETTEXT) || echo "xgettext is required for updating translations" - $(AM_V_GEN) cd $(srcdir); XGETTEXT=$(XGETTEXT) COPYRIGHT_HOLDERS="$(COPYRIGHT_HOLDERS)" $(PYTHON) ../share/qt/extract_strings_qt.py $(libbitcoin_server_a_SOURCES) $(libbitcoin_wallet_a_SOURCES) $(libbitcoin_common_a_SOURCES) $(libbitcoin_zmq_a_SOURCES) $(libbitcoin_consensus_a_SOURCES) $(libbitcoin_util_a_SOURCES) + $(AM_V_GEN) cd $(srcdir); XGETTEXT=$(XGETTEXT) COPYRIGHT_HOLDERS="$(COPYRIGHT_HOLDERS)" $(PYTHON) ../share/qt/extract_strings_qt.py $(libbitcoin_node_a_SOURCES) $(libbitcoin_wallet_a_SOURCES) $(libbitcoin_common_a_SOURCES) $(libbitcoin_zmq_a_SOURCES) $(libbitcoin_consensus_a_SOURCES) $(libbitcoin_util_a_SOURCES) translate: $(srcdir)/qt/bitcoinstrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(BITCOIN_QT_BASE_CPP) qt/bitcoin.cpp $(BITCOIN_QT_WINDOWS_CPP) $(BITCOIN_QT_WALLET_CPP) $(BITCOIN_QT_H) $(BITCOIN_MM) @test -n $(LUPDATE) || echo "lupdate is required for updating translations" diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include index a0900f2691..b92d2cb6e2 100644 --- a/src/Makefile.qttest.include +++ b/src/Makefile.qttest.include @@ -44,7 +44,7 @@ endif # ENABLE_WALLET nodist_qt_test_test_bitcoin_qt_SOURCES = $(TEST_QT_MOC_CPP) -qt_test_test_bitcoin_qt_LDADD = $(LIBBITCOINQT) $(LIBBITCOIN_SERVER) $(LIBTEST_UTIL) +qt_test_test_bitcoin_qt_LDADD = $(LIBBITCOINQT) $(LIBBITCOIN_NODE) $(LIBTEST_UTIL) if ENABLE_WALLET qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_UTIL) $(LIBBITCOIN_WALLET) endif diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 9fe2a3cf8a..801745d0c6 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -38,7 +38,7 @@ BITCOIN_TEST_SUITE = \ FUZZ_SUITE_LD_COMMON = \ $(LIBTEST_UTIL) \ $(LIBTEST_FUZZ) \ - $(LIBBITCOIN_SERVER) \ + $(LIBBITCOIN_NODE) \ $(LIBBITCOIN_WALLET) \ $(LIBBITCOIN_COMMON) \ $(LIBBITCOIN_UTIL) \ @@ -197,7 +197,7 @@ if ENABLE_WALLET test_test_bitcoin_LDADD += $(LIBBITCOIN_WALLET) endif -test_test_bitcoin_LDADD += $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) \ +test_test_bitcoin_LDADD += $(LIBBITCOIN_NODE) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) \ $(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(EVENT_LIBS) $(EVENT_PTHREADS_LIBS) $(MINISKETCH_LIBS) test_test_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) diff --git a/src/Makefile.test_fuzz.include b/src/Makefile.test_fuzz.include index 2d772f2fca..9574454fd2 100644 --- a/src/Makefile.test_fuzz.include +++ b/src/Makefile.test_fuzz.include @@ -19,7 +19,7 @@ libtest_fuzz_a_SOURCES = \ test/fuzz/util.cpp \ $(TEST_FUZZ_H) -LIBTEST_FUZZ += $(LIBBITCOIN_SERVER) +LIBTEST_FUZZ += $(LIBBITCOIN_NODE) LIBTEST_FUZZ += $(LIBBITCOIN_COMMON) LIBTEST_FUZZ += $(LIBBITCOIN_UTIL) LIBTEST_FUZZ += $(LIBBITCOIN_CRYPTO_BASE) diff --git a/src/Makefile.test_util.include b/src/Makefile.test_util.include index 0a3b99e7d2..92cb8a5ce6 100644 --- a/src/Makefile.test_util.include +++ b/src/Makefile.test_util.include @@ -35,7 +35,7 @@ libtest_util_a_SOURCES = \ test/util/wallet.cpp \ $(TEST_UTIL_H) -LIBTEST_UTIL += $(LIBBITCOIN_SERVER) +LIBTEST_UTIL += $(LIBBITCOIN_NODE) LIBTEST_UTIL += $(LIBBITCOIN_COMMON) LIBTEST_UTIL += $(LIBBITCOIN_UTIL) LIBTEST_UTIL += $(LIBBITCOIN_CRYPTO_BASE) diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 8602e362c8..edec883264 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -630,7 +630,7 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr) } Coin newcoin; newcoin.out.scriptPubKey = scriptPubKey; - newcoin.out.nValue = 0; + newcoin.out.nValue = MAX_MONEY; if (prevOut.exists("amount")) { newcoin.out.nValue = AmountFromValue(prevOut["amount"]); } @@ -669,6 +669,10 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr) if (!fHashSingle || (i < mergedTx.vout.size())) ProduceSignature(keystore, MutableTransactionSignatureCreator(&mergedTx, i, amount, nHashType), prevPubKey, sigdata); + if (amount == MAX_MONEY && !sigdata.scriptWitness.IsNull()) { + throw std::runtime_error(strprintf("Missing amount for CTxOut with scriptPubKey=%s", HexStr(prevPubKey))); + } + UpdateInput(txin, sigdata); } diff --git a/src/blockfilter.cpp b/src/blockfilter.cpp index 68cc6462d0..566254d839 100644 --- a/src/blockfilter.cpp +++ b/src/blockfilter.cpp @@ -24,37 +24,6 @@ static const std::map<BlockFilterType, std::string> g_filter_types = { {BlockFilterType::BASIC, "basic"}, }; -// Map a value x that is uniformly distributed in the range [0, 2^64) to a -// value uniformly distributed in [0, n) by returning the upper 64 bits of -// x * n. -// -// See: https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/ -static uint64_t MapIntoRange(uint64_t x, uint64_t n) -{ -#ifdef __SIZEOF_INT128__ - return (static_cast<unsigned __int128>(x) * static_cast<unsigned __int128>(n)) >> 64; -#else - // To perform the calculation on 64-bit numbers without losing the - // result to overflow, split the numbers into the most significant and - // least significant 32 bits and perform multiplication piece-wise. - // - // See: https://stackoverflow.com/a/26855440 - uint64_t x_hi = x >> 32; - uint64_t x_lo = x & 0xFFFFFFFF; - uint64_t n_hi = n >> 32; - uint64_t n_lo = n & 0xFFFFFFFF; - - uint64_t ac = x_hi * n_hi; - uint64_t ad = x_hi * n_lo; - uint64_t bc = x_lo * n_hi; - uint64_t bd = x_lo * n_lo; - - uint64_t mid34 = (bd >> 32) + (bc & 0xFFFFFFFF) + (ad & 0xFFFFFFFF); - uint64_t upper64 = ac + (bc >> 32) + (ad >> 32) + (mid34 >> 32); - return upper64; -#endif -} - uint64_t GCSFilter::HashToRange(const Element& element) const { uint64_t hash = CSipHasher(m_params.m_siphash_k0, m_params.m_siphash_k1) diff --git a/src/init.cpp b/src/init.cpp index b11eb762f2..ab5a53d6e9 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1404,31 +1404,31 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) uiInterface.InitMessage(_("Loading block index…").translated); const int64_t load_block_index_start_time = GetTimeMillis(); - std::optional<ChainstateLoadingError> rv; + std::optional<ChainstateLoadingError> maybe_load_error; try { - rv = LoadChainstate(fReset, - chainman, - Assert(node.mempool.get()), - fPruneMode, - chainparams.GetConsensus(), - fReindexChainState, - cache_sizes.block_tree_db, - cache_sizes.coins_db, - cache_sizes.coins, - false, - false, - ShutdownRequested, - []() { - uiInterface.ThreadSafeMessageBox( - _("Error reading from database, shutting down."), - "", CClientUIInterface::MSG_ERROR); - }); + maybe_load_error = LoadChainstate(fReset, + chainman, + Assert(node.mempool.get()), + fPruneMode, + chainparams.GetConsensus(), + fReindexChainState, + cache_sizes.block_tree_db, + cache_sizes.coins_db, + cache_sizes.coins, + /*block_tree_db_in_memory=*/false, + /*coins_db_in_memory=*/false, + /*shutdown_requested=*/ShutdownRequested, + /*coins_error_cb=*/[]() { + uiInterface.ThreadSafeMessageBox( + _("Error reading from database, shutting down."), + "", CClientUIInterface::MSG_ERROR); + }); } catch (const std::exception& e) { LogPrintf("%s\n", e.what()); - rv = ChainstateLoadingError::ERROR_GENERIC_BLOCKDB_OPEN_FAILED; + maybe_load_error = ChainstateLoadingError::ERROR_GENERIC_BLOCKDB_OPEN_FAILED; } - if (rv.has_value()) { - switch (rv.value()) { + if (maybe_load_error.has_value()) { + switch (maybe_load_error.value()) { case ChainstateLoadingError::ERROR_LOADING_BLOCK_DB: strLoadError = _("Error loading block database"); break; @@ -1462,7 +1462,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) break; } } else { - std::optional<ChainstateLoadVerifyError> rv2; + std::optional<ChainstateLoadVerifyError> maybe_verify_error; try { uiInterface.InitMessage(_("Verifying blocks…").translated); auto check_blocks = args.GetIntArg("-checkblocks", DEFAULT_CHECKBLOCKS); @@ -1470,19 +1470,19 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) LogPrintf("Prune: pruned datadir may not have more than %d blocks; only checking available blocks\n", MIN_BLOCKS_TO_KEEP); } - rv2 = VerifyLoadedChainstate(chainman, - fReset, - fReindexChainState, - chainparams.GetConsensus(), - check_blocks, - args.GetIntArg("-checklevel", DEFAULT_CHECKLEVEL), - static_cast<int64_t(*)()>(GetTime)); + maybe_verify_error = VerifyLoadedChainstate(chainman, + fReset, + fReindexChainState, + chainparams.GetConsensus(), + check_blocks, + args.GetIntArg("-checklevel", DEFAULT_CHECKLEVEL), + /*get_unix_time_seconds=*/static_cast<int64_t(*)()>(GetTime)); } catch (const std::exception& e) { LogPrintf("%s\n", e.what()); - rv2 = ChainstateLoadVerifyError::ERROR_GENERIC_FAILURE; + maybe_verify_error = ChainstateLoadVerifyError::ERROR_GENERIC_FAILURE; } - if (rv2.has_value()) { - switch (rv2.value()) { + if (maybe_verify_error.has_value()) { + switch (maybe_verify_error.value()) { case ChainstateLoadVerifyError::ERROR_BLOCK_FROM_FUTURE: strLoadError = _("The block database contains a block which appears to be from the future. " "This may be due to your computer's date and time being set incorrectly. " diff --git a/src/net.cpp b/src/net.cpp index 019e77fd7a..89a4aee5d9 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1099,10 +1099,10 @@ bool CConnman::AttemptToEvictConnection() void CConnman::AcceptConnection(const ListenSocket& hListenSocket) { struct sockaddr_storage sockaddr; socklen_t len = sizeof(sockaddr); - SOCKET hSocket = accept(hListenSocket.socket, (struct sockaddr*)&sockaddr, &len); + auto sock = hListenSocket.sock->Accept((struct sockaddr*)&sockaddr, &len); CAddress addr; - if (hSocket == INVALID_SOCKET) { + if (!sock) { const int nErr = WSAGetLastError(); if (nErr != WSAEWOULDBLOCK) { LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr)); @@ -1116,15 +1116,15 @@ void CConnman::AcceptConnection(const ListenSocket& hListenSocket) { addr = CAddress{MaybeFlipIPv6toCJDNS(addr), NODE_NONE}; } - const CAddress addr_bind{MaybeFlipIPv6toCJDNS(GetBindAddress(hSocket)), NODE_NONE}; + const CAddress addr_bind{MaybeFlipIPv6toCJDNS(GetBindAddress(sock->Get())), NODE_NONE}; NetPermissionFlags permissionFlags = NetPermissionFlags::None; hListenSocket.AddSocketPermissionFlags(permissionFlags); - CreateNodeFromAcceptedSocket(hSocket, permissionFlags, addr_bind, addr); + CreateNodeFromAcceptedSocket(std::move(sock), permissionFlags, addr_bind, addr); } -void CConnman::CreateNodeFromAcceptedSocket(SOCKET hSocket, +void CConnman::CreateNodeFromAcceptedSocket(std::unique_ptr<Sock>&& sock, NetPermissionFlags permissionFlags, const CAddress& addr_bind, const CAddress& addr) @@ -1150,27 +1150,24 @@ void CConnman::CreateNodeFromAcceptedSocket(SOCKET hSocket, if (!fNetworkActive) { LogPrint(BCLog::NET, "connection from %s dropped: not accepting new connections\n", addr.ToString()); - CloseSocket(hSocket); return; } - if (!IsSelectableSocket(hSocket)) + if (!IsSelectableSocket(sock->Get())) { LogPrintf("connection from %s dropped: non-selectable socket\n", addr.ToString()); - CloseSocket(hSocket); return; } // According to the internet TCP_NODELAY is not carried into accepted sockets // on all platforms. Set it again here just to be sure. - SetSocketNoDelay(hSocket); + SetSocketNoDelay(sock->Get()); // Don't accept connections from banned peers. bool banned = m_banman && m_banman->IsBanned(addr); if (!NetPermissions::HasFlag(permissionFlags, NetPermissionFlags::NoBan) && banned) { LogPrint(BCLog::NET, "connection from %s dropped (banned)\n", addr.ToString()); - CloseSocket(hSocket); return; } @@ -1179,7 +1176,6 @@ void CConnman::CreateNodeFromAcceptedSocket(SOCKET hSocket, if (!NetPermissions::HasFlag(permissionFlags, NetPermissionFlags::NoBan) && nInbound + 1 >= nMaxInbound && discouraged) { LogPrint(BCLog::NET, "connection from %s dropped (discouraged)\n", addr.ToString()); - CloseSocket(hSocket); return; } @@ -1188,7 +1184,6 @@ void CConnman::CreateNodeFromAcceptedSocket(SOCKET hSocket, if (!AttemptToEvictConnection()) { // No connection to evict, disconnect the new connection LogPrint(BCLog::NET, "failed to find an eviction candidate - connection dropped (full)\n"); - CloseSocket(hSocket); return; } } @@ -1202,7 +1197,7 @@ void CConnman::CreateNodeFromAcceptedSocket(SOCKET hSocket, } const bool inbound_onion = std::find(m_onion_binds.begin(), m_onion_binds.end(), addr_bind) != m_onion_binds.end(); - CNode* pnode = new CNode(id, nodeServices, hSocket, addr, CalculateKeyedNetGroup(addr), nonce, addr_bind, "", ConnectionType::INBOUND, inbound_onion); + CNode* pnode = new CNode(id, nodeServices, sock->Release(), addr, CalculateKeyedNetGroup(addr), nonce, addr_bind, "", ConnectionType::INBOUND, inbound_onion); pnode->AddRef(); pnode->m_permissionFlags = permissionFlags; pnode->m_prefer_evict = discouraged; @@ -1364,7 +1359,7 @@ bool CConnman::GenerateSelectSet(const std::vector<CNode*>& nodes, std::set<SOCKET>& error_set) { for (const ListenSocket& hListenSocket : vhListenSocket) { - recv_set.insert(hListenSocket.socket); + recv_set.insert(hListenSocket.sock->Get()); } for (CNode* pnode : nodes) { @@ -1646,7 +1641,7 @@ void CConnman::SocketHandlerListening(const std::set<SOCKET>& recv_set) if (interruptNet) { return; } - if (recv_set.count(listen_socket.socket) > 0) { + if (recv_set.count(listen_socket.sock->Get()) > 0) { AcceptConnection(listen_socket); } } @@ -2335,7 +2330,7 @@ void CConnman::ThreadI2PAcceptIncoming() continue; } - CreateNodeFromAcceptedSocket(conn.sock->Release(), NetPermissionFlags::None, + CreateNodeFromAcceptedSocket(std::move(conn.sock), NetPermissionFlags::None, CAddress{conn.me, NODE_NONE}, CAddress{conn.peer, NODE_NONE}); } } @@ -2397,7 +2392,7 @@ bool CConnman::BindListenPort(const CService& addrBind, bilingual_str& strError, return false; } - vhListenSocket.push_back(ListenSocket(sock->Release(), permissions)); + vhListenSocket.emplace_back(std::move(sock), permissions); return true; } @@ -2706,15 +2701,6 @@ void CConnman::StopNodes() DeleteNode(pnode); } - // Close listening sockets. - for (ListenSocket& hListenSocket : vhListenSocket) { - if (hListenSocket.socket != INVALID_SOCKET) { - if (!CloseSocket(hListenSocket.socket)) { - LogPrintf("CloseSocket(hListenSocket) failed with error %s\n", NetworkErrorString(WSAGetLastError())); - } - } - } - for (CNode* pnode : m_nodes_disconnected) { DeleteNode(pnode); } @@ -25,6 +25,7 @@ #include <threadinterrupt.h> #include <uint256.h> #include <util/check.h> +#include <util/sock.h> #include <atomic> #include <condition_variable> @@ -947,9 +948,13 @@ public: private: struct ListenSocket { public: - SOCKET socket; + std::shared_ptr<Sock> sock; inline void AddSocketPermissionFlags(NetPermissionFlags& flags) const { NetPermissions::AddFlag(flags, m_permissions); } - ListenSocket(SOCKET socket_, NetPermissionFlags permissions_) : socket(socket_), m_permissions(permissions_) {} + ListenSocket(std::shared_ptr<Sock> sock_, NetPermissionFlags permissions_) + : sock{sock_}, m_permissions{permissions_} + { + } + private: NetPermissionFlags m_permissions; }; @@ -969,12 +974,12 @@ private: /** * Create a `CNode` object from a socket that has just been accepted and add the node to * the `m_nodes` member. - * @param[in] hSocket Connected socket to communicate with the peer. + * @param[in] sock Connected socket to communicate with the peer. * @param[in] permissionFlags The peer's permissions. * @param[in] addr_bind The address and port at our side of the connection. * @param[in] addr The address and port at the peer's side of the connection. */ - void CreateNodeFromAcceptedSocket(SOCKET hSocket, + void CreateNodeFromAcceptedSocket(std::unique_ptr<Sock>&& sock, NetPermissionFlags permissionFlags, const CAddress& addr_bind, const CAddress& addr); diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 51aa498fb0..43843624a1 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -57,14 +57,14 @@ static constexpr auto HEADERS_DOWNLOAD_TIMEOUT_PER_HEADER = 1ms; * behind headers chain. */ static constexpr int32_t MAX_OUTBOUND_PEERS_TO_PROTECT_FROM_DISCONNECT = 4; -/** Timeout for (unprotected) outbound peers to sync to our chainwork, in seconds */ -static constexpr int64_t CHAIN_SYNC_TIMEOUT = 20 * 60; // 20 minutes +/** Timeout for (unprotected) outbound peers to sync to our chainwork */ +static constexpr auto CHAIN_SYNC_TIMEOUT{20min}; /** How frequently to check for stale tips */ static constexpr auto STALE_CHECK_INTERVAL{10min}; /** How frequently to check for extra outbound peers and disconnect */ static constexpr auto EXTRA_PEER_CHECK_INTERVAL{45s}; /** Minimum time an outbound-peer-eviction candidate must be connected for, in order to evict */ -static constexpr std::chrono::seconds MINIMUM_CONNECT_TIME{30}; +static constexpr auto MINIMUM_CONNECT_TIME{30s}; /** SHA256("main address relay")[0:8] */ static constexpr uint64_t RANDOMIZER_ID_ADDRESS_RELAY = 0x3cac0035b5866b90ULL; /// Age after which a stale block will no longer be served if requested as @@ -74,7 +74,7 @@ static constexpr int STALE_RELAY_AGE_LIMIT = 30 * 24 * 60 * 60; /// limiting block relay. Set to one week, denominated in seconds. static constexpr int HISTORICAL_BLOCK_AGE = 7 * 24 * 60 * 60; /** Time between pings automatically sent out for latency probing and keepalive */ -static constexpr std::chrono::minutes PING_INTERVAL{2}; +static constexpr auto PING_INTERVAL{2min}; /** The maximum number of entries in a locator */ static const unsigned int MAX_LOCATOR_SZ = 101; /** The maximum number of entries in an 'inv' protocol message */ @@ -88,19 +88,19 @@ static constexpr int32_t MAX_PEER_TX_REQUEST_IN_FLIGHT = 100; * the actual transaction (from any peer) in response to requests for them. */ static constexpr int32_t MAX_PEER_TX_ANNOUNCEMENTS = 5000; /** How long to delay requesting transactions via txids, if we have wtxid-relaying peers */ -static constexpr auto TXID_RELAY_DELAY = std::chrono::seconds{2}; +static constexpr auto TXID_RELAY_DELAY{2s}; /** How long to delay requesting transactions from non-preferred peers */ -static constexpr auto NONPREF_PEER_TX_DELAY = std::chrono::seconds{2}; +static constexpr auto NONPREF_PEER_TX_DELAY{2s}; /** How long to delay requesting transactions from overloaded peers (see MAX_PEER_TX_REQUEST_IN_FLIGHT). */ -static constexpr auto OVERLOADED_PEER_TX_DELAY = std::chrono::seconds{2}; -/** How long to wait (in microseconds) before downloading a transaction from an additional peer */ -static constexpr std::chrono::microseconds GETDATA_TX_INTERVAL{std::chrono::seconds{60}}; +static constexpr auto OVERLOADED_PEER_TX_DELAY{2s}; +/** How long to wait before downloading a transaction from an additional peer */ +static constexpr auto GETDATA_TX_INTERVAL{60s}; /** Limit to avoid sending big packets. Not used in processing incoming GETDATA for compatibility */ static const unsigned int MAX_GETDATA_SZ = 1000; /** Number of blocks that can be requested at any given time from a single peer. */ static const int MAX_BLOCKS_IN_TRANSIT_PER_PEER = 16; /** Time during which a peer must stall block download progress before being disconnected. */ -static constexpr auto BLOCK_STALLING_TIMEOUT = 2s; +static constexpr auto BLOCK_STALLING_TIMEOUT{2s}; /** Number of headers sent in one getheaders result. We rely on the assumption that if a peer sends * less than this number, we reached its tip. Changing this value is a protocol upgrade. */ static const unsigned int MAX_HEADERS_RESULTS = 2000; @@ -125,16 +125,16 @@ static const int MAX_UNCONNECTING_HEADERS = 10; /** Minimum blocks required to signal NODE_NETWORK_LIMITED */ static const unsigned int NODE_NETWORK_LIMITED_MIN_BLOCKS = 288; /** Average delay between local address broadcasts */ -static constexpr auto AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL = 24h; +static constexpr auto AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL{24h}; /** Average delay between peer address broadcasts */ -static constexpr auto AVG_ADDRESS_BROADCAST_INTERVAL = 30s; +static constexpr auto AVG_ADDRESS_BROADCAST_INTERVAL{30s}; /** Average delay between trickled inventory transmissions for inbound peers. * Blocks and peers with NetPermissionFlags::NoBan permission bypass this. */ -static constexpr auto INBOUND_INVENTORY_BROADCAST_INTERVAL = 5s; +static constexpr auto INBOUND_INVENTORY_BROADCAST_INTERVAL{5s}; /** Average delay between trickled inventory transmissions for outbound peers. * Use a smaller delay as there is less privacy concern for them. * Blocks and peers with NetPermissionFlags::NoBan permission bypass this. */ -static constexpr auto OUTBOUND_INVENTORY_BROADCAST_INTERVAL = 2s; +static constexpr auto OUTBOUND_INVENTORY_BROADCAST_INTERVAL{2s}; /** Maximum rate of inventory items to send per second. * Limits the impact of low-fee transaction floods. */ static constexpr unsigned int INVENTORY_BROADCAST_PER_SECOND = 7; @@ -148,9 +148,9 @@ static constexpr unsigned int INVENTORY_MAX_RECENT_RELAY = 3500; * peers, and random variations in the broadcast mechanism. */ static_assert(INVENTORY_MAX_RECENT_RELAY >= INVENTORY_BROADCAST_PER_SECOND * UNCONDITIONAL_RELAY_DELAY / std::chrono::seconds{1}, "INVENTORY_RELAY_MAX too low"); /** Average delay between feefilter broadcasts in seconds. */ -static constexpr auto AVG_FEEFILTER_BROADCAST_INTERVAL = 10min; +static constexpr auto AVG_FEEFILTER_BROADCAST_INTERVAL{10min}; /** Maximum feefilter broadcast delay after significant change. */ -static constexpr auto MAX_FEEFILTER_CHANGE_DELAY = 5min; +static constexpr auto MAX_FEEFILTER_CHANGE_DELAY{5min}; /** Maximum number of compact filters that may be requested with one getcfilters. See BIP 157. */ static constexpr uint32_t MAX_GETCFILTERS_SIZE = 1000; /** Maximum number of cf hashes that may be requested with one getcfheaders. See BIP 157. */ @@ -329,7 +329,7 @@ private: EXCLUSIVE_LOCKS_REQUIRED(cs_main); /** Consider evicting an outbound peer based on the amount of time they've been behind our tip */ - void ConsiderEviction(CNode& pto, int64_t time_in_seconds) EXCLUSIVE_LOCKS_REQUIRED(cs_main); + void ConsiderEviction(CNode& pto, std::chrono::seconds time_in_seconds) EXCLUSIVE_LOCKS_REQUIRED(cs_main); /** If we have extra outbound peers, try to disconnect the one with the oldest block announcement */ void EvictExtraOutboundPeers(std::chrono::seconds now) EXCLUSIVE_LOCKS_REQUIRED(cs_main); @@ -727,7 +727,7 @@ struct CNodeState { * - its chain tip has at least as much work as ours * * CHAIN_SYNC_TIMEOUT: if a peer's best known block has less work than our tip, - * set a timeout CHAIN_SYNC_TIMEOUT seconds in the future: + * set a timeout CHAIN_SYNC_TIMEOUT in the future: * - If at timeout their best known block now has more work than our tip * when the timeout was set, then either reset the timeout or clear it * (after comparing against our current tip's work) @@ -742,7 +742,7 @@ struct CNodeState { */ struct ChainSyncTimeoutState { //! A timeout used for checking whether our peer has sufficiently synced - int64_t m_timeout{0}; + std::chrono::seconds m_timeout{0s}; //! A header with the work we require on our peer's chain const CBlockIndex* m_work_header{nullptr}; //! After timeout is reached, set to true after sending getheaders @@ -949,10 +949,10 @@ bool PeerManagerImpl::TipMayBeStale() { AssertLockHeld(cs_main); const Consensus::Params& consensusParams = m_chainparams.GetConsensus(); - if (count_seconds(m_last_tip_update) == 0) { + if (m_last_tip_update.load() == 0s) { m_last_tip_update = GetTime<std::chrono::seconds>(); } - return count_seconds(m_last_tip_update) < GetTime() - consensusParams.nPowTargetSpacing * 3 && mapBlocksInFlight.empty(); + return m_last_tip_update.load() < GetTime<std::chrono::seconds>() - std::chrono::seconds{consensusParams.nPowTargetSpacing * 3} && mapBlocksInFlight.empty(); } bool PeerManagerImpl::CanDirectFetch() @@ -1137,7 +1137,7 @@ void PeerManagerImpl::AddTxAnnouncement(const CNode& node, const GenTxid& gtxid, // - TXID_RELAY_DELAY for txid announcements while wtxid peers are available // - OVERLOADED_PEER_TX_DELAY for announcements from peers which have at least // MAX_PEER_TX_REQUEST_IN_FLIGHT requests in flight (and don't have NetPermissionFlags::Relay). - auto delay = std::chrono::microseconds{0}; + auto delay{0us}; const bool preferred = state->fPreferredDownload; if (!preferred) delay += NONPREF_PEER_TX_DELAY; if (!gtxid.IsWtxid() && m_wtxid_relay_peers > 0) delay += TXID_RELAY_DELAY; @@ -1191,7 +1191,7 @@ void PeerManagerImpl::ReattemptInitialBroadcast(CScheduler& scheduler) // Schedule next run for 10-15 minutes in the future. // We add randomness on every cycle to avoid the possibility of P2P fingerprinting. - const std::chrono::milliseconds delta = std::chrono::minutes{10} + GetRandMillis(std::chrono::minutes{5}); + const std::chrono::milliseconds delta = 10min + GetRandMillis(5min); scheduler.scheduleFromNow([&] { ReattemptInitialBroadcast(scheduler); }, delta); } @@ -1296,7 +1296,7 @@ bool PeerManagerImpl::GetNodeStateStats(NodeId nodeid, CNodeStateStats& stats) c // since pingtime does not update until the ping is complete, which might take a while. // So, if a ping is taking an unusually long time in flight, // the caller can immediately detect that this is happening. - std::chrono::microseconds ping_wait{0}; + auto ping_wait{0us}; if ((0 != peer->m_ping_nonce_sent) && (0 != peer->m_ping_start.load().count())) { ping_wait = GetTime<std::chrono::microseconds>() - peer->m_ping_start.load(); } @@ -1496,7 +1496,7 @@ void PeerManagerImpl::StartScheduledTasks(CScheduler& scheduler) scheduler.scheduleEvery([this] { this->CheckForStaleTipAndEvictPeers(); }, std::chrono::seconds{EXTRA_PEER_CHECK_INTERVAL}); // schedule next run for 10-15 minutes in the future - const std::chrono::milliseconds delta = std::chrono::minutes{10} + GetRandMillis(std::chrono::minutes{5}); + const std::chrono::milliseconds delta = 10min + GetRandMillis(5min); scheduler.scheduleFromNow([&] { ReattemptInitialBroadcast(scheduler); }, delta); } @@ -1746,8 +1746,8 @@ void PeerManagerImpl::RelayAddress(NodeId originator, // Relay to a limited number of other nodes // Use deterministic randomness to send to the same nodes for 24 hours // at a time so the m_addr_knowns of the chosen nodes prevent repeats - uint64_t hashAddr = addr.GetHash(); - const CSipHasher hasher = m_connman.GetDeterministicRandomizer(RANDOMIZER_ID_ADDRESS_RELAY).Write(hashAddr << 32).Write((GetTime() + hashAddr) / (24 * 60 * 60)); + const uint64_t hashAddr{addr.GetHash()}; + const CSipHasher hasher{m_connman.GetDeterministicRandomizer(RANDOMIZER_ID_ADDRESS_RELAY).Write(hashAddr).Write((GetTime() + hashAddr) / (24 * 60 * 60))}; FastRandomContext insecure_rand; // Relay reachable addresses to 2 peers. Unreachable addresses are relayed randomly to 1 or 2 peers. @@ -1963,10 +1963,9 @@ void PeerManagerImpl::ProcessGetData(CNode& pfrom, Peer& peer, const std::atomic std::vector<CInv> vNotFound; const CNetMsgMaker msgMaker(pfrom.GetCommonVersion()); - const std::chrono::seconds now = GetTime<std::chrono::seconds>(); + const auto now{GetTime<std::chrono::seconds>()}; // Get last mempool request time - const std::chrono::seconds mempool_req = pfrom.m_tx_relay != nullptr ? pfrom.m_tx_relay->m_last_mempool_req.load() - : std::chrono::seconds::min(); + const auto mempool_req = pfrom.m_tx_relay != nullptr ? pfrom.m_tx_relay->m_last_mempool_req.load() : std::chrono::seconds::min(); // Process as many TX items from the front of the getdata queue as // possible, since they're common and it's efficient to batch process @@ -2890,7 +2889,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type, int64_t nSince = nNow - 10 * 60; // Update/increment addr rate limiting bucket. - const auto current_time = GetTime<std::chrono::microseconds>(); + const auto current_time{GetTime<std::chrono::microseconds>()}; if (peer->m_addr_token_bucket < MAX_ADDR_PROCESSING_TOKEN_BUCKET) { // Don't increment bucket if it's already full const auto time_diff = std::max(current_time - peer->m_addr_token_timestamp, 0us); @@ -2976,7 +2975,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type, LOCK(cs_main); - const auto current_time = GetTime<std::chrono::microseconds>(); + const auto current_time{GetTime<std::chrono::microseconds>()}; uint256* best_block{nullptr}; for (CInv& inv : vInv) { @@ -3354,7 +3353,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type, } } if (!fRejectedParents) { - const auto current_time = GetTime<std::chrono::microseconds>(); + const auto current_time{GetTime<std::chrono::microseconds>()}; for (const uint256& parent_txid : unique_parents) { // Here, we only have the txid (and not wtxid) of the @@ -4180,7 +4179,7 @@ bool PeerManagerImpl::ProcessMessages(CNode* pfrom, std::atomic<bool>& interrupt return fMoreWork; } -void PeerManagerImpl::ConsiderEviction(CNode& pto, int64_t time_in_seconds) +void PeerManagerImpl::ConsiderEviction(CNode& pto, std::chrono::seconds time_in_seconds) { AssertLockHeld(cs_main); @@ -4195,12 +4194,12 @@ void PeerManagerImpl::ConsiderEviction(CNode& pto, int64_t time_in_seconds) // unless it's invalid, in which case we should find that out and // disconnect from them elsewhere). if (state.pindexBestKnownBlock != nullptr && state.pindexBestKnownBlock->nChainWork >= m_chainman.ActiveChain().Tip()->nChainWork) { - if (state.m_chain_sync.m_timeout != 0) { - state.m_chain_sync.m_timeout = 0; + if (state.m_chain_sync.m_timeout != 0s) { + state.m_chain_sync.m_timeout = 0s; state.m_chain_sync.m_work_header = nullptr; state.m_chain_sync.m_sent_getheaders = false; } - } else if (state.m_chain_sync.m_timeout == 0 || (state.m_chain_sync.m_work_header != nullptr && state.pindexBestKnownBlock != nullptr && state.pindexBestKnownBlock->nChainWork >= state.m_chain_sync.m_work_header->nChainWork)) { + } else if (state.m_chain_sync.m_timeout == 0s || (state.m_chain_sync.m_work_header != nullptr && state.pindexBestKnownBlock != nullptr && state.pindexBestKnownBlock->nChainWork >= state.m_chain_sync.m_work_header->nChainWork)) { // Our best block known by this peer is behind our tip, and we're either noticing // that for the first time, OR this peer was able to catch up to some earlier point // where we checked against our tip. @@ -4208,7 +4207,7 @@ void PeerManagerImpl::ConsiderEviction(CNode& pto, int64_t time_in_seconds) state.m_chain_sync.m_timeout = time_in_seconds + CHAIN_SYNC_TIMEOUT; state.m_chain_sync.m_work_header = m_chainman.ActiveChain().Tip(); state.m_chain_sync.m_sent_getheaders = false; - } else if (state.m_chain_sync.m_timeout > 0 && time_in_seconds > state.m_chain_sync.m_timeout) { + } else if (state.m_chain_sync.m_timeout > 0s && time_in_seconds > state.m_chain_sync.m_timeout) { // No evidence yet that our peer has synced to a chain with work equal to that // of our tip, when we first detected it was behind. Send a single getheaders // message to give the peer a chance to update us. @@ -4221,7 +4220,7 @@ void PeerManagerImpl::ConsiderEviction(CNode& pto, int64_t time_in_seconds) LogPrint(BCLog::NET, "sending getheaders to outbound peer=%d to verify chain work (current best known block:%s, benchmark blockhash: %s)\n", pto.GetId(), state.pindexBestKnownBlock != nullptr ? state.pindexBestKnownBlock->GetBlockHash().ToString() : "<none>", state.m_chain_sync.m_work_header->GetBlockHash().ToString()); m_connman.PushMessage(&pto, msgMaker.Make(NetMsgType::GETHEADERS, m_chainman.ActiveChain().GetLocator(state.m_chain_sync.m_work_header->pprev), uint256())); state.m_chain_sync.m_sent_getheaders = true; - constexpr int64_t HEADERS_RESPONSE_TIME = 120; // 2 minutes + constexpr auto HEADERS_RESPONSE_TIME{2min}; // Bump the timeout to allow a response, which could clear the timeout // (if the response shows the peer has synced), reset the timeout (if // the peer syncs to the required work but not to our tip), or result @@ -4348,7 +4347,8 @@ void PeerManagerImpl::CheckForStaleTipAndEvictPeers() // Check whether our tip is stale, and if so, allow using an extra // outbound peer if (!fImporting && !fReindex && m_connman.GetNetworkActive() && m_connman.GetUseAddrmanOutgoing() && TipMayBeStale()) { - LogPrintf("Potential stale tip detected, will try using extra outbound peer (last tip update: %d seconds ago)\n", count_seconds(now) - count_seconds(m_last_tip_update)); + LogPrintf("Potential stale tip detected, will try using extra outbound peer (last tip update: %d seconds ago)\n", + count_seconds(now - m_last_tip_update.load())); m_connman.SetTryNewOutboundPeer(true); } else if (m_connman.GetTryNewOutboundPeer()) { m_connman.SetTryNewOutboundPeer(false); @@ -4570,7 +4570,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto) // If we get here, the outgoing message serialization version is set and can't change. const CNetMsgMaker msgMaker(pto->GetCommonVersion()); - const auto current_time = GetTime<std::chrono::microseconds>(); + const auto current_time{GetTime<std::chrono::microseconds>()}; if (pto->IsAddrFetchConn() && current_time - pto->m_connected > 10 * AVG_ADDRESS_BROADCAST_INTERVAL) { LogPrint(BCLog::NET, "addrfetch connection timeout; disconnecting peer=%d\n", pto->GetId()); @@ -4969,7 +4969,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto) // Check that outbound peers have reasonable chains // GetTime() is used by this anti-DoS logic so we can test this using mocktime - ConsiderEviction(*pto, GetTime()); + ConsiderEviction(*pto, GetTime<std::chrono::seconds>()); // // Message: getdata (blocks) diff --git a/src/node/blockstorage.cpp b/src/node/blockstorage.cpp index cffbf2e3e8..8127ebd769 100644 --- a/src/node/blockstorage.cpp +++ b/src/node/blockstorage.cpp @@ -298,7 +298,7 @@ bool BlockManager::LoadBlockIndex( // because they will still be attached to the active chainstate if they // actually contain more work. // - // Instad of this height-based approach, an earlier attempt was made at + // Instead of this height-based approach, an earlier attempt was made at // detecting "holistically" whether the block index under consideration // relied on an assumed-valid ancestor, but this proved to be too slow to // be practical. diff --git a/src/node/chainstate.cpp b/src/node/chainstate.cpp index abeebad1a6..0274587e17 100644 --- a/src/node/chainstate.cpp +++ b/src/node/chainstate.cpp @@ -141,7 +141,7 @@ std::optional<ChainstateLoadVerifyError> VerifyLoadedChainstate(ChainstateManage for (CChainState* chainstate : chainman.GetAll()) { if (!is_coinsview_empty(chainstate)) { const CBlockIndex* tip = chainstate->m_chain.Tip(); - if (tip && tip->nTime > get_unix_time_seconds() + 2 * 60 * 60) { + if (tip && tip->nTime > get_unix_time_seconds() + MAX_FUTURE_BLOCK_TIME) { return ChainstateLoadVerifyError::ERROR_BLOCK_FROM_FUTURE; } diff --git a/src/node/chainstate.h b/src/node/chainstate.h index 11278a0991..4df917a281 100644 --- a/src/node/chainstate.h +++ b/src/node/chainstate.h @@ -50,7 +50,7 @@ enum class ChainstateLoadingError { * this sequence, when we explicitly checked shutdown_requested() at * arbitrary points, one of those calls returned true". Therefore, a * return value other than SHUTDOWN_PROBED does not guarantee that - * shutdown_requested() hasn't been called indirectly. + * shutdown hasn't been called indirectly. * - else * - Success! */ diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 4cd07c9291..0c83e1d4ae 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2021 The Bitcoin Core developers +// Copyright (c) 2009-2022 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -19,10 +19,10 @@ #include <hash.h> #include <index/blockfilterindex.h> #include <index/coinstatsindex.h> +#include <logging/timer.h> #include <net.h> #include <net_processing.h> #include <node/blockstorage.h> -#include <logging/timer.h> #include <node/coinstats.h> #include <node/context.h> #include <node/utxo_snapshot.h> @@ -1743,7 +1743,7 @@ static RPCHelpMan getmempoolinfo() {RPCResult::Type::NUM, "size", "Current tx count"}, {RPCResult::Type::NUM, "bytes", "Sum of all virtual transaction sizes as defined in BIP 141. Differs from actual serialized size because witness data is discounted"}, {RPCResult::Type::NUM, "usage", "Total memory usage for the mempool"}, - {RPCResult::Type::STR_AMOUNT, "total_fee", "Total fees for the mempool in " + CURRENCY_UNIT + ", ignoring modified fees through prioritizetransaction"}, + {RPCResult::Type::STR_AMOUNT, "total_fee", "Total fees for the mempool in " + CURRENCY_UNIT + ", ignoring modified fees through prioritisetransaction"}, {RPCResult::Type::NUM, "maxmempool", "Maximum memory usage for the mempool"}, {RPCResult::Type::STR_AMOUNT, "mempoolminfee", "Minimum fee rate in " + CURRENCY_UNIT + "/kvB for tx to be accepted. Is the maximum of minrelaytxfee and minimum mempool fee"}, {RPCResult::Type::STR_AMOUNT, "minrelaytxfee", "Current minimum relay fee for transactions"}, diff --git a/src/test/fuzz/golomb_rice.cpp b/src/test/fuzz/golomb_rice.cpp index d6879067b8..2d0b29953c 100644 --- a/src/test/fuzz/golomb_rice.cpp +++ b/src/test/fuzz/golomb_rice.cpp @@ -19,20 +19,6 @@ #include <vector> namespace { -uint64_t MapIntoRange(const uint64_t x, const uint64_t n) -{ - const uint64_t x_hi = x >> 32; - const uint64_t x_lo = x & 0xFFFFFFFF; - const uint64_t n_hi = n >> 32; - const uint64_t n_lo = n & 0xFFFFFFFF; - const uint64_t ac = x_hi * n_hi; - const uint64_t ad = x_hi * n_lo; - const uint64_t bc = x_lo * n_hi; - const uint64_t bd = x_lo * n_lo; - const uint64_t mid34 = (bd >> 32) + (bc & 0xFFFFFFFF) + (ad & 0xFFFFFFFF); - const uint64_t upper64 = ac + (bc >> 32) + (ad >> 32) + (mid34 >> 32); - return upper64; -} uint64_t HashToRange(const std::vector<uint8_t>& element, const uint64_t f) { diff --git a/src/test/fuzz/util.cpp b/src/test/fuzz/util.cpp index 5520eee758..f89b597eed 100644 --- a/src/test/fuzz/util.cpp +++ b/src/test/fuzz/util.cpp @@ -13,6 +13,8 @@ #include <util/time.h> #include <version.h> +#include <memory> + FuzzedSock::FuzzedSock(FuzzedDataProvider& fuzzed_data_provider) : m_fuzzed_data_provider{fuzzed_data_provider} { @@ -158,6 +160,20 @@ int FuzzedSock::Connect(const sockaddr*, socklen_t) const return 0; } +std::unique_ptr<Sock> FuzzedSock::Accept(sockaddr* addr, socklen_t* addr_len) const +{ + constexpr std::array accept_errnos{ + ECONNABORTED, + EINTR, + ENOMEM, + }; + if (m_fuzzed_data_provider.ConsumeBool()) { + SetFuzzedErrNo(m_fuzzed_data_provider, accept_errnos); + return std::unique_ptr<FuzzedSock>(); + } + return std::make_unique<FuzzedSock>(m_fuzzed_data_provider); +} + int FuzzedSock::GetSockOpt(int level, int opt_name, void* opt_val, socklen_t* opt_len) const { constexpr std::array getsockopt_errnos{ diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h index f4f8e9e70d..fd7f40c01d 100644 --- a/src/test/fuzz/util.h +++ b/src/test/fuzz/util.h @@ -401,6 +401,8 @@ public: int Connect(const sockaddr*, socklen_t) const override; + std::unique_ptr<Sock> Accept(sockaddr* addr, socklen_t* addr_len) const override; + int GetSockOpt(int level, int opt_name, void* opt_val, socklen_t* opt_len) const override; bool Wait(std::chrono::milliseconds timeout, Event requested, Event* occurred = nullptr) const override; diff --git a/src/test/util/net.h b/src/test/util/net.h index 006e876c1a..20c45058a1 100644 --- a/src/test/util/net.h +++ b/src/test/util/net.h @@ -13,6 +13,7 @@ #include <array> #include <cassert> #include <cstring> +#include <memory> #include <string> struct ConnmanTestMsg : public CConnman { @@ -126,6 +127,23 @@ public: int Connect(const sockaddr*, socklen_t) const override { return 0; } + std::unique_ptr<Sock> Accept(sockaddr* addr, socklen_t* addr_len) const override + { + if (addr != nullptr) { + // Pretend all connections come from 5.5.5.5:6789 + memset(addr, 0x00, *addr_len); + const socklen_t write_len = static_cast<socklen_t>(sizeof(sockaddr_in)); + if (*addr_len >= write_len) { + *addr_len = write_len; + sockaddr_in* addr_in = reinterpret_cast<sockaddr_in*>(addr); + addr_in->sin_family = AF_INET; + memset(&addr_in->sin_addr, 0x05, sizeof(addr_in->sin_addr)); + addr_in->sin_port = htons(6789); + } + } + return std::make_unique<StaticContentsSock>(""); + }; + int GetSockOpt(int level, int opt_name, void* opt_val, socklen_t* opt_len) const override { std::memset(opt_val, 0x0, *opt_len); diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index 3a37aeb531..c48b2025ad 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -182,28 +182,28 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector<const // instead of unit tests, but for now we need these here. RegisterAllCoreRPCCommands(tableRPC); - auto rv = LoadChainstate(fReindex.load(), - *Assert(m_node.chainman.get()), - Assert(m_node.mempool.get()), - fPruneMode, - chainparams.GetConsensus(), - m_args.GetBoolArg("-reindex-chainstate", false), - m_cache_sizes.block_tree_db, - m_cache_sizes.coins_db, - m_cache_sizes.coins, - true, - true); - assert(!rv.has_value()); - - auto maybe_verify_failure = VerifyLoadedChainstate( + auto maybe_load_error = LoadChainstate(fReindex.load(), + *Assert(m_node.chainman.get()), + Assert(m_node.mempool.get()), + fPruneMode, + chainparams.GetConsensus(), + m_args.GetBoolArg("-reindex-chainstate", false), + m_cache_sizes.block_tree_db, + m_cache_sizes.coins_db, + m_cache_sizes.coins, + /*block_tree_db_in_memory=*/true, + /*coins_db_in_memory=*/true); + assert(!maybe_load_error.has_value()); + + auto maybe_verify_error = VerifyLoadedChainstate( *Assert(m_node.chainman), fReindex.load(), m_args.GetBoolArg("-reindex-chainstate", false), chainparams.GetConsensus(), m_args.GetIntArg("-checkblocks", DEFAULT_CHECKBLOCKS), m_args.GetIntArg("-checklevel", DEFAULT_CHECKLEVEL), - static_cast<int64_t(*)()>(GetTime)); - assert(!maybe_verify_failure.has_value()); + /*get_unix_time_seconds=*/static_cast<int64_t(*)()>(GetTime)); + assert(!maybe_verify_error.has_value()); BlockValidationState state; if (!m_node.chainman->ActiveChainstate().ActivateBestChain(state)) { diff --git a/src/util/golombrice.h b/src/util/golombrice.h index 67d262406f..f14cb594db 100644 --- a/src/util/golombrice.h +++ b/src/util/golombrice.h @@ -40,4 +40,35 @@ uint64_t GolombRiceDecode(BitStreamReader<IStream>& bitreader, uint8_t P) return (q << P) + r; } +// Map a value x that is uniformly distributed in the range [0, 2^64) to a +// value uniformly distributed in [0, n) by returning the upper 64 bits of +// x * n. +// +// See: https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/ +static inline uint64_t MapIntoRange(uint64_t x, uint64_t n) +{ +#ifdef __SIZEOF_INT128__ + return (static_cast<unsigned __int128>(x) * static_cast<unsigned __int128>(n)) >> 64; +#else + // To perform the calculation on 64-bit numbers without losing the + // result to overflow, split the numbers into the most significant and + // least significant 32 bits and perform multiplication piece-wise. + // + // See: https://stackoverflow.com/a/26855440 + const uint64_t x_hi = x >> 32; + const uint64_t x_lo = x & 0xFFFFFFFF; + const uint64_t n_hi = n >> 32; + const uint64_t n_lo = n & 0xFFFFFFFF; + + const uint64_t ac = x_hi * n_hi; + const uint64_t ad = x_hi * n_lo; + const uint64_t bc = x_lo * n_hi; + const uint64_t bd = x_lo * n_lo; + + const uint64_t mid34 = (bd >> 32) + (bc & 0xFFFFFFFF) + (ad & 0xFFFFFFFF); + const uint64_t upper64 = ac + (bc >> 32) + (ad >> 32) + (mid34 >> 32); + return upper64; +#endif +} + #endif // BITCOIN_UTIL_GOLOMBRICE_H diff --git a/src/util/sock.cpp b/src/util/sock.cpp index 1a4d67a65e..2029d70a37 100644 --- a/src/util/sock.cpp +++ b/src/util/sock.cpp @@ -10,6 +10,7 @@ #include <util/system.h> #include <util/time.h> +#include <memory> #include <stdexcept> #include <string> @@ -73,6 +74,32 @@ int Sock::Connect(const sockaddr* addr, socklen_t addr_len) const return connect(m_socket, addr, addr_len); } +std::unique_ptr<Sock> Sock::Accept(sockaddr* addr, socklen_t* addr_len) const +{ +#ifdef WIN32 + static constexpr auto ERR = INVALID_SOCKET; +#else + static constexpr auto ERR = SOCKET_ERROR; +#endif + + std::unique_ptr<Sock> sock; + + const auto socket = accept(m_socket, addr, addr_len); + if (socket != ERR) { + try { + sock = std::make_unique<Sock>(socket); + } catch (const std::exception&) { +#ifdef WIN32 + closesocket(socket); +#else + close(socket); +#endif + } + } + + return sock; +} + int Sock::GetSockOpt(int level, int opt_name, void* opt_val, socklen_t* opt_len) const { return getsockopt(m_socket, level, opt_name, static_cast<char*>(opt_val), opt_len); diff --git a/src/util/sock.h b/src/util/sock.h index 59cc8c0b1d..7510482857 100644 --- a/src/util/sock.h +++ b/src/util/sock.h @@ -10,6 +10,7 @@ #include <util/time.h> #include <chrono> +#include <memory> #include <string> /** @@ -97,6 +98,14 @@ public: [[nodiscard]] virtual int Connect(const sockaddr* addr, socklen_t addr_len) const; /** + * accept(2) wrapper. Equivalent to `std::make_unique<Sock>(accept(this->Get(), addr, addr_len))`. + * Code that uses this wrapper can be unit tested if this method is overridden by a mock Sock + * implementation. + * The returned unique_ptr is empty if `accept()` failed in which case errno will be set. + */ + [[nodiscard]] virtual std::unique_ptr<Sock> Accept(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. diff --git a/src/wallet/dump.cpp b/src/wallet/dump.cpp index 645576ef91..9a4c201c4a 100644 --- a/src/wallet/dump.cpp +++ b/src/wallet/dump.cpp @@ -214,6 +214,11 @@ bool CreateFromDump(const std::string& name, const fs::path& wallet_path, biling if (key == "checksum") { std::vector<unsigned char> parsed_checksum = ParseHex(value); + if (parsed_checksum.size() != checksum.size()) { + error = Untranslated("Error: Checksum is not the correct size"); + ret = false; + break; + } std::copy(parsed_checksum.begin(), parsed_checksum.end(), checksum.begin()); break; } |