diff options
Diffstat (limited to 'src')
114 files changed, 693 insertions, 547 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 713b9a30d1..0b25ef9c6b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -143,6 +143,7 @@ BITCOIN_CORE_H = \ compat/compat.h \ compat/cpuid.h \ compat/endian.h \ + common/system.h \ compressor.h \ consensus/consensus.h \ consensus/tx_check.h \ @@ -186,6 +187,7 @@ BITCOIN_CORE_H = \ kernel/mempool_limits.h \ kernel/mempool_options.h \ kernel/mempool_persist.h \ + kernel/notifications_interface.h \ kernel/validation_cache_sizes.h \ key.h \ key_io.h \ @@ -214,6 +216,7 @@ BITCOIN_CORE_H = \ node/database_args.h \ node/eviction.h \ node/interface_ui.h \ + node/kernel_notifications.h \ node/mempool_args.h \ node/mempool_persist_args.h \ node/miner.h \ @@ -277,7 +280,9 @@ BITCOIN_CORE_H = \ txorphanage.h \ txrequest.h \ undo.h \ + util/any.h \ util/asmap.h \ + util/batchpriority.h \ util/bip32.h \ util/bitdeque.h \ util/bytevectorhash.h \ @@ -294,6 +299,7 @@ BITCOIN_CORE_H = \ util/golombrice.h \ util/hash_type.h \ util/hasher.h \ + util/insert.h \ util/macros.h \ util/message.h \ util/moneystr.h \ @@ -309,7 +315,6 @@ BITCOIN_CORE_H = \ util/string.h \ util/syscall_sandbox.h \ util/syserror.h \ - util/system.h \ util/thread.h \ util/threadinterrupt.h \ util/threadnames.h \ @@ -408,6 +413,7 @@ libbitcoin_node_a_SOURCES = \ node/eviction.cpp \ node/interface_ui.cpp \ node/interfaces.cpp \ + node/kernel_notifications.cpp \ node/mempool_args.cpp \ node/mempool_persist_args.cpp \ node/miner.cpp \ @@ -657,6 +663,7 @@ libbitcoin_common_a_SOURCES = \ common/init.cpp \ common/interfaces.cpp \ common/run_command.cpp \ + common/system.cpp \ compressor.cpp \ core_read.cpp \ core_write.cpp \ @@ -708,6 +715,7 @@ libbitcoin_util_a_SOURCES = \ support/cleanse.cpp \ sync.cpp \ util/asmap.cpp \ + util/batchpriority.cpp \ util/bip32.cpp \ util/bytevectorhash.cpp \ util/chaintype.cpp \ @@ -721,7 +729,6 @@ libbitcoin_util_a_SOURCES = \ util/hasher.cpp \ util/sock.cpp \ util/syserror.cpp \ - util/system.cpp \ util/message.cpp \ util/moneystr.cpp \ util/rbf.cpp \ @@ -960,6 +967,7 @@ libbitcoinkernel_la_SOURCES = \ txdb.cpp \ txmempool.cpp \ uint256.cpp \ + util/batchpriority.cpp \ util/chaintype.cpp \ util/check.cpp \ util/exception.cpp \ @@ -975,7 +983,6 @@ libbitcoinkernel_la_SOURCES = \ util/string.cpp \ util/syscall_sandbox.cpp \ util/syserror.cpp \ - util/system.cpp \ util/thread.cpp \ util/threadnames.cpp \ util/time.cpp \ diff --git a/src/addrdb.cpp b/src/addrdb.cpp index fcb0f0719b..23f9600ea5 100644 --- a/src/addrdb.cpp +++ b/src/addrdb.cpp @@ -210,7 +210,8 @@ util::Result<std::unique_ptr<AddrMan>> LoadAddrman(const NetGroupManager& netgro return util::Error{strprintf(_("Invalid or corrupt peers.dat (%s). If you believe this is a bug, please report it to %s. As a workaround, you can move the file (%s) out of the way (rename, move, or delete) to have a new one created on the next start."), e.what(), PACKAGE_BUGREPORT, fs::quoted(fs::PathToString(path_addr)))}; } - return std::move(addrman); // std::move should be unneccessary but is temporarily needed to work around clang bug (https://github.com/bitcoin/bitcoin/pull/25977#issuecomment-1561270092) + return {std::move(addrman)}; // std::move should be unneccessary but is temporarily needed to work around clang bug + // (https://github.com/bitcoin/bitcoin/pull/25977#issuecomment-1561270092) } void DumpAnchors(const fs::path& anchors_db_path, const std::vector<CAddress>& anchors) diff --git a/src/addrdb.h b/src/addrdb.h index 3da630fff8..0037495d18 100644 --- a/src/addrdb.h +++ b/src/addrdb.h @@ -6,12 +6,11 @@ #ifndef BITCOIN_ADDRDB_H #define BITCOIN_ADDRDB_H -#include <net_types.h> // For banmap_t -#include <univalue.h> +#include <net_types.h> #include <util/fs.h> #include <util/result.h> -#include <optional> +#include <memory> #include <vector> class ArgsManager; @@ -19,7 +18,6 @@ class AddrMan; class CAddress; class CDataStream; class NetGroupManager; -struct bilingual_str; bool DumpPeerAddresses(const ArgsManager& args, const AddrMan& addr); /** Only used by tests. */ diff --git a/src/banman.cpp b/src/banman.cpp index 5b2049d654..a96b7e3c53 100644 --- a/src/banman.cpp +++ b/src/banman.cpp @@ -5,11 +5,11 @@ #include <banman.h> +#include <common/system.h> #include <logging.h> #include <netaddress.h> #include <node/interface_ui.h> #include <sync.h> -#include <util/system.h> #include <util/time.h> #include <util/translation.h> diff --git a/src/bench/addrman.cpp b/src/bench/addrman.cpp index 8a5cab443f..f044feebba 100644 --- a/src/bench/addrman.cpp +++ b/src/bench/addrman.cpp @@ -72,20 +72,6 @@ static void FillAddrMan(AddrMan& addrman) AddAddressesToAddrMan(addrman); } -static CNetAddr ResolveIP(const std::string& ip) -{ - CNetAddr addr; - LookupHost(ip, addr, false); - return addr; -} - -static CService ResolveService(const std::string& ip, uint16_t port = 0) -{ - CService serv; - Lookup(ip, serv, port, false); - return serv; -} - /* Benchmarks */ static void AddrManAdd(benchmark::Bench& bench) @@ -118,8 +104,8 @@ static void AddrManSelectFromAlmostEmpty(benchmark::Bench& bench) AddrMan addrman{EMPTY_NETGROUPMAN, /*deterministic=*/false, ADDRMAN_CONSISTENCY_CHECK_RATIO}; // Add one address to the new table - CService addr = ResolveService("250.3.1.1", 8333); - addrman.Add({CAddress(addr, NODE_NONE)}, ResolveService("250.3.1.1", 8333)); + CService addr = Lookup("250.3.1.1", 8333, false).value(); + addrman.Add({CAddress(addr, NODE_NONE)}, addr); bench.run([&] { (void)addrman.Select(); @@ -135,7 +121,7 @@ static void AddrManSelectByNetwork(benchmark::Bench& bench) i2p_service.SetSpecial("udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna.b32.i2p"); CAddress i2p_address(i2p_service, NODE_NONE); i2p_address.nTime = Now<NodeSeconds>(); - CNetAddr source = ResolveIP("252.2.2.2"); + const CNetAddr source{LookupHost("252.2.2.2", false).value()}; addrman.Add({i2p_address}, source); FillAddrMan(addrman); diff --git a/src/bench/checkqueue.cpp b/src/bench/checkqueue.cpp index 8ad6fde6bf..70e0b86eba 100644 --- a/src/bench/checkqueue.cpp +++ b/src/bench/checkqueue.cpp @@ -4,11 +4,11 @@ #include <bench/bench.h> #include <checkqueue.h> +#include <common/system.h> #include <key.h> #include <prevector.h> #include <pubkey.h> #include <random.h> -#include <util/system.h> #include <vector> diff --git a/src/bench/wallet_balance.cpp b/src/bench/wallet_balance.cpp index 6cf71f4b83..bf2195293e 100644 --- a/src/bench/wallet_balance.cpp +++ b/src/bench/wallet_balance.cpp @@ -15,14 +15,7 @@ #include <optional> -using wallet::CWallet; -using wallet::CreateMockableWalletDatabase; -using wallet::DBErrors; -using wallet::GetBalance; -using wallet::WALLET_FLAG_DESCRIPTORS; - -const std::string ADDRESS_BCRT1_UNSPENDABLE = "bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3xueyj"; - +namespace wallet { static void WalletBalance(benchmark::Bench& bench, const bool set_dirty, const bool add_mine) { const auto test_setup = MakeNoLogFileContext<const TestingSetup>(); @@ -37,7 +30,6 @@ static void WalletBalance(benchmark::Bench& bench, const bool set_dirty, const b LOCK(wallet.cs_wallet); wallet.SetWalletFlag(WALLET_FLAG_DESCRIPTORS); wallet.SetupDescriptorScriptPubKeyMans(); - if (wallet.LoadWallet() != DBErrors::LOAD_OK) assert(false); } auto handler = test_setup->m_node.chain->handleNotifications({&wallet, [](CWallet*) {}}); @@ -67,3 +59,4 @@ BENCHMARK(WalletBalanceDirty, benchmark::PriorityLevel::HIGH); BENCHMARK(WalletBalanceClean, benchmark::PriorityLevel::HIGH); BENCHMARK(WalletBalanceMine, benchmark::PriorityLevel::HIGH); BENCHMARK(WalletBalanceWatch, benchmark::PriorityLevel::HIGH); +} // namespace wallet diff --git a/src/bench/wallet_loading.cpp b/src/bench/wallet_loading.cpp index cf32fde51e..5453238728 100644 --- a/src/bench/wallet_loading.cpp +++ b/src/bench/wallet_loading.cpp @@ -16,32 +16,7 @@ #include <optional> -using wallet::CWallet; -using wallet::CreateMockableWalletDatabase; -using wallet::TxStateInactive; -using wallet::WALLET_FLAG_DESCRIPTORS; -using wallet::WalletContext; -using wallet::WalletDatabase; - -static std::shared_ptr<CWallet> BenchLoadWallet(std::unique_ptr<WalletDatabase> database, WalletContext& context, uint64_t create_flags) -{ - bilingual_str error; - std::vector<bilingual_str> warnings; - auto wallet = CWallet::Create(context, "", std::move(database), create_flags, error, warnings); - NotifyWalletLoaded(context, wallet); - if (context.chain) { - wallet->postInitProcess(); - } - return wallet; -} - -static void BenchUnloadWallet(std::shared_ptr<CWallet>&& wallet) -{ - SyncWithValidationInterfaceQueue(); - wallet->m_chain_notifications_handler.reset(); - UnloadWallet(std::move(wallet)); -} - +namespace wallet{ static void AddTx(CWallet& wallet) { CMutableTransaction mtx; @@ -66,7 +41,7 @@ static void WalletLoading(benchmark::Bench& bench, bool legacy_wallet) create_flags = WALLET_FLAG_DESCRIPTORS; } auto database = CreateMockableWalletDatabase(); - auto wallet = BenchLoadWallet(std::move(database), context, create_flags); + auto wallet = TestLoadWallet(std::move(database), context, create_flags); // Generate a bunch of transactions and addresses to put into the wallet for (int i = 0; i < 1000; ++i) { @@ -76,14 +51,14 @@ static void WalletLoading(benchmark::Bench& bench, bool legacy_wallet) database = DuplicateMockDatabase(wallet->GetDatabase()); // reload the wallet for the actual benchmark - BenchUnloadWallet(std::move(wallet)); + TestUnloadWallet(std::move(wallet)); bench.epochs(5).run([&] { - wallet = BenchLoadWallet(std::move(database), context, create_flags); + wallet = TestLoadWallet(std::move(database), context, create_flags); // Cleanup database = DuplicateMockDatabase(wallet->GetDatabase()); - BenchUnloadWallet(std::move(wallet)); + TestUnloadWallet(std::move(wallet)); }); } @@ -96,3 +71,4 @@ BENCHMARK(WalletLoadingLegacy, benchmark::PriorityLevel::HIGH); static void WalletLoadingDescriptors(benchmark::Bench& bench) { WalletLoading(bench, /*legacy_wallet=*/false); } BENCHMARK(WalletLoadingDescriptors, benchmark::PriorityLevel::HIGH); #endif +} // namespace wallet diff --git a/src/bitcoin-chainstate.cpp b/src/bitcoin-chainstate.cpp index c143385d13..5678d4a526 100644 --- a/src/bitcoin-chainstate.cpp +++ b/src/bitcoin-chainstate.cpp @@ -12,6 +12,7 @@ // It is part of the libbitcoinkernel project. #include <kernel/chainparams.h> +#include <kernel/chainstatemanager_opts.h> #include <kernel/checks.h> #include <kernel/context.h> #include <kernel/validation_cache_sizes.h> @@ -31,9 +32,12 @@ #include <validationinterface.h> #include <cassert> +#include <cstdint> #include <filesystem> #include <functional> #include <iosfwd> +#include <memory> +#include <string> int main(int argc, char* argv[]) { @@ -80,12 +84,34 @@ int main(int argc, char* argv[]) GetMainSignals().RegisterBackgroundSignalScheduler(scheduler); + class KernelNotifications : public kernel::Notifications + { + public: + void blockTip(SynchronizationState, CBlockIndex&) override + { + std::cout << "Block tip changed" << std::endl; + } + void headerTip(SynchronizationState, int64_t height, int64_t timestamp, bool presync) override + { + std::cout << "Header tip changed: " << height << ", " << timestamp << ", " << presync << std::endl; + } + void progress(const bilingual_str& title, int progress_percent, bool resume_possible) override + { + std::cout << "Progress: " << title.original << ", " << progress_percent << ", " << resume_possible << std::endl; + } + void warning(const bilingual_str& warning) override + { + std::cout << "Warning: " << warning.original << std::endl; + } + }; + auto notifications = std::make_unique<KernelNotifications>(); // SETUP: Chainstate const ChainstateManager::Options chainman_opts{ .chainparams = *chainparams, .datadir = gArgs.GetDataDirNet(), .adjusted_time_callback = NodeClock::now, + .notifications = *notifications, }; const node::BlockManager::Options blockman_opts{ .chainparams = chainman_opts.chainparams, diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 48dc11b95a..45db7a9a66 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -10,6 +10,7 @@ #include <chainparamsbase.h> #include <clientversion.h> #include <common/args.h> +#include <common/system.h> #include <common/url.h> #include <compat/compat.h> #include <compat/stdin.h> @@ -23,7 +24,6 @@ #include <util/chaintype.h> #include <util/exception.h> #include <util/strencodings.h> -#include <util/system.h> #include <util/time.h> #include <util/translation.h> diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index e291f20a11..0c25ddf373 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -10,6 +10,7 @@ #include <clientversion.h> #include <coins.h> #include <common/args.h> +#include <common/system.h> #include <compat/compat.h> #include <consensus/amount.h> #include <consensus/consensus.h> @@ -27,7 +28,6 @@ #include <util/rbf.h> #include <util/strencodings.h> #include <util/string.h> -#include <util/system.h> #include <util/translation.h> #include <cstdio> diff --git a/src/bitcoin-util.cpp b/src/bitcoin-util.cpp index f62a9f7bbf..582c18c9c6 100644 --- a/src/bitcoin-util.cpp +++ b/src/bitcoin-util.cpp @@ -12,11 +12,11 @@ #include <chainparamsbase.h> #include <clientversion.h> #include <common/args.h> +#include <common/system.h> #include <compat/compat.h> #include <core_io.h> #include <streams.h> #include <util/exception.h> -#include <util/system.h> #include <util/translation.h> #include <version.h> diff --git a/src/bitcoin-wallet.cpp b/src/bitcoin-wallet.cpp index 1863173aa8..d5dfbbec27 100644 --- a/src/bitcoin-wallet.cpp +++ b/src/bitcoin-wallet.cpp @@ -10,6 +10,7 @@ #include <chainparamsbase.h> #include <clientversion.h> #include <common/args.h> +#include <common/system.h> #include <common/url.h> #include <compat/compat.h> #include <interfaces/init.h> @@ -18,7 +19,6 @@ #include <pubkey.h> #include <tinyformat.h> #include <util/exception.h> -#include <util/system.h> #include <util/translation.h> #include <wallet/wallettool.h> diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index e476b06017..aefb130e9c 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -11,6 +11,7 @@ #include <clientversion.h> #include <common/args.h> #include <common/init.h> +#include <common/system.h> #include <common/url.h> #include <compat/compat.h> #include <init.h> @@ -25,7 +26,6 @@ #include <util/strencodings.h> #include <util/syscall_sandbox.h> #include <util/syserror.h> -#include <util/system.h> #include <util/threadnames.h> #include <util/tokenpipe.h> #include <util/translation.h> diff --git a/src/blockencodings.cpp b/src/blockencodings.cpp index a29e4f794e..9aa0a6ba20 100644 --- a/src/blockencodings.cpp +++ b/src/blockencodings.cpp @@ -3,16 +3,16 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <blockencodings.h> +#include <chainparams.h> +#include <common/system.h> #include <consensus/consensus.h> #include <consensus/validation.h> -#include <chainparams.h> #include <crypto/sha256.h> #include <crypto/siphash.h> #include <random.h> #include <streams.h> #include <txmempool.h> #include <validation.h> -#include <util/system.h> #include <unordered_map> diff --git a/src/util/system.cpp b/src/common/system.cpp index 598e6adb88..1d1c5fa56a 100644 --- a/src/util/system.cpp +++ b/src/common/system.cpp @@ -3,20 +3,13 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include <util/system.h> +#include <common/system.h> #include <logging.h> #include <util/string.h> -#include <util/syserror.h> #include <util/time.h> -#if (defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)) -#include <pthread.h> -#include <pthread_np.h> -#endif - #ifndef WIN32 -#include <sched.h> #include <sys/stat.h> #else #include <codecvt> @@ -112,14 +105,3 @@ int64_t GetStartupTime() { return nStartupTime; } - -void ScheduleBatchPriority() -{ -#ifdef SCHED_BATCH - const static sched_param param{}; - const int rc = pthread_setschedparam(pthread_self(), SCHED_BATCH, ¶m); - if (rc != 0) { - LogPrintf("Failed to pthread_setschedparam: %s\n", SysErrorString(rc)); - } -#endif -} diff --git a/src/common/system.h b/src/common/system.h new file mode 100644 index 0000000000..40206aaa01 --- /dev/null +++ b/src/common/system.h @@ -0,0 +1,38 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// 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. + +#ifndef BITCOIN_COMMON_SYSTEM_H +#define BITCOIN_COMMON_SYSTEM_H + +#if defined(HAVE_CONFIG_H) +#include <config/bitcoin-config.h> +#endif + +#include <compat/assumptions.h> +#include <compat/compat.h> + +#include <set> +#include <stdint.h> +#include <string> + +// Application startup time (used for uptime calculation) +int64_t GetStartupTime(); + +void SetupEnvironment(); +bool SetupNetworking(); +#ifndef WIN32 +std::string ShellEscape(const std::string& arg); +#endif +#if HAVE_SYSTEM +void runCommand(const std::string& strCommand); +#endif + +/** + * Return the number of cores available on the current system. + * @note This does count virtual cores, such as those provided by HyperThreading. + */ +int GetNumCores(); + +#endif // BITCOIN_COMMON_SYSTEM_H diff --git a/src/core_write.cpp b/src/core_write.cpp index b0e3b0b3c4..54ca306f60 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -4,6 +4,7 @@ #include <core_io.h> +#include <common/system.h> #include <consensus/amount.h> #include <consensus/consensus.h> #include <consensus/validation.h> @@ -17,7 +18,6 @@ #include <univalue.h> #include <util/check.h> #include <util/strencodings.h> -#include <util/system.h> #include <map> #include <string> diff --git a/src/external_signer.h b/src/external_signer.h index 90f07478e3..81a601811a 100644 --- a/src/external_signer.h +++ b/src/external_signer.h @@ -5,8 +5,8 @@ #ifndef BITCOIN_EXTERNAL_SIGNER_H #define BITCOIN_EXTERNAL_SIGNER_H +#include <common/system.h> #include <univalue.h> -#include <util/system.h> #include <string> #include <vector> diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 4f8a2b4d8d..128c4e3c56 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -170,12 +170,8 @@ static bool ClientAllowed(const CNetAddr& netaddr) static bool InitHTTPAllowList() { rpc_allow_subnets.clear(); - CNetAddr localv4; - CNetAddr localv6; - LookupHost("127.0.0.1", localv4, false); - LookupHost("::1", localv6, false); - rpc_allow_subnets.push_back(CSubNet(localv4, 8)); // always allow IPv4 local subnet - rpc_allow_subnets.push_back(CSubNet(localv6)); // always allow IPv6 localhost + rpc_allow_subnets.push_back(CSubNet{LookupHost("127.0.0.1", false).value(), 8}); // always allow IPv4 local subnet + rpc_allow_subnets.push_back(CSubNet{LookupHost("::1", false).value()}); // always allow IPv6 localhost for (const std::string& strAllow : gArgs.GetArgs("-rpcallowip")) { CSubNet subnet; LookupSubNet(strAllow, subnet); @@ -338,8 +334,8 @@ static bool HTTPBindAddresses(struct evhttp* http) LogPrintf("Binding RPC on address %s port %i\n", i->first, i->second); evhttp_bound_socket *bind_handle = evhttp_bind_socket_with_handle(http, i->first.empty() ? nullptr : i->first.c_str(), i->second); if (bind_handle) { - CNetAddr addr; - if (i->first.empty() || (LookupHost(i->first, addr, false) && addr.IsBindAny())) { + const std::optional<CNetAddr> addr{LookupHost(i->first, false)}; + if (i->first.empty() || (addr.has_value() && addr->IsBindAny())) { LogPrintf("WARNING: the RPC server is not safe to expose to untrusted networks such as the public internet\n"); } boundSockets.push_back(bind_handle); diff --git a/src/i2p.cpp b/src/i2p.cpp index c67b6ed185..f03e375adf 100644 --- a/src/i2p.cpp +++ b/src/i2p.cpp @@ -336,7 +336,7 @@ void Session::GenerateAndSavePrivateKey(const Sock& sock) { DestGenerate(sock); - // umask is set to 0077 in util/system.cpp, which is ok. + // umask is set to 0077 in common/system.cpp, which is ok. if (!WriteBinaryFile(m_private_key_file, std::string(m_private_key.begin(), m_private_key.end()))) { throw std::runtime_error( diff --git a/src/init.cpp b/src/init.cpp index 1ae21ec8d2..e8c804b9a7 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -20,6 +20,7 @@ #include <chainparams.h> #include <chainparamsbase.h> #include <common/args.h> +#include <common/system.h> #include <consensus/amount.h> #include <deploymentstatus.h> #include <hash.h> @@ -45,6 +46,7 @@ #include <node/chainstatemanager_args.h> #include <node/context.h> #include <node/interface_ui.h> +#include <node/kernel_notifications.h> #include <node/mempool_args.h> #include <node/mempool_persist_args.h> #include <node/miner.h> @@ -79,7 +81,6 @@ #include <util/string.h> #include <util/syscall_sandbox.h> #include <util/syserror.h> -#include <util/system.h> #include <util/thread.h> #include <util/threadnames.h> #include <util/translation.h> @@ -124,6 +125,7 @@ using node::DEFAULT_PERSIST_MEMPOOL; using node::DEFAULT_PRINTPRIORITY; using node::fReindex; using node::g_indexes_ready_to_sync; +using node::KernelNotifications; using node::LoadChainstate; using node::MempoolPath; using node::NodeContext; @@ -1020,9 +1022,11 @@ bool AppInitParameterInteraction(const ArgsManager& args, bool use_syscall_sandb // Also report errors from parsing before daemonization { + KernelNotifications notifications{}; ChainstateManager::Options chainman_opts_dummy{ .chainparams = chainparams, .datadir = args.GetDataDirNet(), + .notifications = notifications, }; auto chainman_result{ApplyArgsManOptions(args, chainman_opts_dummy)}; if (!chainman_result) { @@ -1355,12 +1359,12 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) // -noproxy (or -proxy=0) as well as the empty string can be used to not set a proxy, this is the default std::string proxyArg = args.GetArg("-proxy", ""); if (proxyArg != "" && proxyArg != "0") { - CService proxyAddr; - if (!Lookup(proxyArg, proxyAddr, 9050, fNameLookup)) { + const std::optional<CService> proxyAddr{Lookup(proxyArg, 9050, fNameLookup)}; + if (!proxyAddr.has_value()) { return InitError(strprintf(_("Invalid -proxy address or hostname: '%s'"), proxyArg)); } - Proxy addrProxy = Proxy(proxyAddr, proxyRandomize); + Proxy addrProxy = Proxy(proxyAddr.value(), proxyRandomize); if (!addrProxy.IsValid()) return InitError(strprintf(_("Invalid -proxy address or hostname: '%s'"), proxyArg)); @@ -1386,11 +1390,11 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) "reaching the Tor network is explicitly forbidden: -onion=0")); } } else { - CService addr; - if (!Lookup(onionArg, addr, 9050, fNameLookup) || !addr.IsValid()) { + const std::optional<CService> addr{Lookup(onionArg, 9050, fNameLookup)}; + if (!addr.has_value() || !addr->IsValid()) { return InitError(strprintf(_("Invalid -onion address or hostname: '%s'"), onionArg)); } - onion_proxy = Proxy{addr, proxyRandomize}; + onion_proxy = Proxy{addr.value(), proxyRandomize}; } } @@ -1410,9 +1414,9 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) } for (const std::string& strAddr : args.GetArgs("-externalip")) { - CService addrLocal; - if (Lookup(strAddr, addrLocal, GetListenPort(), fNameLookup) && addrLocal.IsValid()) - AddLocal(addrLocal, LOCAL_MANUAL); + const std::optional<CService> addrLocal{Lookup(strAddr, GetListenPort(), fNameLookup)}; + if (addrLocal.has_value() && addrLocal->IsValid()) + AddLocal(addrLocal.value(), LOCAL_MANUAL); else return InitError(ResolveErrMsg("externalip", strAddr)); } @@ -1431,12 +1435,14 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) // ********************************************************* Step 7: load block chain + node.notifications = std::make_unique<KernelNotifications>(); fReindex = args.GetBoolArg("-reindex", false); bool fReindexChainState = args.GetBoolArg("-reindex-chainstate", false); ChainstateManager::Options chainman_opts{ .chainparams = chainparams, .datadir = args.GetDataDirNet(), .adjusted_time_callback = GetAdjustedTime, + .notifications = *node.notifications, }; Assert(ApplyArgsManOptions(args, chainman_opts)); // no error can happen, already checked in AppInitParameterInteraction @@ -1748,13 +1754,14 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) }; for (const std::string& bind_arg : args.GetArgs("-bind")) { - CService bind_addr; + std::optional<CService> bind_addr; const size_t index = bind_arg.rfind('='); if (index == std::string::npos) { - if (Lookup(bind_arg, bind_addr, default_bind_port, /*fAllowLookup=*/false)) { - connOptions.vBinds.push_back(bind_addr); - if (IsBadPort(bind_addr.GetPort())) { - InitWarning(BadPortWarning("-bind", bind_addr.GetPort())); + bind_addr = Lookup(bind_arg, default_bind_port, /*fAllowLookup=*/false); + if (bind_addr.has_value()) { + connOptions.vBinds.push_back(bind_addr.value()); + if (IsBadPort(bind_addr.value().GetPort())) { + InitWarning(BadPortWarning("-bind", bind_addr.value().GetPort())); } continue; } @@ -1762,8 +1769,9 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) const std::string network_type = bind_arg.substr(index + 1); if (network_type == "onion") { const std::string truncated_bind_arg = bind_arg.substr(0, index); - if (Lookup(truncated_bind_arg, bind_addr, BaseParams().OnionServiceTargetPort(), false)) { - connOptions.onion_binds.push_back(bind_addr); + bind_addr = Lookup(truncated_bind_arg, BaseParams().OnionServiceTargetPort(), false); + if (bind_addr.has_value()) { + connOptions.onion_binds.push_back(bind_addr.value()); continue; } } @@ -1841,11 +1849,11 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) const std::string& i2psam_arg = args.GetArg("-i2psam", ""); if (!i2psam_arg.empty()) { - CService addr; - if (!Lookup(i2psam_arg, addr, 7656, fNameLookup) || !addr.IsValid()) { + const std::optional<CService> addr{Lookup(i2psam_arg, 7656, fNameLookup)}; + if (!addr.has_value() || !addr->IsValid()) { return InitError(strprintf(_("Invalid -i2psam address or hostname: '%s'"), i2psam_arg)); } - SetProxy(NET_I2P, Proxy{addr}); + SetProxy(NET_I2P, Proxy{addr.value()}); } else { if (args.IsArgSet("-onlynet") && IsReachable(NET_I2P)) { return InitError( diff --git a/src/ipc/interfaces.cpp b/src/ipc/interfaces.cpp index d804d9d291..e446cc98db 100644 --- a/src/ipc/interfaces.cpp +++ b/src/ipc/interfaces.cpp @@ -2,6 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <common/system.h> #include <interfaces/init.h> #include <interfaces/ipc.h> #include <ipc/capnp/protocol.h> @@ -10,7 +11,6 @@ #include <logging.h> #include <tinyformat.h> #include <util/fs.h> -#include <util/system.h> #include <cstdio> #include <cstdlib> diff --git a/src/kernel/chainstatemanager_opts.h b/src/kernel/chainstatemanager_opts.h index 2395f60164..917f7d226c 100644 --- a/src/kernel/chainstatemanager_opts.h +++ b/src/kernel/chainstatemanager_opts.h @@ -5,6 +5,8 @@ #ifndef BITCOIN_KERNEL_CHAINSTATEMANAGER_OPTS_H #define BITCOIN_KERNEL_CHAINSTATEMANAGER_OPTS_H +#include <kernel/notifications_interface.h> + #include <arith_uint256.h> #include <dbwrapper.h> #include <txdb.h> @@ -42,6 +44,7 @@ struct ChainstateManagerOpts { DBOptions block_tree_db{}; DBOptions coins_db{}; CoinsViewOptions coins_view{}; + Notifications& notifications; }; } // namespace kernel diff --git a/src/kernel/checks.h b/src/kernel/checks.h index 8cff4e3be4..fd8c167015 100644 --- a/src/kernel/checks.h +++ b/src/kernel/checks.h @@ -7,8 +7,6 @@ #include <util/result.h> -struct bilingual_str; - namespace kernel { struct Context; @@ -16,8 +14,7 @@ struct Context; /** * Ensure a usable environment with all necessary library support. */ -util::Result<void> SanityChecks(const Context&); - -} +[[nodiscard]] util::Result<void> SanityChecks(const Context&); +} // namespace kernel #endif // BITCOIN_KERNEL_CHECKS_H diff --git a/src/kernel/notifications_interface.h b/src/kernel/notifications_interface.h new file mode 100644 index 0000000000..48248e9aa0 --- /dev/null +++ b/src/kernel/notifications_interface.h @@ -0,0 +1,33 @@ +// Copyright (c) 2023 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_KERNEL_NOTIFICATIONS_INTERFACE_H +#define BITCOIN_KERNEL_NOTIFICATIONS_INTERFACE_H + +#include <cstdint> +#include <string> + +class CBlockIndex; +enum class SynchronizationState; +struct bilingual_str; + +namespace kernel { + +/** + * A base class defining functions for notifying about certain kernel + * events. + */ +class Notifications +{ +public: + virtual ~Notifications(){}; + + virtual void blockTip(SynchronizationState state, CBlockIndex& index) {} + virtual void headerTip(SynchronizationState state, int64_t height, int64_t timestamp, bool presync) {} + virtual void progress(const bilingual_str& title, int progress_percent, bool resume_possible) {} + virtual void warning(const bilingual_str& warning) {} +}; +} // namespace kernel + +#endif // BITCOIN_KERNEL_NOTIFICATIONS_INTERFACE_H diff --git a/src/mapport.cpp b/src/mapport.cpp index 994fd12cf5..118827901a 100644 --- a/src/mapport.cpp +++ b/src/mapport.cpp @@ -9,12 +9,12 @@ #include <mapport.h> #include <clientversion.h> +#include <common/system.h> #include <logging.h> #include <net.h> #include <netaddress.h> #include <netbase.h> #include <util/syscall_sandbox.h> -#include <util/system.h> #include <util/thread.h> #include <util/threadinterrupt.h> @@ -175,10 +175,10 @@ static bool ProcessUpnp() LogPrintf("UPnP: GetExternalIPAddress() returned %d\n", r); } else { if (externalIPAddress[0]) { - CNetAddr resolved; - if (LookupHost(externalIPAddress, resolved, false)) { - LogPrintf("UPnP: ExternalIPAddress = %s\n", resolved.ToStringAddr()); - AddLocal(resolved, LOCAL_MAPPED); + std::optional<CNetAddr> resolved{LookupHost(externalIPAddress, false)}; + if (resolved.has_value()) { + LogPrintf("UPnP: ExternalIPAddress = %s\n", resolved->ToStringAddr()); + AddLocal(resolved.value(), LOCAL_MAPPED); } } else { LogPrintf("UPnP: GetExternalIPAddress failed.\n"); diff --git a/src/net.cpp b/src/net.cpp index 337cf60680..a53835f999 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -130,14 +130,10 @@ uint16_t GetListenPort() { // If -bind= is provided with ":port" part, use that (first one if multiple are provided). for (const std::string& bind_arg : gArgs.GetArgs("-bind")) { - CService bind_addr; constexpr uint16_t dummy_port = 0; - if (Lookup(bind_arg, bind_addr, dummy_port, /*fAllowLookup=*/false)) { - if (bind_addr.GetPort() != dummy_port) { - return bind_addr.GetPort(); - } - } + const std::optional<CService> bind_addr{Lookup(bind_arg, dummy_port, /*fAllowLookup=*/false)}; + if (bind_addr.has_value() && bind_addr->GetPort() != dummy_port) return bind_addr->GetPort(); } // Otherwise, if -whitebind= without NetPermissionFlags::NoBan is provided, use that @@ -461,9 +457,9 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo const uint16_t default_port{pszDest != nullptr ? Params().GetDefaultPort(pszDest) : Params().GetDefaultPort()}; if (pszDest) { - std::vector<CService> resolved; - if (Lookup(pszDest, resolved, default_port, fNameLookup && !HaveNameProxy(), 256) && !resolved.empty()) { - const CService rnd{resolved[GetRand(resolved.size())]}; + const std::vector<CService> resolved{Lookup(pszDest, default_port, fNameLookup && !HaveNameProxy(), 256)}; + if (!resolved.empty()) { + const CService& rnd{resolved[GetRand(resolved.size())]}; addrConnect = CAddress{MaybeFlipIPv6toCJDNS(rnd), NODE_NONE}; if (!addrConnect.IsValid()) { LogPrint(BCLog::NET, "Resolver returned invalid address %s for %s\n", addrConnect.ToStringAddrPort(), pszDest); @@ -1487,7 +1483,6 @@ void CConnman::ThreadDNSAddressSeed() if (HaveNameProxy()) { AddAddrFetch(seed); } else { - std::vector<CNetAddr> vIPs; std::vector<CAddress> vAdd; ServiceFlags requiredServiceBits = GetDesirableServiceFlags(NODE_NONE); std::string host = strprintf("x%x.%s", requiredServiceBits, seed); @@ -1496,8 +1491,9 @@ void CConnman::ThreadDNSAddressSeed() continue; } unsigned int nMaxIPs = 256; // Limits number of IPs learned from a DNS seed - if (LookupHost(host, vIPs, nMaxIPs, true)) { - for (const CNetAddr& ip : vIPs) { + const auto addresses{LookupHost(host, nMaxIPs, true)}; + if (!addresses.empty()) { + for (const CNetAddr& ip : addresses) { CAddress addr = CAddress(CService(ip, Params().GetDefaultPort()), requiredServiceBits); addr.nTime = rng.rand_uniform_delay(Now<NodeSeconds>() - 3 * 24h, -4 * 24h); // use a random age between 3 and 7 days old vAdd.push_back(addr); @@ -2201,14 +2197,11 @@ void Discover() char pszHostName[256] = ""; if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR) { - std::vector<CNetAddr> vaddr; - if (LookupHost(pszHostName, vaddr, 0, true)) + const std::vector<CNetAddr> addresses{LookupHost(pszHostName, 0, true)}; + for (const CNetAddr& addr : addresses) { - for (const CNetAddr &addr : vaddr) - { - if (AddLocal(addr, LOCAL_IF)) - LogPrintf("%s: %s - %s\n", __func__, pszHostName, addr.ToStringAddr()); - } + if (AddLocal(addr, LOCAL_IF)) + LogPrintf("%s: %s - %s\n", __func__, pszHostName, addr.ToStringAddr()); } } #elif (HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS) diff --git a/src/net_permissions.cpp b/src/net_permissions.cpp index f829e56aa2..23226bbb4f 100644 --- a/src/net_permissions.cpp +++ b/src/net_permissions.cpp @@ -2,10 +2,10 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <common/system.h> #include <net_permissions.h> #include <netbase.h> #include <util/error.h> -#include <util/system.h> #include <util/translation.h> const std::vector<std::string> NET_PERMISSIONS_DOC{ @@ -88,18 +88,18 @@ bool NetWhitebindPermissions::TryParse(const std::string& str, NetWhitebindPermi if (!TryParsePermissionFlags(str, flags, offset, error)) return false; const std::string strBind = str.substr(offset); - CService addrBind; - if (!Lookup(strBind, addrBind, 0, false)) { + const std::optional<CService> addrBind{Lookup(strBind, 0, false)}; + if (!addrBind.has_value()) { error = ResolveErrMsg("whitebind", strBind); return false; } - if (addrBind.GetPort() == 0) { + if (addrBind.value().GetPort() == 0) { error = strprintf(_("Need to specify a port with -whitebind: '%s'"), strBind); return false; } output.m_flags = flags; - output.m_service = addrBind; + output.m_service = addrBind.value(); error = Untranslated(""); return true; } diff --git a/src/netbase.cpp b/src/netbase.cpp index 4f78d2e31a..8f6f92ea7d 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -132,14 +132,9 @@ std::vector<std::string> GetNetworkNames(bool append_unroutable) return names; } -static bool LookupIntern(const std::string& name, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup, DNSLookupFn dns_lookup_function) +static std::vector<CNetAddr> LookupIntern(const std::string& name, unsigned int nMaxSolutions, bool fAllowLookup, DNSLookupFn dns_lookup_function) { - vIP.clear(); - - if (!ContainsNoNUL(name)) { - return false; - } - + if (!ContainsNoNUL(name)) return {}; { CNetAddr addr; // From our perspective, onion addresses are not hostnames but rather @@ -148,83 +143,65 @@ static bool LookupIntern(const std::string& name, std::vector<CNetAddr>& vIP, un // getaddrinfo to decode them and it wouldn't make sense to resolve // them, we return a network address representing it instead. See // CNetAddr::SetSpecial(const std::string&) for more details. - if (addr.SetSpecial(name)) { - vIP.push_back(addr); - return true; - } + if (addr.SetSpecial(name)) return {addr}; } + std::vector<CNetAddr> addresses; + for (const CNetAddr& resolved : dns_lookup_function(name, fAllowLookup)) { - if (nMaxSolutions > 0 && vIP.size() >= nMaxSolutions) { + if (nMaxSolutions > 0 && addresses.size() >= nMaxSolutions) { break; } /* Never allow resolving to an internal address. Consider any such result invalid */ if (!resolved.IsInternal()) { - vIP.push_back(resolved); + addresses.push_back(resolved); } } - return (vIP.size() > 0); + return addresses; } -bool LookupHost(const std::string& name, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup, DNSLookupFn dns_lookup_function) +std::vector<CNetAddr> LookupHost(const std::string& name, unsigned int nMaxSolutions, bool fAllowLookup, DNSLookupFn dns_lookup_function) { - if (!ContainsNoNUL(name)) { - return false; - } + if (!ContainsNoNUL(name)) return {}; std::string strHost = name; - if (strHost.empty()) - return false; + if (strHost.empty()) return {}; if (strHost.front() == '[' && strHost.back() == ']') { strHost = strHost.substr(1, strHost.size() - 2); } - return LookupIntern(strHost, vIP, nMaxSolutions, fAllowLookup, dns_lookup_function); + return LookupIntern(strHost, nMaxSolutions, fAllowLookup, dns_lookup_function); } -bool LookupHost(const std::string& name, CNetAddr& addr, bool fAllowLookup, DNSLookupFn dns_lookup_function) +std::optional<CNetAddr> LookupHost(const std::string& name, bool fAllowLookup, DNSLookupFn dns_lookup_function) { - if (!ContainsNoNUL(name)) { - return false; - } - std::vector<CNetAddr> vIP; - LookupHost(name, vIP, 1, fAllowLookup, dns_lookup_function); - if(vIP.empty()) - return false; - addr = vIP.front(); - return true; + const std::vector<CNetAddr> addresses{LookupHost(name, 1, fAllowLookup, dns_lookup_function)}; + return addresses.empty() ? std::nullopt : std::make_optional(addresses.front()); } -bool Lookup(const std::string& name, std::vector<CService>& vAddr, uint16_t portDefault, bool fAllowLookup, unsigned int nMaxSolutions, DNSLookupFn dns_lookup_function) +std::vector<CService> Lookup(const std::string& name, uint16_t portDefault, bool fAllowLookup, unsigned int nMaxSolutions, DNSLookupFn dns_lookup_function) { if (name.empty() || !ContainsNoNUL(name)) { - return false; + return {}; } uint16_t port{portDefault}; std::string hostname; SplitHostPort(name, port, hostname); - std::vector<CNetAddr> vIP; - bool fRet = LookupIntern(hostname, vIP, nMaxSolutions, fAllowLookup, dns_lookup_function); - if (!fRet) - return false; - vAddr.resize(vIP.size()); - for (unsigned int i = 0; i < vIP.size(); i++) - vAddr[i] = CService(vIP[i], port); - return true; + const std::vector<CNetAddr> addresses{LookupIntern(hostname, nMaxSolutions, fAllowLookup, dns_lookup_function)}; + if (addresses.empty()) return {}; + std::vector<CService> services; + services.reserve(addresses.size()); + for (const auto& addr : addresses) + services.emplace_back(addr, port); + return services; } -bool Lookup(const std::string& name, CService& addr, uint16_t portDefault, bool fAllowLookup, DNSLookupFn dns_lookup_function) +std::optional<CService> Lookup(const std::string& name, uint16_t portDefault, bool fAllowLookup, DNSLookupFn dns_lookup_function) { - if (!ContainsNoNUL(name)) { - return false; - } - std::vector<CService> vService; - bool fRet = Lookup(name, vService, portDefault, fAllowLookup, 1, dns_lookup_function); - if (!fRet) - return false; - addr = vService[0]; - return true; + const std::vector<CService> services{Lookup(name, portDefault, fAllowLookup, 1, dns_lookup_function)}; + + return services.empty() ? std::nullopt : std::make_optional(services.front()); } CService LookupNumeric(const std::string& name, uint16_t portDefault, DNSLookupFn dns_lookup_function) @@ -232,12 +209,9 @@ CService LookupNumeric(const std::string& name, uint16_t portDefault, DNSLookupF if (!ContainsNoNUL(name)) { return {}; } - CService addr; // "1.2:345" will fail to resolve the ip, but will still set the port. // If the ip fails to resolve, re-init the result. - if(!Lookup(name, addr, portDefault, false, dns_lookup_function)) - addr = CService(); - return addr; + return Lookup(name, portDefault, /*fAllowLookup=*/false, dns_lookup_function).value_or(CService{}); } /** SOCKS version */ @@ -689,27 +663,27 @@ bool LookupSubNet(const std::string& subnet_str, CSubNet& subnet_out) const size_t slash_pos{subnet_str.find_last_of('/')}; const std::string str_addr{subnet_str.substr(0, slash_pos)}; - CNetAddr addr; + const std::optional<CNetAddr> addr{LookupHost(str_addr, /*fAllowLookup=*/false)}; - if (LookupHost(str_addr, addr, /*fAllowLookup=*/false)) { + if (addr.has_value()) { if (slash_pos != subnet_str.npos) { const std::string netmask_str{subnet_str.substr(slash_pos + 1)}; uint8_t netmask; if (ParseUInt8(netmask_str, &netmask)) { // Valid number; assume CIDR variable-length subnet masking. - subnet_out = CSubNet{addr, netmask}; + subnet_out = CSubNet{addr.value(), netmask}; return subnet_out.IsValid(); } else { // Invalid number; try full netmask syntax. Never allow lookup for netmask. - CNetAddr full_netmask; - if (LookupHost(netmask_str, full_netmask, /*fAllowLookup=*/false)) { - subnet_out = CSubNet{addr, full_netmask}; + const std::optional<CNetAddr> full_netmask{LookupHost(netmask_str, /*fAllowLookup=*/false)}; + if (full_netmask.has_value()) { + subnet_out = CSubNet{addr.value(), full_netmask.value()}; return subnet_out.IsValid(); } } } else { // Single IP subnet (<ipv4>/32 or <ipv6>/128). - subnet_out = CSubNet{addr}; + subnet_out = CSubNet{addr.value()}; return subnet_out.IsValid(); } } diff --git a/src/netbase.h b/src/netbase.h index a43f22f240..1da4f5c51d 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -105,24 +105,25 @@ extern DNSLookupFn g_dns_lookup; * @param name The string representing a host. Could be a name or a numerical * IP address (IPv6 addresses in their bracketed form are * allowed). - * @param[out] vIP The resulting network addresses to which the specified host - * string resolved. * - * @returns Whether or not the specified host string successfully resolved to - * any resulting network addresses. + * @returns The resulting network addresses to which the specified host + * string resolved. * - * @see Lookup(const std::string&, std::vector<CService>&, uint16_t, bool, unsigned int, DNSLookupFn) + * @see Lookup(const std::string&, uint16_t, bool, unsigned int, DNSLookupFn) * for additional parameter descriptions. */ -bool LookupHost(const std::string& name, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup, DNSLookupFn dns_lookup_function = g_dns_lookup); +std::vector<CNetAddr> LookupHost(const std::string& name, unsigned int nMaxSolutions, bool fAllowLookup, DNSLookupFn dns_lookup_function = g_dns_lookup); /** * Resolve a host string to its first corresponding network address. * - * @see LookupHost(const std::string&, std::vector<CNetAddr>&, uint16_t, bool, DNSLookupFn) + * @returns The resulting network address to which the specified host + * string resolved or std::nullopt if host does not resolve to an address. + * + * @see LookupHost(const std::string&, unsigned int, bool, DNSLookupFn) * for additional parameter descriptions. */ -bool LookupHost(const std::string& name, CNetAddr& addr, bool fAllowLookup, DNSLookupFn dns_lookup_function = g_dns_lookup); +std::optional<CNetAddr> LookupHost(const std::string& name, bool fAllowLookup, DNSLookupFn dns_lookup_function = g_dns_lookup); /** * Resolve a service string to its corresponding service. @@ -132,8 +133,6 @@ bool LookupHost(const std::string& name, CNetAddr& addr, bool fAllowLookup, DNSL * disambiguated bracketed form), optionally followed by a uint16_t port * number. (e.g. example.com:8333 or * [2001:db8:85a3:8d3:1319:8a2e:370:7348]:420) - * @param[out] vAddr The resulting services to which the specified service string - * resolved. * @param portDefault The default port for resulting services if not specified * by the service string. * @param fAllowLookup Whether or not hostname lookups are permitted. If yes, @@ -141,18 +140,18 @@ bool LookupHost(const std::string& name, CNetAddr& addr, bool fAllowLookup, DNSL * @param nMaxSolutions The maximum number of results we want, specifying 0 * means "as many solutions as we get." * - * @returns Whether or not the service string successfully resolved to any - * resulting services. + * @returns The resulting services to which the specified service string + * resolved. */ -bool Lookup(const std::string& name, std::vector<CService>& vAddr, uint16_t portDefault, bool fAllowLookup, unsigned int nMaxSolutions, DNSLookupFn dns_lookup_function = g_dns_lookup); +std::vector<CService> Lookup(const std::string& name, uint16_t portDefault, bool fAllowLookup, unsigned int nMaxSolutions, DNSLookupFn dns_lookup_function = g_dns_lookup); /** * Resolve a service string to its first corresponding service. * - * @see Lookup(const std::string&, std::vector<CService>&, uint16_t, bool, unsigned int, DNSLookupFn) + * @see Lookup(const std::string&, uint16_t, bool, unsigned int, DNSLookupFn) * for additional parameter descriptions. */ -bool Lookup(const std::string& name, CService& addr, uint16_t portDefault, bool fAllowLookup, DNSLookupFn dns_lookup_function = g_dns_lookup); +std::optional<CService> Lookup(const std::string& name, uint16_t portDefault, bool fAllowLookup, DNSLookupFn dns_lookup_function = g_dns_lookup); /** * Resolve a service string with a numeric IP to its first corresponding @@ -160,7 +159,7 @@ bool Lookup(const std::string& name, CService& addr, uint16_t portDefault, bool * * @returns The resulting CService if the resolution was successful, [::]:0 otherwise. * - * @see Lookup(const std::string&, std::vector<CService>&, uint16_t, bool, unsigned int, DNSLookupFn) + * @see Lookup(const std::string&, uint16_t, bool, unsigned int, DNSLookupFn) * for additional parameter descriptions. */ CService LookupNumeric(const std::string& name, uint16_t portDefault = 0, DNSLookupFn dns_lookup_function = g_dns_lookup); diff --git a/src/node/blockmanager_args.h b/src/node/blockmanager_args.h index 84540b1922..de9fe83a5c 100644 --- a/src/node/blockmanager_args.h +++ b/src/node/blockmanager_args.h @@ -12,7 +12,7 @@ class ArgsManager; namespace node { -util::Result<void> ApplyArgsManOptions(const ArgsManager& args, BlockManager::Options& opts); +[[nodiscard]] util::Result<void> ApplyArgsManOptions(const ArgsManager& args, BlockManager::Options& opts); } // namespace node #endif // BITCOIN_NODE_BLOCKMANAGER_ARGS_H diff --git a/src/node/blockstorage.cpp b/src/node/blockstorage.cpp index f8d4e6c1da..b7afa8a7c3 100644 --- a/src/node/blockstorage.cpp +++ b/src/node/blockstorage.cpp @@ -17,9 +17,9 @@ #include <signet.h> #include <streams.h> #include <undo.h> +#include <util/batchpriority.h> #include <util/fs.h> #include <util/syscall_sandbox.h> -#include <util/system.h> #include <validation.h> #include <map> diff --git a/src/node/chainstate.cpp b/src/node/chainstate.cpp index 40b609d069..8f997b0594 100644 --- a/src/node/chainstate.cpp +++ b/src/node/chainstate.cpp @@ -253,7 +253,7 @@ ChainstateLoadResult VerifyLoadedChainstate(ChainstateManager& chainman, const C "Only rebuild the block database if you are sure that your computer's date and time are correct")}; } - VerifyDBResult result = CVerifyDB().VerifyDB( + VerifyDBResult result = CVerifyDB(chainman.GetNotifications()).VerifyDB( *chainstate, chainman.GetConsensus(), chainstate->CoinsDB(), options.check_level, options.check_blocks); diff --git a/src/node/chainstatemanager_args.h b/src/node/chainstatemanager_args.h index 82eb037368..701515953e 100644 --- a/src/node/chainstatemanager_args.h +++ b/src/node/chainstatemanager_args.h @@ -11,7 +11,7 @@ class ArgsManager; namespace node { -util::Result<void> ApplyArgsManOptions(const ArgsManager& args, ChainstateManager::Options& opts); +[[nodiscard]] util::Result<void> ApplyArgsManOptions(const ArgsManager& args, ChainstateManager::Options& opts); } // namespace node #endif // BITCOIN_NODE_CHAINSTATEMANAGER_ARGS_H diff --git a/src/node/context.cpp b/src/node/context.cpp index af59ab932b..ca56fa0b86 100644 --- a/src/node/context.cpp +++ b/src/node/context.cpp @@ -11,6 +11,7 @@ #include <net.h> #include <net_processing.h> #include <netgroup.h> +#include <node/kernel_notifications.h> #include <policy/fees.h> #include <scheduler.h> #include <txmempool.h> diff --git a/src/node/context.h b/src/node/context.h index 84f4053c84..9532153cdb 100644 --- a/src/node/context.h +++ b/src/node/context.h @@ -30,6 +30,8 @@ class WalletLoader; } // namespace interfaces namespace node { +class KernelNotifications; + //! NodeContext struct containing references to chain state and connection //! state. //! @@ -62,6 +64,7 @@ struct NodeContext { interfaces::WalletLoader* wallet_loader{nullptr}; std::unique_ptr<CScheduler> scheduler; std::function<void()> rpc_interruption_point = [] {}; + std::unique_ptr<KernelNotifications> notifications; //! Declare default constructor and destructor that are not inline, so code //! instantiating the NodeContext struct doesn't need to #include class diff --git a/src/node/kernel_notifications.cpp b/src/node/kernel_notifications.cpp new file mode 100644 index 0000000000..926b157f3b --- /dev/null +++ b/src/node/kernel_notifications.cpp @@ -0,0 +1,75 @@ +// Copyright (c) 2023 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 <node/kernel_notifications.h> + +#if defined(HAVE_CONFIG_H) +#include <config/bitcoin-config.h> +#endif + +#include <common/args.h> +#include <common/system.h> +#include <node/interface_ui.h> +#include <util/strencodings.h> +#include <util/string.h> +#include <util/translation.h> +#include <warnings.h> + +#include <cstdint> +#include <string> +#include <thread> + +static void AlertNotify(const std::string& strMessage) +{ + uiInterface.NotifyAlertChanged(); +#if HAVE_SYSTEM + std::string strCmd = gArgs.GetArg("-alertnotify", ""); + if (strCmd.empty()) return; + + // Alert text should be plain ascii coming from a trusted source, but to + // be safe we first strip anything not in safeChars, then add single quotes around + // the whole string before passing it to the shell: + std::string singleQuote("'"); + std::string safeStatus = SanitizeString(strMessage); + safeStatus = singleQuote+safeStatus+singleQuote; + ReplaceAll(strCmd, "%s", safeStatus); + + std::thread t(runCommand, strCmd); + t.detach(); // thread runs free +#endif +} + +static void DoWarning(const bilingual_str& warning) +{ + static bool fWarned = false; + SetMiscWarning(warning); + if (!fWarned) { + AlertNotify(warning.original); + fWarned = true; + } +} + +namespace node { + +void KernelNotifications::blockTip(SynchronizationState state, CBlockIndex& index) +{ + uiInterface.NotifyBlockTip(state, &index); +} + +void KernelNotifications::headerTip(SynchronizationState state, int64_t height, int64_t timestamp, bool presync) +{ + uiInterface.NotifyHeaderTip(state, height, timestamp, presync); +} + +void KernelNotifications::progress(const bilingual_str& title, int progress_percent, bool resume_possible) +{ + uiInterface.ShowProgress(title.translated, progress_percent, resume_possible); +} + +void KernelNotifications::warning(const bilingual_str& warning) +{ + DoWarning(warning); +} + +} // namespace node diff --git a/src/node/kernel_notifications.h b/src/node/kernel_notifications.h new file mode 100644 index 0000000000..3e665bbf14 --- /dev/null +++ b/src/node/kernel_notifications.h @@ -0,0 +1,31 @@ +// Copyright (c) 2023 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_NODE_KERNEL_NOTIFICATIONS_H +#define BITCOIN_NODE_KERNEL_NOTIFICATIONS_H + +#include <kernel/notifications_interface.h> + +#include <cstdint> +#include <string> + +class CBlockIndex; +enum class SynchronizationState; +struct bilingual_str; + +namespace node { +class KernelNotifications : public kernel::Notifications +{ +public: + void blockTip(SynchronizationState state, CBlockIndex& index) override; + + void headerTip(SynchronizationState state, int64_t height, int64_t timestamp, bool presync) override; + + void progress(const bilingual_str& title, int progress_percent, bool resume_possible) override; + + void warning(const bilingual_str& warning) override; +}; +} // namespace node + +#endif // BITCOIN_NODE_KERNEL_NOTIFICATIONS_H diff --git a/src/node/txreconciliation.cpp b/src/node/txreconciliation.cpp index 9938759074..d62046daaa 100644 --- a/src/node/txreconciliation.cpp +++ b/src/node/txreconciliation.cpp @@ -4,9 +4,9 @@ #include <node/txreconciliation.h> +#include <common/system.h> #include <logging.h> #include <util/check.h> -#include <util/system.h> #include <unordered_map> #include <variant> diff --git a/src/policy/fees.cpp b/src/policy/fees.cpp index 6121224979..ae226f7011 100644 --- a/src/policy/fees.cpp +++ b/src/policy/fees.cpp @@ -6,6 +6,7 @@ #include <policy/fees.h> #include <clientversion.h> +#include <common/system.h> #include <consensus/amount.h> #include <kernel/mempool_entry.h> #include <logging.h> @@ -19,7 +20,6 @@ #include <uint256.h> #include <util/fs.h> #include <util/serfloat.h> -#include <util/system.h> #include <util/time.h> #include <algorithm> diff --git a/src/protocol.cpp b/src/protocol.cpp index 5725813b7e..5ecaabec36 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -5,7 +5,7 @@ #include <protocol.h> -#include <util/system.h> +#include <common/system.h> #include <atomic> diff --git a/src/protocol.h b/src/protocol.h index cbcd400fef..ac4545c311 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -134,7 +134,8 @@ extern const char* GETADDR; /** * The mempool message requests the TXIDs of transactions that the receiving * node has verified as valid but which have not yet appeared in a block. - * @since protocol version 60002. + * @since protocol version 60002 as described by BIP35. + * Only available with service bit NODE_BLOOM, see also BIP111. */ extern const char* MEMPOOL; /** @@ -278,8 +279,6 @@ enum ServiceFlags : uint64_t { // set by all Bitcoin Core non pruned nodes, and is unset by SPV clients or other light clients. NODE_NETWORK = (1 << 0), // NODE_BLOOM means the node is capable and willing to handle bloom-filtered connections. - // Bitcoin Core nodes used to support this by default, without advertising this bit, - // but no longer do as of protocol version 70011 (= NO_BLOOM_VERSION) NODE_BLOOM = (1 << 2), // NODE_WITNESS indicates that a node can be asked for blocks and transactions including // witness data. diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index d602d2c1ac..e33753f5e7 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -11,6 +11,7 @@ #include <chainparams.h> #include <common/args.h> #include <common/init.h> +#include <common/system.h> #include <init.h> #include <interfaces/handler.h> #include <interfaces/init.h> @@ -32,7 +33,6 @@ #include <uint256.h> #include <util/exception.h> #include <util/string.h> -#include <util/system.h> #include <util/threadnames.h> #include <util/translation.h> #include <validation.h> diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index d26ef52eb4..f201d8fa01 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -30,16 +30,17 @@ #include <qt/macdockiconhandler.h> #endif -#include <functional> #include <chain.h> #include <chainparams.h> +#include <common/system.h> #include <interfaces/handler.h> #include <interfaces/node.h> #include <node/interface_ui.h> -#include <util/system.h> #include <util/translation.h> #include <validation.h> +#include <functional> + #include <QAction> #include <QActionGroup> #include <QApplication> diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index b22f1bc35c..ff7405d139 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -12,11 +12,11 @@ #include <clientversion.h> #include <common/args.h> +#include <common/system.h> #include <interfaces/handler.h> #include <interfaces/node.h> #include <net.h> #include <netbase.h> -#include <util/system.h> #include <util/threadnames.h> #include <util/time.h> #include <validation.h> diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 6dec4b2e42..512fce473d 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -15,11 +15,11 @@ #include <qt/guiutil.h> #include <qt/optionsmodel.h> +#include <common/system.h> #include <interfaces/node.h> -#include <validation.h> // for DEFAULT_SCRIPTCHECK_THREADS and MAX_SCRIPTCHECK_THREADS #include <netbase.h> -#include <txdb.h> // for -dbcache defaults -#include <util/system.h> +#include <txdb.h> +#include <validation.h> #include <chrono> @@ -406,9 +406,8 @@ void OptionsDialog::updateProxyValidationState() void OptionsDialog::updateDefaultProxyNets() { - CNetAddr ui_proxy_netaddr; - LookupHost(ui->proxyIp->text().toStdString(), ui_proxy_netaddr, /*fAllowLookup=*/false); - const CService ui_proxy{ui_proxy_netaddr, ui->proxyPort->text().toUShort()}; + const std::optional<CNetAddr> ui_proxy_netaddr{LookupHost(ui->proxyIp->text().toStdString(), /*fAllowLookup=*/false)}; + const CService ui_proxy{ui_proxy_netaddr.value_or(CNetAddr{}), ui->proxyPort->text().toUShort()}; Proxy proxy; bool has_proxy; diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index bac64e3d5f..90aae0219e 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -10,6 +10,7 @@ #include <qt/forms/ui_debugwindow.h> #include <chainparams.h> +#include <common/system.h> #include <interfaces/node.h> #include <qt/bantablemodel.h> #include <qt/clientmodel.h> @@ -21,7 +22,6 @@ #include <rpc/server.h> #include <util/strencodings.h> #include <util/string.h> -#include <util/system.h> #include <util/threadnames.h> #include <univalue.h> diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index 096f8a0ded..8872f8be32 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -9,13 +9,13 @@ #include <qt/splashscreen.h> #include <clientversion.h> +#include <common/system.h> #include <interfaces/handler.h> #include <interfaces/node.h> #include <interfaces/wallet.h> #include <qt/guiutil.h> #include <qt/networkstyle.h> #include <qt/walletmodel.h> -#include <util/system.h> #include <util/translation.h> #include <functional> diff --git a/src/qt/test/rpcnestedtests.cpp b/src/qt/test/rpcnestedtests.cpp index 669a05fe0f..72e8055425 100644 --- a/src/qt/test/rpcnestedtests.cpp +++ b/src/qt/test/rpcnestedtests.cpp @@ -4,12 +4,12 @@ #include <qt/test/rpcnestedtests.h> +#include <common/system.h> #include <interfaces/node.h> -#include <rpc/server.h> #include <qt/rpcconsole.h> +#include <rpc/server.h> #include <test/util/setup_common.h> #include <univalue.h> -#include <util/system.h> #include <QTest> diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 2461a06930..fa110cfbc9 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -13,12 +13,12 @@ #include <qt/paymentserver.h> #include <qt/transactionrecord.h> +#include <common/system.h> #include <consensus/consensus.h> #include <interfaces/node.h> #include <interfaces/wallet.h> #include <key_io.h> #include <policy/policy.h> -#include <util/system.h> #include <validation.h> #include <wallet/types.h> diff --git a/src/rest.cpp b/src/rest.cpp index dae064f89d..c9e61d70bd 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -24,8 +24,8 @@ #include <streams.h> #include <sync.h> #include <txmempool.h> +#include <util/any.h> #include <util/check.h> -#include <util/system.h> #include <validation.h> #include <version.h> diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 4c25dbc345..ee3237638e 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1123,7 +1123,7 @@ static RPCHelpMan verifychain() LOCK(cs_main); Chainstate& active_chainstate = chainman.ActiveChainstate(); - return CVerifyDB().VerifyDB( + return CVerifyDB(chainman.GetNotifications()).VerifyDB( active_chainstate, chainman.GetParams().GetConsensus(), active_chainstate.CoinsTip(), check_level, check_depth) == VerifyDBResult::SUCCESS; }, }; diff --git a/src/rpc/external_signer.cpp b/src/rpc/external_signer.cpp index ac135ba216..310eec5f15 100644 --- a/src/rpc/external_signer.cpp +++ b/src/rpc/external_signer.cpp @@ -3,12 +3,12 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <common/args.h> +#include <common/system.h> #include <external_signer.h> #include <rpc/protocol.h> #include <rpc/server.h> #include <rpc/util.h> #include <util/strencodings.h> -#include <util/system.h> #include <string> #include <vector> diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 68017e5af2..eb61d58a33 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -5,6 +5,7 @@ #include <chain.h> #include <chainparams.h> +#include <common/system.h> #include <consensus/amount.h> #include <consensus/consensus.h> #include <consensus/merkle.h> @@ -32,7 +33,6 @@ #include <univalue.h> #include <util/strencodings.h> #include <util/string.h> -#include <util/system.h> #include <util/translation.h> #include <validation.h> #include <validationinterface.h> diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index f247e6ee91..a2a46ef32f 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -713,9 +713,10 @@ static RPCHelpMan setban() isSubnet = true; if (!isSubnet) { - CNetAddr resolved; - LookupHost(request.params[0].get_str(), resolved, false); - netAddr = resolved; + const std::optional<CNetAddr> addr{LookupHost(request.params[0].get_str(), false)}; + if (addr.has_value()) { + netAddr = addr.value(); + } } else LookupSubNet(request.params[0].get_str(), subNet); @@ -943,11 +944,11 @@ static RPCHelpMan addpeeraddress() const bool tried{request.params[2].isNull() ? false : request.params[2].get_bool()}; UniValue obj(UniValue::VOBJ); - CNetAddr net_addr; + std::optional<CNetAddr> net_addr{LookupHost(addr_string, false)}; bool success{false}; - if (LookupHost(addr_string, net_addr, false)) { - CService service{net_addr, port}; + if (net_addr.has_value()) { + CService service{net_addr.value(), port}; CAddress address{MaybeFlipIPv6toCJDNS(service), ServiceFlags{NODE_NETWORK | NODE_WITNESS}}; address.nTime = Now<NodeSeconds>(); // The source address is set equal to the address. This is equivalent to the peer diff --git a/src/rpc/node.cpp b/src/rpc/node.cpp index ca8db0f82a..45d46d223b 100644 --- a/src/rpc/node.cpp +++ b/src/rpc/node.cpp @@ -19,9 +19,9 @@ #include <rpc/util.h> #include <scheduler.h> #include <univalue.h> +#include <util/any.h> #include <util/check.h> #include <util/syscall_sandbox.h> -#include <util/system.h> #include <stdint.h> #ifdef HAVE_MALLOC_INFO diff --git a/src/rpc/request.cpp b/src/rpc/request.cpp index cf1b6cd92b..4c67da8b70 100644 --- a/src/rpc/request.cpp +++ b/src/rpc/request.cpp @@ -88,7 +88,7 @@ bool GenerateAuthCookie(std::string *cookie_out) std::string cookie = COOKIEAUTH_USER + ":" + HexStr(rand_pwd); /** the umask determines what permissions are used to create this file - - * these are set to 0077 in util/system.cpp. + * these are set to 0077 in common/system.cpp. */ std::ofstream file; fs::path filepath_tmp = GetAuthCookieFile(true); diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 354f949002..474b318c66 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -6,13 +6,13 @@ #include <rpc/server.h> #include <common/args.h> +#include <common/system.h> #include <logging.h> #include <rpc/util.h> #include <shutdown.h> #include <sync.h> #include <util/strencodings.h> #include <util/string.h> -#include <util/system.h> #include <util/time.h> #include <boost/signals2/signal.hpp> diff --git a/src/rpc/server_util.cpp b/src/rpc/server_util.cpp index 13d007b496..1d4afb3758 100644 --- a/src/rpc/server_util.cpp +++ b/src/rpc/server_util.cpp @@ -11,7 +11,7 @@ #include <rpc/protocol.h> #include <rpc/request.h> #include <txmempool.h> -#include <util/system.h> +#include <util/any.h> #include <validation.h> #include <any> diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp index e52e8cd309..7c6c282cc4 100644 --- a/src/script/sigcache.cpp +++ b/src/script/sigcache.cpp @@ -5,11 +5,11 @@ #include <script/sigcache.h> +#include <common/system.h> #include <logging.h> #include <pubkey.h> #include <random.h> #include <uint256.h> -#include <util/system.h> #include <cuckoocache.h> diff --git a/src/signet.cpp b/src/signet.cpp index b76b1e342f..b73d82bb2e 100644 --- a/src/signet.cpp +++ b/src/signet.cpp @@ -8,6 +8,7 @@ #include <cstdint> #include <vector> +#include <common/system.h> #include <consensus/merkle.h> #include <consensus/params.h> #include <consensus/validation.h> @@ -22,7 +23,6 @@ #include <streams.h> #include <uint256.h> #include <util/strencodings.h> -#include <util/system.h> static constexpr uint8_t SIGNET_HEADER[4] = {0xec, 0xc7, 0xda, 0xa2}; diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp index 54d923e4a4..328e7f81a0 100644 --- a/src/test/addrman_tests.cpp +++ b/src/test/addrman_tests.cpp @@ -33,16 +33,16 @@ static int32_t GetCheckRatio(const NodeContext& node_ctx) static CNetAddr ResolveIP(const std::string& ip) { - CNetAddr addr; - BOOST_CHECK_MESSAGE(LookupHost(ip, addr, false), strprintf("failed to resolve: %s", ip)); - return addr; + const std::optional<CNetAddr> addr{LookupHost(ip, false)}; + BOOST_CHECK_MESSAGE(addr.has_value(), strprintf("failed to resolve: %s", ip)); + return addr.value_or(CNetAddr{}); } static CService ResolveService(const std::string& ip, uint16_t port = 0) { - CService serv; - BOOST_CHECK_MESSAGE(Lookup(ip, serv, port, false), strprintf("failed to resolve: %s:%i", ip, port)); - return serv; + const std::optional<CService> serv{Lookup(ip, port, false)}; + BOOST_CHECK_MESSAGE(serv.has_value(), strprintf("failed to resolve: %s:%i", ip, port)); + return serv.value_or(CService{}); } @@ -948,18 +948,23 @@ BOOST_AUTO_TEST_CASE(load_addrman) { AddrMan addrman{EMPTY_NETGROUPMAN, DETERMINISTIC, GetCheckRatio(m_node)}; - CService addr1, addr2, addr3; - BOOST_CHECK(Lookup("250.7.1.1", addr1, 8333, false)); - BOOST_CHECK(Lookup("250.7.2.2", addr2, 9999, false)); - BOOST_CHECK(Lookup("250.7.3.3", addr3, 9999, false)); - BOOST_CHECK(Lookup("250.7.3.3"s, addr3, 9999, false)); - BOOST_CHECK(!Lookup("250.7.3.3\0example.com"s, addr3, 9999, false)); + std::optional<CService> addr1, addr2, addr3, addr4; + addr1 = Lookup("250.7.1.1", 8333, false); + BOOST_CHECK(addr1.has_value()); + addr2 = Lookup("250.7.2.2", 9999, false); + BOOST_CHECK(addr2.has_value()); + addr3 = Lookup("250.7.3.3", 9999, false); + BOOST_CHECK(addr3.has_value()); + addr3 = Lookup("250.7.3.3"s, 9999, false); + BOOST_CHECK(addr3.has_value()); + addr4 = Lookup("250.7.3.3\0example.com"s, 9999, false); + BOOST_CHECK(!addr4.has_value()); // Add three addresses to new table. - CService source; - BOOST_CHECK(Lookup("252.5.1.1", source, 8333, false)); - std::vector<CAddress> addresses{CAddress(addr1, NODE_NONE), CAddress(addr2, NODE_NONE), CAddress(addr3, NODE_NONE)}; - BOOST_CHECK(addrman.Add(addresses, source)); + const std::optional<CService> source{Lookup("252.5.1.1", 8333, false)}; + BOOST_CHECK(source.has_value()); + std::vector<CAddress> addresses{CAddress(addr1.value(), NODE_NONE), CAddress(addr2.value(), NODE_NONE), CAddress(addr3.value(), NODE_NONE)}; + BOOST_CHECK(addrman.Add(addresses, source.value())); BOOST_CHECK(addrman.Size() == 3); // Test that the de-serialization does not throw an exception. @@ -1004,12 +1009,12 @@ static CDataStream MakeCorruptPeersDat() int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30); s << nUBuckets; - CService serv; - BOOST_CHECK(Lookup("252.1.1.1", serv, 7777, false)); - CAddress addr = CAddress(serv, NODE_NONE); - CNetAddr resolved; - BOOST_CHECK(LookupHost("252.2.2.2", resolved, false)); - AddrInfo info = AddrInfo(addr, resolved); + const std::optional<CService> serv{Lookup("252.1.1.1", 7777, false)}; + BOOST_REQUIRE(serv.has_value()); + CAddress addr = CAddress(serv.value(), NODE_NONE); + std::optional<CNetAddr> resolved{LookupHost("252.2.2.2", false)}; + BOOST_REQUIRE(resolved.has_value()); + AddrInfo info = AddrInfo(addr, resolved.value()); s << info; return s; diff --git a/src/test/allocator_tests.cpp b/src/test/allocator_tests.cpp index f74e50a890..8c0af6f26f 100644 --- a/src/test/allocator_tests.cpp +++ b/src/test/allocator_tests.cpp @@ -2,8 +2,8 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <common/system.h> #include <support/lockedpool.h> -#include <util/system.h> #include <limits> #include <memory> diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp index 5d4c5eea0e..93c0412593 100644 --- a/src/test/bloom_tests.cpp +++ b/src/test/bloom_tests.cpp @@ -5,6 +5,7 @@ #include <common/bloom.h> #include <clientversion.h> +#include <common/system.h> #include <key.h> #include <key_io.h> #include <merkleblock.h> @@ -16,7 +17,6 @@ #include <test/util/setup_common.h> #include <uint256.h> #include <util/strencodings.h> -#include <util/system.h> #include <vector> diff --git a/src/test/fuzz/integer.cpp b/src/test/fuzz/integer.cpp index 392f3591f1..edb1dca457 100644 --- a/src/test/fuzz/integer.cpp +++ b/src/test/fuzz/integer.cpp @@ -4,6 +4,7 @@ #include <arith_uint256.h> #include <common/args.h> +#include <common/system.h> #include <compressor.h> #include <consensus/amount.h> #include <consensus/merkle.h> @@ -32,7 +33,6 @@ #include <util/overflow.h> #include <util/strencodings.h> #include <util/string.h> -#include <util/system.h> #include <version.h> #include <cassert> diff --git a/src/test/fuzz/netbase_dns_lookup.cpp b/src/test/fuzz/netbase_dns_lookup.cpp index 81e216b358..dcf500acc3 100644 --- a/src/test/fuzz/netbase_dns_lookup.cpp +++ b/src/test/fuzz/netbase_dns_lookup.cpp @@ -29,33 +29,29 @@ FUZZ_TARGET(netbase_dns_lookup) }; { - std::vector<CNetAddr> resolved_addresses; - if (LookupHost(name, resolved_addresses, max_results, allow_lookup, fuzzed_dns_lookup_function)) { - for (const CNetAddr& resolved_address : resolved_addresses) { - assert(!resolved_address.IsInternal()); - } + const std::vector<CNetAddr> resolved_addresses{LookupHost(name, max_results, allow_lookup, fuzzed_dns_lookup_function)}; + for (const CNetAddr& resolved_address : resolved_addresses) { + assert(!resolved_address.IsInternal()); } assert(resolved_addresses.size() <= max_results || max_results == 0); } { - CNetAddr resolved_address; - if (LookupHost(name, resolved_address, allow_lookup, fuzzed_dns_lookup_function)) { - assert(!resolved_address.IsInternal()); + const std::optional<CNetAddr> resolved_address{LookupHost(name, allow_lookup, fuzzed_dns_lookup_function)}; + if (resolved_address.has_value()) { + assert(!resolved_address.value().IsInternal()); } } { - std::vector<CService> resolved_services; - if (Lookup(name, resolved_services, default_port, allow_lookup, max_results, fuzzed_dns_lookup_function)) { - for (const CNetAddr& resolved_service : resolved_services) { - assert(!resolved_service.IsInternal()); - } + const std::vector<CService> resolved_services{Lookup(name, default_port, allow_lookup, max_results, fuzzed_dns_lookup_function)}; + for (const CNetAddr& resolved_service : resolved_services) { + assert(!resolved_service.IsInternal()); } assert(resolved_services.size() <= max_results || max_results == 0); } { - CService resolved_service; - if (Lookup(name, resolved_service, default_port, allow_lookup, fuzzed_dns_lookup_function)) { - assert(!resolved_service.IsInternal()); + const std::optional<CService> resolved_service{Lookup(name, default_port, allow_lookup, fuzzed_dns_lookup_function)}; + if (resolved_service.has_value()) { + assert(!resolved_service.value().IsInternal()); } } { diff --git a/src/test/fuzz/string.cpp b/src/test/fuzz/string.cpp index 5de24a939d..75c78ce1bd 100644 --- a/src/test/fuzz/string.cpp +++ b/src/test/fuzz/string.cpp @@ -5,6 +5,7 @@ #include <blockfilter.h> #include <clientversion.h> #include <common/args.h> +#include <common/system.h> #include <common/url.h> #include <netbase.h> #include <outputtype.h> @@ -24,7 +25,6 @@ #include <util/settings.h> #include <util/strencodings.h> #include <util/string.h> -#include <util/system.h> #include <util/translation.h> #include <cassert> diff --git a/src/test/fuzz/system.cpp b/src/test/fuzz/system.cpp index 04cbbe52cb..73c01d9297 100644 --- a/src/test/fuzz/system.cpp +++ b/src/test/fuzz/system.cpp @@ -55,7 +55,7 @@ FUZZ_TARGET_INIT(system, initialize_system) [&] { const OptionsCategory options_category = fuzzed_data_provider.PickValueInArray<OptionsCategory>({OptionsCategory::OPTIONS, OptionsCategory::CONNECTION, OptionsCategory::WALLET, OptionsCategory::WALLET_DEBUG_TEST, OptionsCategory::ZMQ, OptionsCategory::DEBUG_TEST, OptionsCategory::CHAINPARAMS, OptionsCategory::NODE_RELAY, OptionsCategory::BLOCK_CREATION, OptionsCategory::RPC, OptionsCategory::GUI, OptionsCategory::COMMANDS, OptionsCategory::REGISTER_COMMANDS, OptionsCategory::HIDDEN}); // Avoid hitting: - // util/system.cpp:425: void ArgsManager::AddArg(const std::string &, const std::string &, unsigned int, const OptionsCategory &): Assertion `ret.second' failed. + // common/args.cpp:563: void ArgsManager::AddArg(const std::string &, const std::string &, unsigned int, const OptionsCategory &): Assertion `ret.second' failed. const std::string argument_name = GetArgumentName(fuzzed_data_provider.ConsumeRandomLengthString(16)); if (args_manager.GetArgFlags(argument_name) != std::nullopt) { return; @@ -64,7 +64,7 @@ FUZZ_TARGET_INIT(system, initialize_system) }, [&] { // Avoid hitting: - // util/system.cpp:425: void ArgsManager::AddArg(const std::string &, const std::string &, unsigned int, const OptionsCategory &): Assertion `ret.second' failed. + // common/args.cpp:563: void ArgsManager::AddArg(const std::string &, const std::string &, unsigned int, const OptionsCategory &): Assertion `ret.second' failed. const std::vector<std::string> names = ConsumeRandomLengthStringVector(fuzzed_data_provider); std::vector<std::string> hidden_arguments; for (const std::string& name : names) { diff --git a/src/test/fuzz/utxo_total_supply.cpp b/src/test/fuzz/utxo_total_supply.cpp index 19f41880f4..ea78edd05f 100644 --- a/src/test/fuzz/utxo_total_supply.cpp +++ b/src/test/fuzz/utxo_total_supply.cpp @@ -119,7 +119,9 @@ FUZZ_TARGET(utxo_total_supply) current_block = PrepareNextBlock(); StoreLastTxo(); - LIMITED_WHILE(fuzzed_data_provider.remaining_bytes(), 100'000) + // Limit to avoid timeout, but enough to cover duplicate_coinbase_height + // and CVE-2018-17144. + LIMITED_WHILE(fuzzed_data_provider.remaining_bytes(), 2'000) { CallOneOf( fuzzed_data_provider, @@ -142,14 +144,14 @@ FUZZ_TARGET(utxo_total_supply) node::RegenerateCommitments(*current_block, chainman); const bool was_valid = !MineBlock(node, current_block).IsNull(); + if (duplicate_coinbase_height == ActiveHeight()) { + // we mined the duplicate coinbase + assert(current_block->vtx.at(0)->vin.at(0).scriptSig == duplicate_coinbase_script); + } + const auto prev_utxo_stats = utxo_stats; if (was_valid) { circulation += GetBlockSubsidy(ActiveHeight(), Params().GetConsensus()); - - if (duplicate_coinbase_height == ActiveHeight()) { - // we mined the duplicate coinbase - assert(current_block->vtx.at(0)->vin.at(0).scriptSig == duplicate_coinbase_script); - } } UpdateUtxoStats(); diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp index ea5b94f3a5..8f11bf5db2 100644 --- a/src/test/key_tests.cpp +++ b/src/test/key_tests.cpp @@ -4,6 +4,7 @@ #include <key.h> +#include <common/system.h> #include <key_io.h> #include <streams.h> #include <test/util/random.h> @@ -11,7 +12,6 @@ #include <uint256.h> #include <util/strencodings.h> #include <util/string.h> -#include <util/system.h> #include <string> #include <vector> diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp index 94e553a304..db58a0baec 100644 --- a/src/test/mempool_tests.cpp +++ b/src/test/mempool_tests.cpp @@ -2,10 +2,10 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <common/system.h> #include <policy/policy.h> #include <test/util/txmempool.h> #include <txmempool.h> -#include <util/system.h> #include <util/time.h> #include <test/util/setup_common.h> diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index cfab762307..94e3f27930 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -3,6 +3,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <coins.h> +#include <common/system.h> #include <consensus/consensus.h> #include <consensus/merkle.h> #include <consensus/tx_verify.h> @@ -15,7 +16,6 @@ #include <txmempool.h> #include <uint256.h> #include <util/strencodings.h> -#include <util/system.h> #include <util/time.h> #include <validation.h> #include <versionbits.h> diff --git a/src/test/miniminer_tests.cpp b/src/test/miniminer_tests.cpp index 3f4a5fbe74..371147b0e2 100644 --- a/src/test/miniminer_tests.cpp +++ b/src/test/miniminer_tests.cpp @@ -3,7 +3,6 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <node/mini_miner.h> #include <txmempool.h> -#include <util/system.h> #include <util/time.h> #include <test/util/setup_common.h> diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp index 631c213627..aa577f7b27 100644 --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -135,7 +135,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_basic) CNetAddr addr; // IPv4, INADDR_ANY - BOOST_REQUIRE(LookupHost("0.0.0.0", addr, false)); + addr = LookupHost("0.0.0.0", false).value(); BOOST_REQUIRE(!addr.IsValid()); BOOST_REQUIRE(addr.IsIPv4()); @@ -144,7 +144,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_basic) BOOST_CHECK_EQUAL(addr.ToStringAddr(), "0.0.0.0"); // IPv4, INADDR_NONE - BOOST_REQUIRE(LookupHost("255.255.255.255", addr, false)); + addr = LookupHost("255.255.255.255", false).value(); BOOST_REQUIRE(!addr.IsValid()); BOOST_REQUIRE(addr.IsIPv4()); @@ -153,7 +153,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_basic) BOOST_CHECK_EQUAL(addr.ToStringAddr(), "255.255.255.255"); // IPv4, casual - BOOST_REQUIRE(LookupHost("12.34.56.78", addr, false)); + addr = LookupHost("12.34.56.78", false).value(); BOOST_REQUIRE(addr.IsValid()); BOOST_REQUIRE(addr.IsIPv4()); @@ -162,7 +162,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_basic) BOOST_CHECK_EQUAL(addr.ToStringAddr(), "12.34.56.78"); // IPv6, in6addr_any - BOOST_REQUIRE(LookupHost("::", addr, false)); + addr = LookupHost("::", false).value(); BOOST_REQUIRE(!addr.IsValid()); BOOST_REQUIRE(addr.IsIPv6()); @@ -171,7 +171,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_basic) BOOST_CHECK_EQUAL(addr.ToStringAddr(), "::"); // IPv6, casual - BOOST_REQUIRE(LookupHost("1122:3344:5566:7788:9900:aabb:ccdd:eeff", addr, false)); + addr = LookupHost("1122:3344:5566:7788:9900:aabb:ccdd:eeff", false).value(); BOOST_REQUIRE(addr.IsValid()); BOOST_REQUIRE(addr.IsIPv6()); @@ -186,14 +186,14 @@ BOOST_AUTO_TEST_CASE(cnetaddr_basic) // id of "32", return the address as "fe80::1%32". const std::string link_local{"fe80::1"}; const std::string scoped_addr{link_local + "%32"}; - BOOST_REQUIRE(LookupHost(scoped_addr, addr, false)); + addr = LookupHost(scoped_addr, false).value(); BOOST_REQUIRE(addr.IsValid()); BOOST_REQUIRE(addr.IsIPv6()); BOOST_CHECK(!addr.IsBindAny()); BOOST_CHECK_EQUAL(addr.ToStringAddr(), scoped_addr); // Test that the delimiter "%" and default zone id of 0 can be omitted for the default scope. - BOOST_REQUIRE(LookupHost(link_local + "%0", addr, false)); + addr = LookupHost(link_local + "%0", false).value(); BOOST_REQUIRE(addr.IsValid()); BOOST_REQUIRE(addr.IsIPv6()); BOOST_CHECK(!addr.IsBindAny()); @@ -318,10 +318,9 @@ BOOST_AUTO_TEST_CASE(cnetaddr_tostring_canonical_ipv6) {"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.ToStringAddr(), expected_canonical_representation_output); + const std::optional<CNetAddr> net_addr{LookupHost(input_address, false)}; + BOOST_REQUIRE(net_addr.value().IsIPv6()); + BOOST_CHECK_EQUAL(net_addr.value().ToStringAddr(), expected_canonical_representation_output); } } @@ -334,12 +333,12 @@ BOOST_AUTO_TEST_CASE(cnetaddr_serialize_v1) BOOST_CHECK_EQUAL(HexStr(s), "00000000000000000000000000000000"); s.clear(); - BOOST_REQUIRE(LookupHost("1.2.3.4", addr, false)); + addr = LookupHost("1.2.3.4", false).value(); s << addr; BOOST_CHECK_EQUAL(HexStr(s), "00000000000000000000ffff01020304"); s.clear(); - BOOST_REQUIRE(LookupHost("1a1b:2a2b:3a3b:4a4b:5a5b:6a6b:7a7b:8a8b", addr, false)); + addr = LookupHost("1a1b:2a2b:3a3b:4a4b:5a5b:6a6b:7a7b:8a8b", false).value(); s << addr; BOOST_CHECK_EQUAL(HexStr(s), "1a1b2a2b3a3b4a4b5a5b6a6b7a7b8a8b"); s.clear(); @@ -370,12 +369,12 @@ BOOST_AUTO_TEST_CASE(cnetaddr_serialize_v2) BOOST_CHECK_EQUAL(HexStr(s), "021000000000000000000000000000000000"); s.clear(); - BOOST_REQUIRE(LookupHost("1.2.3.4", addr, false)); + addr = LookupHost("1.2.3.4", false).value(); s << addr; BOOST_CHECK_EQUAL(HexStr(s), "010401020304"); s.clear(); - BOOST_REQUIRE(LookupHost("1a1b:2a2b:3a3b:4a4b:5a5b:6a6b:7a7b:8a8b", addr, false)); + addr = LookupHost("1a1b:2a2b:3a3b:4a4b:5a5b:6a6b:7a7b:8a8b", false).value(); s << addr; BOOST_CHECK_EQUAL(HexStr(s), "02101a1b2a2b3a3b4a4b5a5b6a6b7a7b8a8b"); s.clear(); diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp index 7e91819ddc..05953bfd10 100644 --- a/src/test/netbase_tests.cpp +++ b/src/test/netbase_tests.cpp @@ -24,9 +24,7 @@ BOOST_FIXTURE_TEST_SUITE(netbase_tests, BasicTestingSetup) static CNetAddr ResolveIP(const std::string& ip) { - CNetAddr addr; - LookupHost(ip, addr, false); - return addr; + return LookupHost(ip, false).value_or(CNetAddr{}); } static CSubNet ResolveSubNet(const std::string& subnet) @@ -477,11 +475,10 @@ BOOST_AUTO_TEST_CASE(netpermissions_test) BOOST_AUTO_TEST_CASE(netbase_dont_resolve_strings_with_embedded_nul_characters) { - CNetAddr addr; - BOOST_CHECK(LookupHost("127.0.0.1"s, addr, false)); - BOOST_CHECK(!LookupHost("127.0.0.1\0"s, addr, false)); - BOOST_CHECK(!LookupHost("127.0.0.1\0example.com"s, addr, false)); - BOOST_CHECK(!LookupHost("127.0.0.1\0example.com\0"s, addr, false)); + BOOST_CHECK(LookupHost("127.0.0.1"s, false).has_value()); + BOOST_CHECK(!LookupHost("127.0.0.1\0"s, false).has_value()); + BOOST_CHECK(!LookupHost("127.0.0.1\0example.com"s, false).has_value()); + BOOST_CHECK(!LookupHost("127.0.0.1\0example.com\0"s, false).has_value()); CSubNet ret; BOOST_CHECK(LookupSubNet("1.2.3.0/24"s, ret)); BOOST_CHECK(!LookupSubNet("1.2.3.0/24\0"s, ret)); diff --git a/src/test/rbf_tests.cpp b/src/test/rbf_tests.cpp index 0ec253747b..10205cd641 100644 --- a/src/test/rbf_tests.cpp +++ b/src/test/rbf_tests.cpp @@ -1,11 +1,11 @@ // Copyright (c) 2021-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. +#include <common/system.h> #include <policy/rbf.h> #include <random.h> #include <test/util/txmempool.h> #include <txmempool.h> -#include <util/system.h> #include <util/time.h> #include <test/util/setup_common.h> diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index d8898743b0..c89f2c1f5b 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -5,6 +5,7 @@ #include <test/data/script_tests.json.h> #include <test/data/bip341_wallet_vectors.json.h> +#include <common/system.h> #include <core_io.h> #include <key.h> #include <rpc/util.h> @@ -20,7 +21,6 @@ #include <test/util/transaction_utils.h> #include <util/fs.h> #include <util/strencodings.h> -#include <util/system.h> #if defined(HAVE_CONSENSUS_LIB) #include <script/bitcoinconsensus.h> diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index e2d11afa6a..68ef719c71 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -2,6 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <common/system.h> #include <consensus/tx_check.h> #include <consensus/validation.h> #include <hash.h> @@ -14,7 +15,6 @@ #include <test/util/random.h> #include <test/util/setup_common.h> #include <util/strencodings.h> -#include <util/system.h> #include <version.h> #include <iostream> diff --git a/src/test/sock_tests.cpp b/src/test/sock_tests.cpp index 9e6f73745e..26ee724bf8 100644 --- a/src/test/sock_tests.cpp +++ b/src/test/sock_tests.cpp @@ -2,10 +2,10 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <common/system.h> #include <compat/compat.h> #include <test/util/setup_common.h> #include <util/sock.h> -#include <util/system.h> #include <util/threadinterrupt.h> #include <boost/test/unit_test.hpp> diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index eedb406cbd..483404779e 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -9,6 +9,7 @@ #include <addrman.h> #include <banman.h> #include <chainparams.h> +#include <common/system.h> #include <common/url.h> #include <consensus/consensus.h> #include <consensus/params.h> @@ -23,6 +24,7 @@ #include <node/blockstorage.h> #include <node/chainstate.h> #include <node/context.h> +#include <node/kernel_notifications.h> #include <node/mempool_args.h> #include <node/miner.h> #include <node/validation_cache_args.h> @@ -45,7 +47,6 @@ #include <util/chaintype.h> #include <util/strencodings.h> #include <util/string.h> -#include <util/system.h> #include <util/thread.h> #include <util/threadnames.h> #include <util/time.h> @@ -64,6 +65,7 @@ using node::ApplyArgsManOptions; using node::BlockAssembler; using node::BlockManager; using node::CalculateCacheSizes; +using node::KernelNotifications; using node::LoadChainstate; using node::RegenerateCommitments; using node::VerifyLoadedChainstate; @@ -182,11 +184,14 @@ ChainTestingSetup::ChainTestingSetup(const ChainType chainType, const std::vecto m_cache_sizes = CalculateCacheSizes(m_args); + m_node.notifications = std::make_unique<KernelNotifications>(); + const ChainstateManager::Options chainman_opts{ .chainparams = chainparams, .datadir = m_args.GetDataDirNet(), .adjusted_time_callback = GetAdjustedTime, .check_block_index = true, + .notifications = *m_node.notifications, }; const BlockManager::Options blockman_opts{ .chainparams = chainman_opts.chainparams, diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 812737429d..26677bfa55 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -1687,7 +1687,7 @@ BOOST_AUTO_TEST_CASE(message_hash) BOOST_AUTO_TEST_CASE(remove_prefix) { - BOOST_CHECK_EQUAL(RemovePrefix("./util/system.h", "./"), "util/system.h"); + BOOST_CHECK_EQUAL(RemovePrefix("./common/system.h", "./"), "common/system.h"); BOOST_CHECK_EQUAL(RemovePrefixView("foo", "foo"), ""); BOOST_CHECK_EQUAL(RemovePrefix("foo", "fo"), "o"); BOOST_CHECK_EQUAL(RemovePrefixView("foo", "f"), "oo"); diff --git a/src/test/validation_chainstatemanager_tests.cpp b/src/test/validation_chainstatemanager_tests.cpp index 05e2787075..8ca4e62e27 100644 --- a/src/test/validation_chainstatemanager_tests.cpp +++ b/src/test/validation_chainstatemanager_tests.cpp @@ -4,6 +4,7 @@ // #include <chainparams.h> #include <consensus/validation.h> +#include <node/kernel_notifications.h> #include <node/utxo_snapshot.h> #include <random.h> #include <rpc/blockchain.h> @@ -23,6 +24,7 @@ #include <boost/test/unit_test.hpp> using node::BlockManager; +using node::KernelNotifications; using node::SnapshotMetadata; BOOST_FIXTURE_TEST_SUITE(validation_chainstatemanager_tests, ChainTestingSetup) @@ -377,10 +379,12 @@ struct SnapshotTestSetup : TestChain100Setup { LOCK(::cs_main); chainman.ResetChainstates(); BOOST_CHECK_EQUAL(chainman.GetAll().size(), 0); + m_node.notifications = std::make_unique<KernelNotifications>(); const ChainstateManager::Options chainman_opts{ .chainparams = ::Params(), .datadir = m_args.GetDataDirNet(), .adjusted_time_callback = GetAdjustedTime, + .notifications = *m_node.notifications, }; const BlockManager::Options blockman_opts{ .chainparams = chainman_opts.chainparams, diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 92b55f9fc4..98d68f93e9 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -133,15 +133,15 @@ bool TorControlConnection::Connect(const std::string& tor_control_center, const Disconnect(); } - CService control_service; - if (!Lookup(tor_control_center, control_service, 9051, fNameLookup)) { + const std::optional<CService> control_service{Lookup(tor_control_center, 9051, fNameLookup)}; + if (!control_service.has_value()) { LogPrintf("tor: Failed to look up control center %s\n", tor_control_center); return false; } struct sockaddr_storage control_address; socklen_t control_address_len = sizeof(control_address); - if (!control_service.GetSockAddr(reinterpret_cast<struct sockaddr*>(&control_address), &control_address_len)) { + if (!control_service.value().GetSockAddr(reinterpret_cast<struct sockaddr*>(&control_address), &control_address_len)) { LogPrintf("tor: Error parsing socket address %s\n", tor_control_center); return false; } diff --git a/src/txdb.h b/src/txdb.h index c92733a22c..04d0ecb39f 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -13,6 +13,9 @@ #include <util/fs.h> #include <util/result.h> +#include <cstddef> +#include <cstdint> +#include <functional> #include <memory> #include <optional> #include <string> @@ -21,11 +24,11 @@ class CBlockFileInfo; class CBlockIndex; +class COutPoint; class uint256; namespace Consensus { struct Params; }; -struct bilingual_str; //! -dbcache default (MiB) static const int64_t nDefaultDbCache = 450; @@ -99,6 +102,6 @@ public: EXCLUSIVE_LOCKS_REQUIRED(::cs_main); }; -util::Result<void> CheckLegacyTxindex(CBlockTreeDB& block_tree_db); +[[nodiscard]] util::Result<void> CheckLegacyTxindex(CBlockTreeDB& block_tree_db); #endif // BITCOIN_TXDB_H diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 6019346eed..1ba110d9cb 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -7,6 +7,7 @@ #include <chain.h> #include <coins.h> +#include <common/system.h> #include <consensus/consensus.h> #include <consensus/tx_verify.h> #include <consensus/validation.h> @@ -19,7 +20,6 @@ #include <util/moneystr.h> #include <util/overflow.h> #include <util/result.h> -#include <util/system.h> #include <util/time.h> #include <util/trace.h> #include <util/translation.h> diff --git a/src/util/any.h b/src/util/any.h new file mode 100644 index 0000000000..4562c5bd8a --- /dev/null +++ b/src/util/any.h @@ -0,0 +1,26 @@ +// Copyright (c) 2023 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_UTIL_ANY_H +#define BITCOIN_UTIL_ANY_H + +#include <any> + +namespace util { + +/** + * Helper function to access the contained object of a std::any instance. + * Returns a pointer to the object if passed instance has a value and the type + * matches, nullptr otherwise. + */ +template<typename T> +T* AnyPtr(const std::any& any) noexcept +{ + T* const* ptr = std::any_cast<T*>(&any); + return ptr ? *ptr : nullptr; +} + +} // namespace util + +#endif // BITCOIN_UTIL_ANY_H diff --git a/src/util/batchpriority.cpp b/src/util/batchpriority.cpp new file mode 100644 index 0000000000..c73aef1eb4 --- /dev/null +++ b/src/util/batchpriority.cpp @@ -0,0 +1,26 @@ +// Copyright (c) 2023 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 <logging.h> +#include <util/syserror.h> + +#if (defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)) +#include <pthread.h> +#include <pthread_np.h> +#endif + +#ifndef WIN32 +#include <sched.h> +#endif + +void ScheduleBatchPriority() +{ +#ifdef SCHED_BATCH + const static sched_param param{}; + const int rc = pthread_setschedparam(pthread_self(), SCHED_BATCH, ¶m); + if (rc != 0) { + LogPrintf("Failed to pthread_setschedparam: %s\n", SysErrorString(rc)); + } +#endif +} diff --git a/src/util/batchpriority.h b/src/util/batchpriority.h new file mode 100644 index 0000000000..5ffc8dd684 --- /dev/null +++ b/src/util/batchpriority.h @@ -0,0 +1,15 @@ +// Copyright (c) 2023 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_UTIL_BATCHPRIORITY_H +#define BITCOIN_UTIL_BATCHPRIORITY_H + +/** + * On platforms that support it, tell the kernel the calling thread is + * CPU-intensive and non-interactive. See SCHED_BATCH in sched(7) for details. + * + */ +void ScheduleBatchPriority(); + +#endif // BITCOIN_UTIL_BATCHPRIORITY_H diff --git a/src/util/insert.h b/src/util/insert.h new file mode 100644 index 0000000000..5332eca60a --- /dev/null +++ b/src/util/insert.h @@ -0,0 +1,24 @@ +// Copyright (c) 2023 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_UTIL_INSERT_H +#define BITCOIN_UTIL_INSERT_H + +#include <set> + +namespace util { + +//! Simplification of std insertion +template <typename Tdst, typename Tsrc> +inline void insert(Tdst& dst, const Tsrc& src) { + dst.insert(dst.begin(), src.begin(), src.end()); +} +template <typename TsetT, typename Tsrc> +inline void insert(std::set<TsetT>& dst, const Tsrc& src) { + dst.insert(src.begin(), src.end()); +} + +} // namespace util + +#endif // BITCOIN_UTIL_INSERT_H diff --git a/src/util/sock.cpp b/src/util/sock.cpp index 53d20bdf19..c83869bc77 100644 --- a/src/util/sock.cpp +++ b/src/util/sock.cpp @@ -2,12 +2,12 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <common/system.h> #include <compat/compat.h> #include <logging.h> #include <tinyformat.h> #include <util/sock.h> #include <util/syserror.h> -#include <util/system.h> #include <util/threadinterrupt.h> #include <util/time.h> diff --git a/src/util/system.h b/src/util/system.h deleted file mode 100644 index e2fc3450f6..0000000000 --- a/src/util/system.h +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto -// 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. - -#ifndef BITCOIN_UTIL_SYSTEM_H -#define BITCOIN_UTIL_SYSTEM_H - -#if defined(HAVE_CONFIG_H) -#include <config/bitcoin-config.h> -#endif - -#include <compat/assumptions.h> -#include <compat/compat.h> - -#include <any> -#include <set> -#include <stdint.h> -#include <string> - -// Application startup time (used for uptime calculation) -int64_t GetStartupTime(); - -void SetupEnvironment(); -bool SetupNetworking(); -#ifndef WIN32 -std::string ShellEscape(const std::string& arg); -#endif -#if HAVE_SYSTEM -void runCommand(const std::string& strCommand); -#endif - -/** - * Return the number of cores available on the current system. - * @note This does count virtual cores, such as those provided by HyperThreading. - */ -int GetNumCores(); - -/** - * On platforms that support it, tell the kernel the calling thread is - * CPU-intensive and non-interactive. See SCHED_BATCH in sched(7) for details. - * - */ -void ScheduleBatchPriority(); - -namespace util { - -//! Simplification of std insertion -template <typename Tdst, typename Tsrc> -inline void insert(Tdst& dst, const Tsrc& src) { - dst.insert(dst.begin(), src.begin(), src.end()); -} -template <typename TsetT, typename Tsrc> -inline void insert(std::set<TsetT>& dst, const Tsrc& src) { - dst.insert(src.begin(), src.end()); -} - -/** - * Helper function to access the contained object of a std::any instance. - * Returns a pointer to the object if passed instance has a value and the type - * matches, nullptr otherwise. - */ -template<typename T> -T* AnyPtr(const std::any& any) noexcept -{ - T* const* ptr = std::any_cast<T*>(&any); - return ptr ? *ptr : nullptr; -} - -} // namespace util - -#endif // BITCOIN_UTIL_SYSTEM_H diff --git a/src/validation.cpp b/src/validation.cpp index e536dfb4eb..5fd2d05447 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -23,10 +23,10 @@ #include <hash.h> #include <kernel/chainparams.h> #include <kernel/mempool_entry.h> +#include <kernel/notifications_interface.h> #include <logging.h> #include <logging/timer.h> #include <node/blockstorage.h> -#include <node/interface_ui.h> #include <node/utxo_snapshot.h> #include <policy/policy.h> #include <policy/rbf.h> @@ -52,7 +52,6 @@ #include <util/moneystr.h> #include <util/rbf.h> #include <util/strencodings.h> -#include <util/system.h> #include <util/time.h> #include <util/trace.h> #include <util/translation.h> @@ -72,6 +71,7 @@ using kernel::CCoinsStats; using kernel::CoinStatsHashType; using kernel::ComputeUTXOStats; using kernel::LoadMempool; +using kernel::Notifications; using fsbridge::FopenFn; using node::BlockManager; @@ -1639,26 +1639,6 @@ bool Chainstate::IsInitialBlockDownload() const return false; } -static void AlertNotify(const std::string& strMessage) -{ - uiInterface.NotifyAlertChanged(); -#if HAVE_SYSTEM - std::string strCmd = gArgs.GetArg("-alertnotify", ""); - if (strCmd.empty()) return; - - // Alert text should be plain ascii coming from a trusted source, but to - // be safe we first strip anything not in safeChars, then add single quotes around - // the whole string before passing it to the shell: - std::string singleQuote("'"); - std::string safeStatus = SanitizeString(strMessage); - safeStatus = singleQuote+safeStatus+singleQuote; - ReplaceAll(strCmd, "%s", safeStatus); - - std::thread t(runCommand, strCmd); - t.detach(); // thread runs free -#endif -} - void Chainstate::CheckForkWarningConditions() { AssertLockHeld(cs_main); @@ -2599,16 +2579,6 @@ void Chainstate::PruneAndFlush() } } -static void DoWarning(const bilingual_str& warning) -{ - static bool fWarned = false; - SetMiscWarning(warning); - if (!fWarned) { - AlertNotify(warning.original); - fWarned = true; - } -} - /** Private helper function that concatenates warning messages. */ static void AppendWarning(bilingual_str& res, const bilingual_str& warn) { @@ -2675,7 +2645,7 @@ void Chainstate::UpdateTip(const CBlockIndex* pindexNew) if (state == ThresholdState::ACTIVE || state == ThresholdState::LOCKED_IN) { const bilingual_str warning = strprintf(_("Unknown new rules activated (versionbit %i)"), bit); if (state == ThresholdState::ACTIVE) { - DoWarning(warning); + m_chainman.GetNotifications().warning(warning); } else { AppendWarning(warning_messages, warning); } @@ -2760,7 +2730,6 @@ bool Chainstate::DisconnectTip(BlockValidationState& state, DisconnectedBlockTra return true; } -static SteadyClock::duration time_read_from_disk_total{}; static SteadyClock::duration time_connect_total{}; static SteadyClock::duration time_flush{}; static SteadyClock::duration time_chainstate{}; @@ -2834,12 +2803,11 @@ bool Chainstate::ConnectTip(BlockValidationState& state, CBlockIndex* pindexNew, const CBlock& blockConnecting = *pthisBlock; // Apply the block atomically to the chain state. const auto time_2{SteadyClock::now()}; - time_read_from_disk_total += time_2 - time_1; SteadyClock::time_point time_3; - LogPrint(BCLog::BENCH, " - Load block from disk: %.2fms [%.2fs (%.2fms/blk)]\n", - Ticks<MillisecondsDouble>(time_2 - time_1), - Ticks<SecondsDouble>(time_read_from_disk_total), - Ticks<MillisecondsDouble>(time_read_from_disk_total) / num_blocks_total); + // When adding aggregate statistics in the future, keep in mind that + // num_blocks_total may be zero until the ConnectBlock() call below. + LogPrint(BCLog::BENCH, " - Load block from disk: %.2fms\n", + Ticks<MillisecondsDouble>(time_2 - time_1)); { CCoinsViewCache view(&CoinsTip()); bool rv = ConnectBlock(blockConnecting, state, pindexNew, view); @@ -3097,7 +3065,7 @@ static bool NotifyHeaderTip(Chainstate& chainstate) LOCKS_EXCLUDED(cs_main) { } // Send block tip changed notifications without cs_main if (fNotify) { - uiInterface.NotifyHeaderTip(GetSynchronizationState(fInitialBlockDownload), pindexHeader->nHeight, pindexHeader->nTime, false); + chainstate.m_chainman.GetNotifications().headerTip(GetSynchronizationState(fInitialBlockDownload), pindexHeader->nHeight, pindexHeader->nTime, false); } return fNotify; } @@ -3206,7 +3174,7 @@ bool Chainstate::ActivateBestChain(BlockValidationState& state, std::shared_ptr< GetMainSignals().UpdatedBlockTip(pindexNewTip, pindexFork, fInitialDownload); // Always notify the UI if a new block tip was connected - uiInterface.NotifyBlockTip(GetSynchronizationState(fInitialDownload), pindexNewTip); + m_chainman.GetNotifications().blockTip(GetSynchronizationState(fInitialDownload), *pindexNewTip); } } // When we reach this point, we switched to a new tip (stored in pindexNewTip). @@ -3403,7 +3371,7 @@ bool Chainstate::InvalidateBlock(BlockValidationState& state, CBlockIndex* pinde // Only notify about a new block tip if the active chain was modified. if (pindex_was_in_chain) { - uiInterface.NotifyBlockTip(GetSynchronizationState(IsInitialBlockDownload()), to_mark_failed->pprev); + m_chainman.GetNotifications().blockTip(GetSynchronizationState(IsInitialBlockDownload()), *to_mark_failed->pprev); } return true; } @@ -3920,7 +3888,7 @@ void ChainstateManager::ReportHeadersPresync(const arith_uint256& work, int64_t m_last_presync_update = now; } bool initial_download = chainstate.IsInitialBlockDownload(); - uiInterface.NotifyHeaderTip(GetSynchronizationState(initial_download), height, timestamp, /*presync=*/true); + GetNotifications().headerTip(GetSynchronizationState(initial_download), height, timestamp, /*presync=*/true); if (initial_download) { const int64_t blocks_left{(GetTime() - timestamp) / GetConsensus().nPowTargetSpacing}; const double progress{100.0 * height / (height + blocks_left)}; @@ -4145,14 +4113,15 @@ bool Chainstate::LoadChainTip() return true; } -CVerifyDB::CVerifyDB() +CVerifyDB::CVerifyDB(Notifications& notifications) + : m_notifications{notifications} { - uiInterface.ShowProgress(_("Verifying blocks…").translated, 0, false); + m_notifications.progress(_("Verifying blocks…"), 0, false); } CVerifyDB::~CVerifyDB() { - uiInterface.ShowProgress("", 100, false); + m_notifications.progress(bilingual_str{}, 100, false); } VerifyDBResult CVerifyDB::VerifyDB( @@ -4192,7 +4161,7 @@ VerifyDBResult CVerifyDB::VerifyDB( LogPrintf("Verification progress: %d%%\n", percentageDone); reportDone = percentageDone / 10; } - uiInterface.ShowProgress(_("Verifying blocks…").translated, percentageDone, false); + m_notifications.progress(_("Verifying blocks…"), percentageDone, false); if (pindex->nHeight <= chainstate.m_chain.Height() - nCheckDepth) { break; } @@ -4268,7 +4237,7 @@ VerifyDBResult CVerifyDB::VerifyDB( LogPrintf("Verification progress: %d%%\n", percentageDone); reportDone = percentageDone / 10; } - uiInterface.ShowProgress(_("Verifying blocks…").translated, percentageDone, false); + m_notifications.progress(_("Verifying blocks…"), percentageDone, false); pindex = chainstate.m_chain.Next(pindex); CBlock block; if (!chainstate.m_blockman.ReadBlockFromDisk(block, *pindex)) { @@ -4327,7 +4296,7 @@ bool Chainstate::ReplayBlocks() if (hashHeads.empty()) return true; // We're already in a consistent state. if (hashHeads.size() != 2) return error("ReplayBlocks(): unknown inconsistent state"); - uiInterface.ShowProgress(_("Replaying blocks…").translated, 0, false); + m_chainman.GetNotifications().progress(_("Replaying blocks…"), 0, false); LogPrintf("Replaying blocks\n"); const CBlockIndex* pindexOld = nullptr; // Old tip during the interrupted flush. @@ -4374,13 +4343,13 @@ bool Chainstate::ReplayBlocks() const CBlockIndex& pindex{*Assert(pindexNew->GetAncestor(nHeight))}; LogPrintf("Rolling forward %s (%i)\n", pindex.GetBlockHash().ToString(), nHeight); - uiInterface.ShowProgress(_("Replaying blocks…").translated, (int) ((nHeight - nForkHeight) * 100.0 / (pindexNew->nHeight - nForkHeight)) , false); + m_chainman.GetNotifications().progress(_("Replaying blocks…"), (int)((nHeight - nForkHeight) * 100.0 / (pindexNew->nHeight - nForkHeight)), false); if (!RollforwardBlock(&pindex, cache)) return false; } cache.SetBestBlock(pindexNew->GetBlockHash()); cache.Flush(); - uiInterface.ShowProgress("", 100, false); + m_chainman.GetNotifications().progress(bilingual_str{}, 100, false); return true; } diff --git a/src/validation.h b/src/validation.h index fd0e2115f7..444fe72db4 100644 --- a/src/validation.h +++ b/src/validation.h @@ -364,9 +364,13 @@ enum class VerifyDBResult { }; /** RAII wrapper for VerifyDB: Verify consistency of the block and coin databases */ -class CVerifyDB { +class CVerifyDB +{ +private: + kernel::Notifications& m_notifications; + public: - CVerifyDB(); + explicit CVerifyDB(kernel::Notifications& notifications); ~CVerifyDB(); [[nodiscard]] VerifyDBResult VerifyDB( Chainstate& chainstate, @@ -955,6 +959,7 @@ public: bool ShouldCheckBlockIndex() const { return *Assert(m_options.check_block_index); } const arith_uint256& MinimumChainWork() const { return *Assert(m_options.minimum_chain_work); } const uint256& AssumedValidBlock() const { return *Assert(m_options.assumed_valid_block); } + kernel::Notifications& GetNotifications() const { return m_options.notifications; }; /** * Alias for ::cs_main. diff --git a/src/version.h b/src/version.h index ee646eefc3..611a670314 100644 --- a/src/version.h +++ b/src/version.h @@ -20,9 +20,6 @@ static const int MIN_PEER_PROTO_VERSION = 31800; //! BIP 0031, pong message, is enabled for all versions AFTER this one static const int BIP0031_VERSION = 60000; -//! "filter*" commands are disabled without NODE_BLOOM after and including this version -static const int NO_BLOOM_VERSION = 70011; - //! "sendheaders" command and announcing blocks with headers starts with this version static const int SENDHEADERS_VERSION = 70012; diff --git a/src/wallet/bdb.h b/src/wallet/bdb.h index 9134643b23..e8a57e8a5e 100644 --- a/src/wallet/bdb.h +++ b/src/wallet/bdb.h @@ -7,10 +7,10 @@ #define BITCOIN_WALLET_BDB_H #include <clientversion.h> +#include <common/system.h> #include <serialize.h> #include <streams.h> #include <util/fs.h> -#include <util/system.h> #include <wallet/db.h> #include <atomic> diff --git a/src/wallet/coinselection.cpp b/src/wallet/coinselection.cpp index 832d24746f..bd74025f09 100644 --- a/src/wallet/coinselection.cpp +++ b/src/wallet/coinselection.cpp @@ -4,13 +4,13 @@ #include <wallet/coinselection.h> +#include <common/system.h> #include <consensus/amount.h> #include <consensus/consensus.h> #include <logging.h> #include <policy/feerate.h> #include <util/check.h> #include <util/moneystr.h> -#include <util/system.h> #include <numeric> #include <optional> diff --git a/src/wallet/coinselection.h b/src/wallet/coinselection.h index 723f5bbfb3..432d7d1431 100644 --- a/src/wallet/coinselection.h +++ b/src/wallet/coinselection.h @@ -11,8 +11,8 @@ #include <policy/feerate.h> #include <primitives/transaction.h> #include <random.h> -#include <util/system.h> #include <util/check.h> +#include <util/insert.h> #include <util/result.h> #include <optional> diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp index cd414b3d44..e2799c2d05 100644 --- a/src/wallet/crypter.cpp +++ b/src/wallet/crypter.cpp @@ -4,9 +4,9 @@ #include <wallet/crypter.h> +#include <common/system.h> #include <crypto/aes.h> #include <crypto/sha512.h> -#include <util/system.h> #include <vector> diff --git a/src/wallet/external_signer_scriptpubkeyman.cpp b/src/wallet/external_signer_scriptpubkeyman.cpp index e2852c5d52..6d026d02c1 100644 --- a/src/wallet/external_signer_scriptpubkeyman.cpp +++ b/src/wallet/external_signer_scriptpubkeyman.cpp @@ -4,8 +4,8 @@ #include <chainparams.h> #include <common/args.h> +#include <common/system.h> #include <external_signer.h> -#include <util/system.h> #include <wallet/external_signer_scriptpubkeyman.h> #include <iostream> diff --git a/src/wallet/feebumper.cpp b/src/wallet/feebumper.cpp index b6b1fa1d3e..0e1f1f9847 100644 --- a/src/wallet/feebumper.cpp +++ b/src/wallet/feebumper.cpp @@ -2,13 +2,13 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <common/system.h> #include <consensus/validation.h> #include <interfaces/chain.h> #include <policy/fees.h> #include <policy/policy.h> #include <util/moneystr.h> #include <util/rbf.h> -#include <util/system.h> #include <util/translation.h> #include <wallet/coincontrol.h> #include <wallet/feebumper.h> diff --git a/src/wallet/rpc/util.cpp b/src/wallet/rpc/util.cpp index 4ff44b84b0..06ec7db1bc 100644 --- a/src/wallet/rpc/util.cpp +++ b/src/wallet/rpc/util.cpp @@ -6,7 +6,7 @@ #include <common/url.h> #include <rpc/util.h> -#include <util/system.h> +#include <util/any.h> #include <util/translation.h> #include <wallet/context.h> #include <wallet/wallet.h> diff --git a/src/wallet/scriptpubkeyman.h b/src/wallet/scriptpubkeyman.h index 5c7240823f..bf35c776ae 100644 --- a/src/wallet/scriptpubkeyman.h +++ b/src/wallet/scriptpubkeyman.h @@ -5,6 +5,7 @@ #ifndef BITCOIN_WALLET_SCRIPTPUBKEYMAN_H #define BITCOIN_WALLET_SCRIPTPUBKEYMAN_H +#include <logging.h> #include <psbt.h> #include <script/descriptor.h> #include <script/signingprovider.h> @@ -27,6 +28,8 @@ enum class OutputType; struct bilingual_str; namespace wallet { +struct MigrationData; + // Wallet storage things that ScriptPubKeyMans need in order to be able to store things to the wallet database. // It provides access to things that are part of the entire wallet and not specific to a ScriptPubKeyMan such as // wallet flags, wallet version, encryption keys, encryption status, and the database itself. This allows a @@ -661,6 +664,18 @@ public: void UpgradeDescriptorCache(); }; + +/** struct containing information needed for migrating legacy wallets to descriptor wallets */ +struct MigrationData +{ + CExtKey master_key; + std::vector<std::pair<std::string, int64_t>> watch_descs; + std::vector<std::pair<std::string, int64_t>> solvable_descs; + std::vector<std::unique_ptr<DescriptorScriptPubKeyMan>> desc_spkms; + std::shared_ptr<CWallet> watchonly_wallet{nullptr}; + std::shared_ptr<CWallet> solvable_wallet{nullptr}; +}; + } // namespace wallet #endif // BITCOIN_WALLET_SCRIPTPUBKEYMAN_H diff --git a/src/wallet/spend.cpp b/src/wallet/spend.cpp index b14a30921b..99c6582f9c 100644 --- a/src/wallet/spend.cpp +++ b/src/wallet/spend.cpp @@ -4,6 +4,7 @@ #include <algorithm> #include <common/args.h> +#include <common/system.h> #include <consensus/amount.h> #include <consensus/validation.h> #include <interfaces/chain.h> @@ -15,7 +16,6 @@ #include <util/fees.h> #include <util/moneystr.h> #include <util/rbf.h> -#include <util/system.h> #include <util/trace.h> #include <util/translation.h> #include <wallet/coincontrol.h> diff --git a/src/wallet/test/fuzz/notifications.cpp b/src/wallet/test/fuzz/notifications.cpp index de381a5ec9..f4b69f7403 100644 --- a/src/wallet/test/fuzz/notifications.cpp +++ b/src/wallet/test/fuzz/notifications.cpp @@ -141,6 +141,10 @@ FUZZ_TARGET_INIT(wallet_notifications, initialize_setup) info.prev_hash = &block.hashPrevBlock; info.height = chain.size(); info.data = █ + // Ensure that no blocks are skipped by the wallet by setting the chain's accumulated + // time to the maximum value. This ensures that the wallet's birth time is always + // earlier than this maximum time. + info.chain_time_max = std::numeric_limits<unsigned int>::max(); a.wallet->blockConnected(info); b.wallet->blockConnected(info); // Store the coins for the next block diff --git a/src/wallet/test/util.cpp b/src/wallet/test/util.cpp index 09e7979c02..eacb70cd69 100644 --- a/src/wallet/test/util.cpp +++ b/src/wallet/test/util.cpp @@ -9,6 +9,7 @@ #include <key_io.h> #include <streams.h> #include <test/util/setup_common.h> +#include <wallet/context.h> #include <wallet/wallet.h> #include <wallet/walletdb.h> @@ -45,6 +46,36 @@ std::unique_ptr<CWallet> CreateSyncedWallet(interfaces::Chain& chain, CChain& cc return wallet; } +std::shared_ptr<CWallet> TestLoadWallet(std::unique_ptr<WalletDatabase> database, WalletContext& context, uint64_t create_flags) +{ + bilingual_str error; + std::vector<bilingual_str> warnings; + auto wallet = CWallet::Create(context, "", std::move(database), create_flags, error, warnings); + NotifyWalletLoaded(context, wallet); + if (context.chain) { + wallet->postInitProcess(); + } + return wallet; +} + +std::shared_ptr<CWallet> TestLoadWallet(WalletContext& context) +{ + DatabaseOptions options; + options.create_flags = WALLET_FLAG_DESCRIPTORS; + DatabaseStatus status; + bilingual_str error; + std::vector<bilingual_str> warnings; + auto database = MakeWalletDatabase("", options, status, error); + return TestLoadWallet(std::move(database), context, options.create_flags); +} + +void TestUnloadWallet(std::shared_ptr<CWallet>&& wallet) +{ + SyncWithValidationInterfaceQueue(); + wallet->m_chain_notifications_handler.reset(); + UnloadWallet(std::move(wallet)); +} + std::unique_ptr<WalletDatabase> DuplicateMockDatabase(WalletDatabase& database) { return std::make_unique<MockableDatabase>(dynamic_cast<MockableDatabase&>(database).m_records); diff --git a/src/wallet/test/util.h b/src/wallet/test/util.h index eb1cfd9e21..b1ad1c959b 100644 --- a/src/wallet/test/util.h +++ b/src/wallet/test/util.h @@ -21,6 +21,7 @@ class Chain; namespace wallet { class CWallet; class WalletDatabase; +struct WalletContext; static const DatabaseFormat DATABASE_FORMATS[] = { #ifdef USE_SQLITE @@ -31,8 +32,14 @@ static const DatabaseFormat DATABASE_FORMATS[] = { #endif }; +const std::string ADDRESS_BCRT1_UNSPENDABLE = "bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3xueyj"; + std::unique_ptr<CWallet> CreateSyncedWallet(interfaces::Chain& chain, CChain& cchain, const CKey& key); +std::shared_ptr<CWallet> TestLoadWallet(WalletContext& context); +std::shared_ptr<CWallet> TestLoadWallet(std::unique_ptr<WalletDatabase> database, WalletContext& context, uint64_t create_flags); +void TestUnloadWallet(std::shared_ptr<CWallet>&& wallet); + // Creates a copy of the provided database std::unique_ptr<WalletDatabase> DuplicateMockDatabase(WalletDatabase& database); diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index 194c8663db..cb1be9ea5b 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -42,26 +42,6 @@ static_assert(WALLET_INCREMENTAL_RELAY_FEE >= DEFAULT_INCREMENTAL_RELAY_FEE, "wa BOOST_FIXTURE_TEST_SUITE(wallet_tests, WalletTestingSetup) -static std::shared_ptr<CWallet> TestLoadWallet(WalletContext& context) -{ - DatabaseOptions options; - options.create_flags = WALLET_FLAG_DESCRIPTORS; - DatabaseStatus status; - bilingual_str error; - std::vector<bilingual_str> warnings; - auto database = MakeWalletDatabase("", options, status, error); - auto wallet = CWallet::Create(context, "", std::move(database), options.create_flags, error, warnings); - NotifyWalletLoaded(context, wallet); - return wallet; -} - -static void TestUnloadWallet(std::shared_ptr<CWallet>&& wallet) -{ - SyncWithValidationInterfaceQueue(); - wallet->m_chain_notifications_handler.reset(); - UnloadWallet(std::move(wallet)); -} - static CMutableTransaction TestSimpleSpend(const CTransaction& from, uint32_t index, const CKey& key, const CScript& pubkey) { CMutableTransaction mtx; @@ -845,10 +825,11 @@ BOOST_FIXTURE_TEST_CASE(CreateWallet, TestChain100Setup) // Reload wallet and make sure new transactions are detected despite events // being blocked + // Loading will also ask for current mempool transactions wallet = TestLoadWallet(context); BOOST_CHECK(rescan_completed); - // AddToWallet events for block_tx and mempool_tx - BOOST_CHECK_EQUAL(addtx_count, 2); + // AddToWallet events for block_tx and mempool_tx (x2) + BOOST_CHECK_EQUAL(addtx_count, 3); { LOCK(wallet->cs_wallet); BOOST_CHECK_EQUAL(wallet->mapWallet.count(block_tx.GetHash()), 1U); @@ -862,7 +843,7 @@ BOOST_FIXTURE_TEST_CASE(CreateWallet, TestChain100Setup) SyncWithValidationInterfaceQueue(); // AddToWallet events for block_tx and mempool_tx events are counted a // second time as the notification queue is processed - BOOST_CHECK_EQUAL(addtx_count, 4); + BOOST_CHECK_EQUAL(addtx_count, 5); TestUnloadWallet(std::move(wallet)); @@ -885,7 +866,9 @@ BOOST_FIXTURE_TEST_CASE(CreateWallet, TestChain100Setup) SyncWithValidationInterfaceQueue(); }); wallet = TestLoadWallet(context); - BOOST_CHECK_EQUAL(addtx_count, 2); + // Since mempool transactions are requested at the end of loading, there will + // be 2 additional AddToWallet calls, one from the previous test, and a duplicate for mempool_tx + BOOST_CHECK_EQUAL(addtx_count, 2 + 2); { LOCK(wallet->cs_wallet); BOOST_CHECK_EQUAL(wallet->mapWallet.count(block_tx.GetHash()), 1U); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 0b241c4ef4..63ace5c47f 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -42,6 +42,7 @@ #include <wallet/context.h> #include <wallet/external_signer_scriptpubkeyman.h> #include <wallet/fees.h> +#include <wallet/scriptpubkeyman.h> #include <univalue.h> diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 7bf7264568..cbd5008366 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1074,7 +1074,7 @@ struct MigrationResult { }; //! Do all steps to migrate a legacy wallet to a descriptor wallet -util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& wallet_name, const SecureString& passphrase, WalletContext& context); +[[nodiscard]] util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& wallet_name, const SecureString& passphrase, WalletContext& context); } // namespace wallet #endif // BITCOIN_WALLET_WALLET_H diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index ddabdac99f..34fe8ab17f 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -5,13 +5,13 @@ #include <wallet/walletdb.h> +#include <common/system.h> #include <key_io.h> #include <protocol.h> #include <serialize.h> #include <sync.h> #include <util/bip32.h> #include <util/fs.h> -#include <util/system.h> #include <util/time.h> #include <util/translation.h> #ifdef USE_BDB diff --git a/src/wallet/walletutil.h b/src/wallet/walletutil.h index f639078de5..3f0c1228e3 100644 --- a/src/wallet/walletutil.h +++ b/src/wallet/walletutil.h @@ -104,20 +104,6 @@ public: WalletDescriptor() {} WalletDescriptor(std::shared_ptr<Descriptor> descriptor, uint64_t creation_time, int32_t range_start, int32_t range_end, int32_t next_index) : descriptor(descriptor), creation_time(creation_time), range_start(range_start), range_end(range_end), next_index(next_index) {} }; - -class CWallet; -class DescriptorScriptPubKeyMan; - -/** struct containing information needed for migrating legacy wallets to descriptor wallets */ -struct MigrationData -{ - CExtKey master_key; - std::vector<std::pair<std::string, int64_t>> watch_descs; - std::vector<std::pair<std::string, int64_t>> solvable_descs; - std::vector<std::unique_ptr<DescriptorScriptPubKeyMan>> desc_spkms; - std::shared_ptr<CWallet> watchonly_wallet{nullptr}; - std::shared_ptr<CWallet> solvable_wallet{nullptr}; -}; } // namespace wallet #endif // BITCOIN_WALLET_WALLETUTIL_H diff --git a/src/warnings.cpp b/src/warnings.cpp index d0de706953..cb73c7aea2 100644 --- a/src/warnings.cpp +++ b/src/warnings.cpp @@ -5,9 +5,9 @@ #include <warnings.h> +#include <common/system.h> #include <sync.h> #include <util/string.h> -#include <util/system.h> #include <util/translation.h> #include <vector> diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp index 21aa44c309..1241431523 100644 --- a/src/zmq/zmqpublishnotifier.cpp +++ b/src/zmq/zmqpublishnotifier.cpp @@ -97,9 +97,8 @@ static bool IsZMQAddressIPV6(const std::string &zmq_address) const size_t colon_index = zmq_address.rfind(':'); if (tcp_index == 0 && colon_index != std::string::npos) { const std::string ip = zmq_address.substr(tcp_prefix.length(), colon_index - tcp_prefix.length()); - CNetAddr addr; - LookupHost(ip, addr, false); - if (addr.IsIPv6()) return true; + const std::optional<CNetAddr> addr{LookupHost(ip, false)}; + if (addr.has_value() && addr.value().IsIPv6()) return true; } return false; } |