diff --git a/src/coins.cpp b/src/coins.cpp index d43e886b7603..b152fe07dec6 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -352,11 +352,13 @@ const Coin& AccessByTxid(const CCoinsViewCache& view, const uint256& txid) return coinEmpty; } -bool CCoinsViewErrorCatcher::GetCoin(const COutPoint &outpoint, Coin &coin) const { +template +static bool ExecuteBackedWrapper(Func func, const std::vector>& err_callbacks) +{ try { - return CCoinsViewBacked::GetCoin(outpoint, coin); + return func(); } catch(const std::runtime_error& e) { - for (const auto& f : m_err_callbacks) { + for (const auto& f : err_callbacks) { f(); } LogPrintf("Error reading from database: %s\n", e.what()); @@ -367,3 +369,11 @@ bool CCoinsViewErrorCatcher::GetCoin(const COutPoint &outpoint, Coin &coin) cons std::abort(); } } + +bool CCoinsViewErrorCatcher::GetCoin(const COutPoint &outpoint, Coin &coin) const { + return ExecuteBackedWrapper([&]() { return CCoinsViewBacked::GetCoin(outpoint, coin); }, m_err_callbacks); +} + +bool CCoinsViewErrorCatcher::HaveCoin(const COutPoint &outpoint) const { + return ExecuteBackedWrapper([&]() { return CCoinsViewBacked::HaveCoin(outpoint); }, m_err_callbacks); +} diff --git a/src/coins.h b/src/coins.h index dedfeb74d1dc..9f314f1a81af 100644 --- a/src/coins.h +++ b/src/coins.h @@ -382,6 +382,7 @@ class CCoinsViewErrorCatcher final : public CCoinsViewBacked } bool GetCoin(const COutPoint &outpoint, Coin &coin) const override; + bool HaveCoin(const COutPoint &outpoint) const override; private: /** A list of callbacks to execute upon leveldb read error. */ diff --git a/src/init.cpp b/src/init.cpp index db99f54a42a3..bba44889b086 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1549,6 +1549,15 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) RandAddPeriodic(); }, std::chrono::minutes{1}); + // Check disk space every 5 minutes to avoid db corruption. + node.scheduler->scheduleEvery([&args]{ + constexpr uint64_t min_disk_space = 50 << 20; // 50 MB + if (!CheckDiskSpace(args.GetBlocksDirPath(), min_disk_space)) { + LogPrintf("Shutting down due to lack of disk space!\n"); + StartShutdown(); + } + }, std::chrono::minutes{5}); + GetMainSignals().RegisterBackgroundSignalScheduler(*node.scheduler); // Create client interfaces for wallets that are supposed to be loaded diff --git a/src/test/fuzz/transaction.cpp b/src/test/fuzz/transaction.cpp index 86131de22976..8a823d21896e 100644 --- a/src/test/fuzz/transaction.cpp +++ b/src/test/fuzz/transaction.cpp @@ -93,10 +93,14 @@ FUZZ_TARGET(transaction, .init = initialize_transaction) const CCoinsViewCache coins_view_cache(&coins_view); (void)AreInputsStandard(tx, coins_view_cache); - UniValue u(UniValue::VOBJ); - TxToUniv(tx, /*block_hash=*/uint256::ZERO, /*entry=*/u); - TxToUniv(tx, /*block_hash=*/uint256::ONE, /*entry=*/u); - -// TxToUniv(tx, /*block_hash=*/uint256::ZERO, /*include_addresses=*/true, u); -// TxToUniv(tx, /*block_hash=*/uint256::ONE, /*include_addresses=*/false, u); + if (tx.GetTotalSize() < 250'000) { // Avoid high memory usage (with msan) due to json encoding + { + UniValue u{UniValue::VOBJ}; + TxToUniv(tx, /*block_hash=*/uint256::ZERO, /*entry=*/u); + } + { + UniValue u{UniValue::VOBJ}; + TxToUniv(tx, /*block_hash=*/uint256::ONE, /*entry=*/u); + } + } } diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index 9847e4b2f913..1f2edd616f02 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -156,6 +157,15 @@ void DashChainstateSetupClose(NodeContext& node) Assert(node.mempool.get())); } +struct NetworkSetup +{ + NetworkSetup() + { + Assert(SetupNetworking()); + } +}; +static NetworkSetup g_networksetup_instance; + BasicTestingSetup::BasicTestingSetup(const std::string& chainName, const std::vector& extra_args) : m_path_root{fs::temp_directory_path() / "test_common_" PACKAGE_NAME / g_insecure_rand_ctx_temp_path.rand256().ToString()}, m_args{} @@ -201,7 +211,6 @@ BasicTestingSetup::BasicTestingSetup(const std::string& chainName, const std::ve ECC_Start(); BLSInit(); SetupEnvironment(); - SetupNetworking(); InitSignatureCache(); InitScriptExecutionCache(); diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 2da64caf6576..ef5fd3e5b316 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -1232,6 +1232,9 @@ BOOST_AUTO_TEST_CASE(test_LockDirectory) // has released the lock as we would expect by probing it. int processstatus; BOOST_CHECK_EQUAL(write(fd[1], &LockCommand, 1), 1); + // The following line invokes the ~CNetCleanup dtor without + // a paired SetupNetworking call. This is acceptable as long as + // ~CNetCleanup is a no-op for non-Windows platforms. BOOST_CHECK_EQUAL(write(fd[1], &ExitCommand, 1), 1); BOOST_CHECK_EQUAL(waitpid(pid, &processstatus, 0), pid); BOOST_CHECK_EQUAL(processstatus, 0); diff --git a/src/util/system.h b/src/util/system.h index 08722d5f57bc..d3450cee5dd1 100644 --- a/src/util/system.h +++ b/src/util/system.h @@ -47,7 +47,7 @@ extern const char * const BITCOIN_CONF_FILENAME; extern const char * const BITCOIN_SETTINGS_FILENAME; void SetupEnvironment(); -bool SetupNetworking(); +[[nodiscard]] bool SetupNetworking(); template bool error(const char* fmt, const Args&... args) diff --git a/src/wallet/test/fuzz/notifications.cpp b/src/wallet/test/fuzz/notifications.cpp index daa9d5a8aa09..62c951c7a371 100644 --- a/src/wallet/test/fuzz/notifications.cpp +++ b/src/wallet/test/fuzz/notifications.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021 The Bitcoin Core developers +// Copyright (c) 2021-present The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -84,7 +84,7 @@ FUZZ_TARGET(wallet_notifications, .init = initialize_setup) // The total amount, to be distributed to the wallets a and b in txs // without fee. Thus, the balance of the wallets should always equal the // total amount. - const auto total_amount{ConsumeMoney(fuzzed_data_provider)}; + const auto total_amount{ConsumeMoney(fuzzed_data_provider, /*max=*/MAX_MONEY / 100000)}; FuzzedWallet a{"fuzzed_wallet_a"}; FuzzedWallet b{"fuzzed_wallet_b"}; diff --git a/test/functional/mempool_package_limits.py b/test/functional/mempool_package_limits.py index 9df8899895b8..330887ec22ac 100755 --- a/test/functional/mempool_package_limits.py +++ b/test/functional/mempool_package_limits.py @@ -46,8 +46,7 @@ def set_test_params(self): def run_test(self): self.wallet = MiniWallet(self.nodes[0]) # Add enough mature utxos to the wallet so that all txs spend confirmed coins. - self.generate(self.wallet, 35) - self.generate(self.nodes[0], COINBASE_MATURITY) + self.generate(self.wallet, COINBASE_MATURITY + 35) self.test_chain_limits() self.test_desc_count_limits()