diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.test.include | 1 | ||||
-rw-r--r-- | src/crypto/sha256_arm_shani.cpp | 2 | ||||
-rw-r--r-- | src/fs.h | 22 | ||||
-rw-r--r-- | src/index/base.cpp | 5 | ||||
-rw-r--r-- | src/index/coinstatsindex.cpp | 4 | ||||
-rw-r--r-- | src/node/blockstorage.cpp | 2 | ||||
-rw-r--r-- | src/test/dbwrapper_tests.cpp | 4 | ||||
-rw-r--r-- | src/test/fs_tests.cpp | 60 | ||||
-rw-r--r-- | src/test/fuzz/script.cpp | 8 | ||||
-rw-r--r-- | src/test/fuzz/script_format.cpp | 30 | ||||
-rw-r--r-- | src/util/system.cpp | 11 | ||||
-rw-r--r-- | src/validation.cpp | 62 | ||||
-rw-r--r-- | src/validation.h | 14 | ||||
-rw-r--r-- | src/wallet/test/wallet_tests.cpp | 2 |
14 files changed, 196 insertions, 31 deletions
diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 1763dcb562..e2e08468a7 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -294,6 +294,7 @@ test_fuzz_fuzz_SOURCES = \ test/fuzz/script_bitcoin_consensus.cpp \ test/fuzz/script_descriptor_cache.cpp \ test/fuzz/script_flags.cpp \ + test/fuzz/script_format.cpp \ test/fuzz/script_interpreter.cpp \ test/fuzz/script_ops.cpp \ test/fuzz/script_sigcache.cpp \ diff --git a/src/crypto/sha256_arm_shani.cpp b/src/crypto/sha256_arm_shani.cpp index 7ffa56be70..2ea1d9c2ac 100644 --- a/src/crypto/sha256_arm_shani.cpp +++ b/src/crypto/sha256_arm_shani.cpp @@ -62,7 +62,7 @@ void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks) MSG3 = vreinterpretq_u32_u8(vrev32q_u8(vld1q_u8(chunk + 48))); chunk += 64; - // Original implemenation preloaded message and constant addition which was 1-3% slower. + // Original implementation preloaded message and constant addition which was 1-3% slower. // Now included as first step in quad round code saving one Q Neon register // "TMP0 = vaddq_u32(MSG0, vld1q_u32(&K[0]));" @@ -140,6 +140,28 @@ static inline path PathFromString(const std::string& string) return std::filesystem::path(string); #endif } + +/** + * Create directory (and if necessary its parents), unless the leaf directory + * already exists or is a symlink to an existing directory. + * This is a temporary workaround for an issue in libstdc++ that has been fixed + * upstream [PR101510]. + */ +static inline bool create_directories(const std::filesystem::path& p) +{ + if (std::filesystem::is_symlink(p) && std::filesystem::is_directory(p)) { + return false; + } + return std::filesystem::create_directories(p); +} + +/** + * This variant is not used. Delete it to prevent it from accidentally working + * around the workaround. If it is needed, add a workaround in the same pattern + * as above. + */ +bool create_directories(const std::filesystem::path& p, std::error_code& ec) = delete; + } // namespace fs /** Bridge operations to C stdio */ diff --git a/src/index/base.cpp b/src/index/base.cpp index 2e3d500cd1..8fe30f8960 100644 --- a/src/index/base.cpp +++ b/src/index/base.cpp @@ -211,6 +211,11 @@ bool BaseIndex::Commit() bool BaseIndex::CommitInternal(CDBBatch& batch) { LOCK(cs_main); + // Don't commit anything if we haven't indexed any block yet + // (this could happen if init is interrupted). + if (m_best_block_index == nullptr) { + return false; + } GetDB().WriteBestBlock(batch, m_chainstate->m_chain.GetLocator(m_best_block_index)); return true; } diff --git a/src/index/coinstatsindex.cpp b/src/index/coinstatsindex.cpp index ef247dc119..7d4860b20b 100644 --- a/src/index/coinstatsindex.cpp +++ b/src/index/coinstatsindex.cpp @@ -360,9 +360,9 @@ bool CoinStatsIndex::Init() if (pindex) { DBVal entry; if (!LookUpOne(*m_db, pindex, entry)) { - return false; + return error("%s: Cannot read current %s state; index may be corrupted", + __func__, GetName()); } - m_transaction_output_count = entry.transaction_output_count; m_bogo_size = entry.bogo_size; m_total_amount = entry.total_amount; diff --git a/src/node/blockstorage.cpp b/src/node/blockstorage.cpp index 7691c9a5ce..8a99130fd0 100644 --- a/src/node/blockstorage.cpp +++ b/src/node/blockstorage.cpp @@ -295,7 +295,7 @@ bool BlockManager::LoadBlockIndex( // them from the background chainstate's setBlockIndexCandidates set. This // does mean that some blocks which are not technically assumed-valid // (later blocks on a fork beginning before the first assumed-valid block) - // might not get added to the the background chainstate, but this is ok, + // might not get added to the background chainstate, but this is ok, // because they will still be attached to the active chainstate if they // actually contain more work. // diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp index 2f95cc27a3..fc89fe1450 100644 --- a/src/test/dbwrapper_tests.cpp +++ b/src/test/dbwrapper_tests.cpp @@ -203,7 +203,7 @@ BOOST_AUTO_TEST_CASE(existing_data_no_obfuscate) { // We're going to share this fs::path between two wrappers fs::path ph = m_args.GetDataDirBase() / "existing_data_no_obfuscate"; - create_directories(ph); + fs::create_directories(ph); // Set up a non-obfuscated wrapper to write some initial data. std::unique_ptr<CDBWrapper> dbw = std::make_unique<CDBWrapper>(ph, (1 << 10), false, false, false); @@ -244,7 +244,7 @@ BOOST_AUTO_TEST_CASE(existing_data_reindex) { // We're going to share this fs::path between two wrappers fs::path ph = m_args.GetDataDirBase() / "existing_data_reindex"; - create_directories(ph); + fs::create_directories(ph); // Set up a non-obfuscated wrapper to write some initial data. std::unique_ptr<CDBWrapper> dbw = std::make_unique<CDBWrapper>(ph, (1 << 10), false, false, false); diff --git a/src/test/fs_tests.cpp b/src/test/fs_tests.cpp index 1256395849..313064b294 100644 --- a/src/test/fs_tests.cpp +++ b/src/test/fs_tests.cpp @@ -118,4 +118,62 @@ BOOST_AUTO_TEST_CASE(fsbridge_fstream) } } -BOOST_AUTO_TEST_SUITE_END()
\ No newline at end of file +BOOST_AUTO_TEST_CASE(rename) +{ + const fs::path tmpfolder{m_args.GetDataDirBase()}; + + const fs::path path1{GetUniquePath(tmpfolder)}; + const fs::path path2{GetUniquePath(tmpfolder)}; + + const std::string path1_contents{"1111"}; + const std::string path2_contents{"2222"}; + + { + std::ofstream file{path1}; + file << path1_contents; + } + + { + std::ofstream file{path2}; + file << path2_contents; + } + + // Rename path1 -> path2. + BOOST_CHECK(RenameOver(path1, path2)); + + BOOST_CHECK(!fs::exists(path1)); + + { + std::ifstream file{path2}; + std::string contents; + file >> contents; + BOOST_CHECK_EQUAL(contents, path1_contents); + } + fs::remove(path2); +} + +#ifndef WIN32 +BOOST_AUTO_TEST_CASE(create_directories) +{ + // Test fs::create_directories workaround. + const fs::path tmpfolder{m_args.GetDataDirBase()}; + + const fs::path dir{GetUniquePath(tmpfolder)}; + fs::create_directory(dir); + BOOST_CHECK(fs::exists(dir)); + BOOST_CHECK(fs::is_directory(dir)); + BOOST_CHECK(!fs::create_directories(dir)); + + const fs::path symlink{GetUniquePath(tmpfolder)}; + fs::create_directory_symlink(dir, symlink); + BOOST_CHECK(fs::exists(symlink)); + BOOST_CHECK(fs::is_symlink(symlink)); + BOOST_CHECK(fs::is_directory(symlink)); + BOOST_CHECK(!fs::create_directories(symlink)); + + fs::remove(symlink); + fs::remove(dir); +} +#endif // WIN32 + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/fuzz/script.cpp b/src/test/fuzz/script.cpp index 14a59912db..fdcd0da37d 100644 --- a/src/test/fuzz/script.cpp +++ b/src/test/fuzz/script.cpp @@ -167,12 +167,4 @@ FUZZ_TARGET_INIT(script, initialize_script) Assert(dest == GetScriptForDestination(tx_destination_2)); } } - - (void)FormatScript(script); - (void)ScriptToAsmStr(script, /*fAttemptSighashDecode=*/fuzzed_data_provider.ConsumeBool()); - - UniValue o1(UniValue::VOBJ); - ScriptPubKeyToUniv(script, o1, /*include_hex=*/fuzzed_data_provider.ConsumeBool()); - UniValue o3(UniValue::VOBJ); - ScriptToUniv(script, o3); } diff --git a/src/test/fuzz/script_format.cpp b/src/test/fuzz/script_format.cpp new file mode 100644 index 0000000000..2fa893f812 --- /dev/null +++ b/src/test/fuzz/script_format.cpp @@ -0,0 +1,30 @@ +// Copyright (c) 2019-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 <chainparams.h> +#include <core_io.h> +#include <script/script.h> +#include <test/fuzz/FuzzedDataProvider.h> +#include <test/fuzz/fuzz.h> +#include <test/fuzz/util.h> +#include <univalue.h> + +void initialize_script_format() +{ + SelectParams(CBaseChainParams::REGTEST); +} + +FUZZ_TARGET_INIT(script_format, initialize_script_format) +{ + FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); + const CScript script{ConsumeScript(fuzzed_data_provider)}; + + (void)FormatScript(script); + (void)ScriptToAsmStr(script, /*fAttemptSighashDecode=*/fuzzed_data_provider.ConsumeBool()); + + UniValue o1(UniValue::VOBJ); + ScriptPubKeyToUniv(script, o1, /*include_hex=*/fuzzed_data_provider.ConsumeBool()); + UniValue o3(UniValue::VOBJ); + ScriptToUniv(script, o3); +} diff --git a/src/util/system.cpp b/src/util/system.cpp index 5cef2be07a..69811a751b 100644 --- a/src/util/system.cpp +++ b/src/util/system.cpp @@ -1062,9 +1062,20 @@ void ArgsManager::LogArgs() const bool RenameOver(fs::path src, fs::path dest) { +#ifdef __MINGW64__ + // This is a workaround for a bug in libstdc++ which + // implements std::filesystem::rename with _wrename function. + // This bug has been fixed in upstream: + // - GCC 10.3: 8dd1c1085587c9f8a21bb5e588dfe1e8cdbba79e + // - GCC 11.1: 1dfd95f0a0ca1d9e6cbc00e6cbfd1fa20a98f312 + // For more details see the commits mentioned above. + return MoveFileExW(src.wstring().c_str(), dest.wstring().c_str(), + MOVEFILE_REPLACE_EXISTING) != 0; +#else std::error_code error; fs::rename(src, dest, error); return !error; +#endif } /** diff --git a/src/validation.cpp b/src/validation.cpp index e20e2fe523..5b52638fc5 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -286,8 +286,10 @@ bool CheckSequenceLocks(CBlockIndex* tip, static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const Consensus::Params& chainparams); static void LimitMempoolSize(CTxMemPool& pool, CCoinsViewCache& coins_cache, size_t limit, std::chrono::seconds age) - EXCLUSIVE_LOCKS_REQUIRED(pool.cs, ::cs_main) + EXCLUSIVE_LOCKS_REQUIRED(::cs_main, pool.cs) { + AssertLockHeld(::cs_main); + AssertLockHeld(pool.cs); int expired = pool.Expire(GetTime<std::chrono::seconds>() - age); if (expired != 0) { LogPrint(BCLog::MEMPOOL, "Expired %i transactions from the memory pool\n", expired); @@ -628,8 +630,10 @@ private: EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs); // Compare a package's feerate against minimum allowed. - bool CheckFeeRate(size_t package_size, CAmount package_fee, TxValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs) + bool CheckFeeRate(size_t package_size, CAmount package_fee, TxValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(::cs_main, m_pool.cs) { + AssertLockHeld(::cs_main); + AssertLockHeld(m_pool.cs); CAmount mempoolRejectFee = m_pool.GetMinFee(gArgs.GetIntArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFee(package_size); if (mempoolRejectFee > 0 && package_fee < mempoolRejectFee) { return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "mempool min fee not met", strprintf("%d < %d", package_fee, mempoolRejectFee)); @@ -663,6 +667,8 @@ private: bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws) { + AssertLockHeld(cs_main); + AssertLockHeld(m_pool.cs); const CTransactionRef& ptx = ws.m_ptx; const CTransaction& tx = *ws.m_ptx; const uint256& hash = ws.m_hash; @@ -963,6 +969,8 @@ bool MemPoolAccept::PackageMempoolChecks(const std::vector<CTransactionRef>& txn bool MemPoolAccept::PolicyScriptChecks(const ATMPArgs& args, Workspace& ws) { + AssertLockHeld(cs_main); + AssertLockHeld(m_pool.cs); const CTransaction& tx = *ws.m_ptx; TxValidationState& state = ws.m_state; @@ -989,6 +997,8 @@ bool MemPoolAccept::PolicyScriptChecks(const ATMPArgs& args, Workspace& ws) bool MemPoolAccept::ConsensusScriptChecks(const ATMPArgs& args, Workspace& ws) { + AssertLockHeld(cs_main); + AssertLockHeld(m_pool.cs); const CTransaction& tx = *ws.m_ptx; const uint256& hash = ws.m_hash; TxValidationState& state = ws.m_state; @@ -1021,6 +1031,8 @@ bool MemPoolAccept::ConsensusScriptChecks(const ATMPArgs& args, Workspace& ws) bool MemPoolAccept::Finalize(const ATMPArgs& args, Workspace& ws) { + AssertLockHeld(cs_main); + AssertLockHeld(m_pool.cs); const CTransaction& tx = *ws.m_ptx; const uint256& hash = ws.m_hash; TxValidationState& state = ws.m_state; @@ -1342,8 +1354,9 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptPackage(const Package& package, MempoolAcceptResult AcceptToMemoryPool(CChainState& active_chainstate, const CTransactionRef& tx, int64_t accept_time, bool bypass_limits, bool test_accept) - EXCLUSIVE_LOCKS_REQUIRED(cs_main) + EXCLUSIVE_LOCKS_REQUIRED(::cs_main) { + AssertLockHeld(::cs_main); const CChainParams& chainparams{active_chainstate.m_params}; assert(active_chainstate.GetMempool() != nullptr); CTxMemPool& pool{*active_chainstate.GetMempool()}; @@ -1421,6 +1434,7 @@ CoinsViews::CoinsViews( void CoinsViews::InitCache() { + AssertLockHeld(::cs_main); m_cacheview = std::make_unique<CCoinsViewCache>(&m_catcherview); } @@ -1451,6 +1465,7 @@ void CChainState::InitCoinsDB( void CChainState::InitCoinsCache(size_t cache_size_bytes) { + AssertLockHeld(::cs_main); assert(m_coins_views != nullptr); m_coinstip_cache_size_bytes = cache_size_bytes; m_coins_views->InitCache(); @@ -1524,6 +1539,7 @@ void CChainState::CheckForkWarningConditions() // Called both upon regular invalid block discovery *and* InvalidateBlock void CChainState::InvalidChainFound(CBlockIndex* pindexNew) { + AssertLockHeld(cs_main); if (!m_chainman.m_best_invalid || pindexNew->nChainWork > m_chainman.m_best_invalid->nChainWork) { m_chainman.m_best_invalid = pindexNew; } @@ -1546,6 +1562,7 @@ void CChainState::InvalidChainFound(CBlockIndex* pindexNew) // which does its own setBlockIndexCandidates management. void CChainState::InvalidBlockFound(CBlockIndex* pindex, const BlockValidationState& state) { + AssertLockHeld(cs_main); if (state.GetResult() != BlockValidationResult::BLOCK_MUTATED) { pindex->nStatus |= BLOCK_FAILED_VALID; m_chainman.m_failed_blocks.insert(pindex); @@ -1906,7 +1923,10 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state, { AssertLockHeld(cs_main); assert(pindex); - assert(*pindex->phashBlock == block.GetHash()); + + uint256 block_hash{block.GetHash()}; + assert(*pindex->phashBlock == block_hash); + int64_t nTimeStart = GetTimeMicros(); // Check it again in case a previous version let a bad block in @@ -1940,7 +1960,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state, // Special case for the genesis block, skipping connection of its transactions // (its coinbase is unspendable) - if (block.GetHash() == m_params.GetConsensus().hashGenesisBlock) { + if (block_hash == m_params.GetConsensus().hashGenesisBlock) { if (!fJustCheck) view.SetBestBlock(pindex->GetBlockHash()); return true; @@ -2197,12 +2217,12 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state, LogPrint(BCLog::BENCH, " - Index writing: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime5 - nTime4), nTimeIndex * MICRO, nTimeIndex * MILLI / nBlocksTotal); TRACE6(validation, block_connected, - block.GetHash().data(), + block_hash.data(), pindex->nHeight, block.vtx.size(), nInputs, nSigOpsCost, - GetTimeMicros() - nTimeStart // in microseconds (µs) + nTime5 - nTimeStart // in microseconds (µs) ); return true; @@ -2210,6 +2230,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state, CoinsCacheSizeState CChainState::GetCoinsCacheSizeState() { + AssertLockHeld(::cs_main); return this->GetCoinsCacheSizeState( m_coinstip_cache_size_bytes, gArgs.GetIntArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000); @@ -2219,6 +2240,7 @@ CoinsCacheSizeState CChainState::GetCoinsCacheSizeState( size_t max_coins_cache_size_bytes, size_t max_mempool_size_bytes) { + AssertLockHeld(::cs_main); const int64_t nMempoolUsage = m_mempool ? m_mempool->DynamicMemoryUsage() : 0; int64_t cacheSize = CoinsTip().DynamicMemoryUsage(); int64_t nTotalSpace = @@ -2427,6 +2449,7 @@ static void UpdateTipLog( void CChainState::UpdateTip(const CBlockIndex* pindexNew) { + AssertLockHeld(::cs_main); const auto& coins_tip = this->CoinsTip(); // The remainder of the function isn't relevant if we are not acting on @@ -2650,7 +2673,9 @@ bool CChainState::ConnectTip(BlockValidationState& state, CBlockIndex* pindexNew * Return the tip of the chain with the most work in it, that isn't * known to be invalid (it's however far from certain to be valid). */ -CBlockIndex* CChainState::FindMostWorkChain() { +CBlockIndex* CChainState::FindMostWorkChain() +{ + AssertLockHeld(::cs_main); do { CBlockIndex *pindexNew = nullptr; @@ -2854,7 +2879,7 @@ bool CChainState::ActivateBestChain(BlockValidationState& state, std::shared_ptr // far from a guarantee. Things in the P2P/RPC will often end up calling // us in the middle of ProcessNewBlock - do not assume pblock is set // sanely for performance or correctness! - AssertLockNotHeld(cs_main); + AssertLockNotHeld(::cs_main); // ABC maintains a fair degree of expensive-to-calculate internal state // because this function periodically releases cs_main so that it does not lock up other threads for too long @@ -2950,6 +2975,8 @@ bool CChainState::ActivateBestChain(BlockValidationState& state, std::shared_ptr bool CChainState::PreciousBlock(BlockValidationState& state, CBlockIndex* pindex) { + AssertLockNotHeld(m_chainstate_mutex); + AssertLockNotHeld(::cs_main); { LOCK(cs_main); if (pindex->nChainWork < m_chain.Tip()->nChainWork) { @@ -2980,6 +3007,7 @@ bool CChainState::PreciousBlock(BlockValidationState& state, CBlockIndex* pindex bool CChainState::InvalidateBlock(BlockValidationState& state, CBlockIndex* pindex) { AssertLockNotHeld(m_chainstate_mutex); + AssertLockNotHeld(::cs_main); // Genesis block can't be invalidated assert(pindex); @@ -3158,6 +3186,7 @@ void CChainState::ResetBlockFailureFlags(CBlockIndex *pindex) { /** Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS). */ void CChainState::ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pindexNew, const FlatFilePos& pos) { + AssertLockHeld(cs_main); pindexNew->nTx = block.vtx.size(); pindexNew->nChainTx = 0; pindexNew->nFile = pos.nFile; @@ -3330,8 +3359,9 @@ std::vector<unsigned char> GenerateCoinbaseCommitment(CBlock& block, const CBloc * in ConnectBlock(). * Note that -reindex-chainstate skips the validation that happens here! */ -static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidationState& state, BlockManager& blockman, const CChainParams& params, const CBlockIndex* pindexPrev, int64_t nAdjustedTime) EXCLUSIVE_LOCKS_REQUIRED(cs_main) +static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidationState& state, BlockManager& blockman, const CChainParams& params, const CBlockIndex* pindexPrev, int64_t nAdjustedTime) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) { + AssertLockHeld(::cs_main); assert(pindexPrev != nullptr); const int nHeight = pindexPrev->nHeight + 1; @@ -3702,6 +3732,7 @@ bool ChainstateManager::ProcessNewBlock(const CChainParams& chainparams, const s MempoolAcceptResult ChainstateManager::ProcessTransaction(const CTransactionRef& tx, bool test_accept) { + AssertLockHeld(cs_main); CChainState& active_chainstate = ActiveChainstate(); if (!active_chainstate.GetMempool()) { TxValidationState state; @@ -3915,6 +3946,7 @@ bool CVerifyDB::VerifyDB( /** Apply the effects of a block on the utxo cache, ignoring that it may already have been applied. */ bool CChainState::RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& inputs) { + AssertLockHeld(cs_main); // TODO: merge with ConnectBlock CBlock block; if (!ReadBlockFromDisk(block, pindex, m_params.GetConsensus())) { @@ -4018,7 +4050,9 @@ bool CChainState::NeedsRedownload() const return false; } -void CChainState::UnloadBlockIndex() { +void CChainState::UnloadBlockIndex() +{ + AssertLockHeld(::cs_main); nBlockSequenceId = 1; setBlockIndexCandidates.clear(); } @@ -4090,6 +4124,7 @@ bool CChainState::LoadGenesisBlock() void CChainState::LoadExternalBlockFile(FILE* fileIn, FlatFilePos* dbp) { + AssertLockNotHeld(m_chainstate_mutex); // Map of disk positions for blocks with unknown parent (only used for reindex) static std::multimap<uint256, FlatFilePos> mapBlocksUnknownParent; int64_t nStart = GetTimeMillis(); @@ -4430,6 +4465,7 @@ void CChainState::CheckBlockIndex() std::string CChainState::ToString() { + AssertLockHeld(::cs_main); CBlockIndex* tip = m_chain.Tip(); return strprintf("Chainstate [%s] @ height %d (%s)", m_from_snapshot_blockhash ? "snapshot" : "ibd", @@ -4438,6 +4474,7 @@ std::string CChainState::ToString() bool CChainState::ResizeCoinsCaches(size_t coinstip_size, size_t coinsdb_size) { + AssertLockHeld(::cs_main); if (coinstip_size == m_coinstip_cache_size_bytes && coinsdb_size == m_coinsdb_cache_size_bytes) { // Cache sizes are unchanged, no need to continue. @@ -4662,6 +4699,7 @@ std::vector<CChainState*> ChainstateManager::GetAll() CChainState& ChainstateManager::InitializeChainstate( CTxMemPool* mempool, const std::optional<uint256>& snapshot_blockhash) { + AssertLockHeld(::cs_main); bool is_snapshot = snapshot_blockhash.has_value(); std::unique_ptr<CChainState>& to_modify = is_snapshot ? m_snapshot_chainstate : m_ibd_chainstate; @@ -4999,6 +5037,7 @@ bool ChainstateManager::IsSnapshotActive() const void ChainstateManager::Unload() { + AssertLockHeld(::cs_main); for (CChainState* chainstate : this->GetAll()) { chainstate->m_chain.SetTip(nullptr); chainstate->UnloadBlockIndex(); @@ -5020,6 +5059,7 @@ void ChainstateManager::Reset() void ChainstateManager::MaybeRebalanceCaches() { + AssertLockHeld(::cs_main); if (m_ibd_chainstate && !m_snapshot_chainstate) { LogPrintf("[snapshot] allocating all cache to the IBD chainstate\n"); // Allocate everything to the IBD chainstate. diff --git a/src/validation.h b/src/validation.h index fdfd29d1f8..968f62aa9a 100644 --- a/src/validation.h +++ b/src/validation.h @@ -529,7 +529,9 @@ public: //! @returns whether or not the CoinsViews object has been fully initialized and we can //! safely flush this object to disk. - bool CanFlushToDisk() const EXCLUSIVE_LOCKS_REQUIRED(cs_main) { + bool CanFlushToDisk() const EXCLUSIVE_LOCKS_REQUIRED(::cs_main) + { + AssertLockHeld(::cs_main); return m_coins_views && m_coins_views->m_cacheview; } @@ -557,15 +559,17 @@ public: std::set<CBlockIndex*, node::CBlockIndexWorkComparator> setBlockIndexCandidates; //! @returns A reference to the in-memory cache of the UTXO set. - CCoinsViewCache& CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(cs_main) + CCoinsViewCache& CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(::cs_main) { + AssertLockHeld(::cs_main); assert(m_coins_views->m_cacheview); return *m_coins_views->m_cacheview.get(); } //! @returns A reference to the on-disk UTXO set database. - CCoinsViewDB& CoinsDB() EXCLUSIVE_LOCKS_REQUIRED(cs_main) + CCoinsViewDB& CoinsDB() EXCLUSIVE_LOCKS_REQUIRED(::cs_main) { + AssertLockHeld(::cs_main); return m_coins_views->m_dbview; } @@ -577,8 +581,9 @@ public: //! @returns A reference to a wrapped view of the in-memory UTXO set that //! handles disk read errors gracefully. - CCoinsViewErrorCatcher& CoinsErrorCatcher() EXCLUSIVE_LOCKS_REQUIRED(cs_main) + CCoinsViewErrorCatcher& CoinsErrorCatcher() EXCLUSIVE_LOCKS_REQUIRED(::cs_main) { + AssertLockHeld(::cs_main); return m_coins_views->m_catcherview; } @@ -924,6 +929,7 @@ public: node::BlockMap& BlockIndex() EXCLUSIVE_LOCKS_REQUIRED(::cs_main) { + AssertLockHeld(::cs_main); return m_blockman.m_block_index; } diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index 8ef0d46c4f..7693c9c0e8 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -426,7 +426,7 @@ BOOST_AUTO_TEST_CASE(LoadReceiveRequests) // Test some watch-only LegacyScriptPubKeyMan methods by the procedure of loading (LoadWatchOnly), // checking (HaveWatchOnly), getting (GetWatchPubKey) and removing (RemoveWatchOnly) a -// given PubKey, resp. its corresponding P2PK Script. Results of the the impact on +// given PubKey, resp. its corresponding P2PK Script. Results of the impact on // the address -> PubKey map is dependent on whether the PubKey is a point on the curve static void TestWatchOnlyPubKey(LegacyScriptPubKeyMan* spk_man, const CPubKey& add_pubkey) { |