[refactor] interfaces: Add missing LockAnnotation for cs_main

This commit is contained in:
MarcoFalke 2019-04-19 13:19:20 -04:00
parent 14959753a4
commit fa3c651143
No known key found for this signature in database
GPG key ID: CE2B75697E69A548
11 changed files with 55 additions and 20 deletions

View file

@ -114,6 +114,7 @@ void benchmark::BenchRunner::RunAll(Printer& printer, uint64_t num_evals, double
for (const auto& p : benchmarks()) { for (const auto& p : benchmarks()) {
TestingSetup test{CBaseChainParams::REGTEST}; TestingSetup test{CBaseChainParams::REGTEST};
{ {
LOCK(cs_main);
assert(::ChainActive().Height() == 0); assert(::ChainActive().Height() == 0);
const bool witness_enabled{IsWitnessEnabled(::ChainActive().Tip(), Params().GetConsensus())}; const bool witness_enabled{IsWitnessEnabled(::ChainActive().Tip(), Params().GetConsensus())};
assert(witness_enabled); assert(witness_enabled);

View file

@ -29,6 +29,7 @@ static void DuplicateInputs(benchmark::State& state)
CMutableTransaction coinbaseTx{}; CMutableTransaction coinbaseTx{};
CMutableTransaction naughtyTx{}; CMutableTransaction naughtyTx{};
LOCK(cs_main);
CBlockIndex* pindexPrev = ::ChainActive().Tip(); CBlockIndex* pindexPrev = ::ChainActive().Tip();
assert(pindexPrev != nullptr); assert(pindexPrev != nullptr);
block.nBits = GetNextWorkRequired(pindexPrev, &block, chainparams.GetConsensus()); block.nBits = GetNextWorkRequired(pindexPrev, &block, chainparams.GetConsensus());

View file

@ -41,6 +41,7 @@ class LockImpl : public Chain::Lock
{ {
Optional<int> getHeight() override Optional<int> getHeight() override
{ {
LockAnnotation lock(::cs_main);
int height = ::ChainActive().Height(); int height = ::ChainActive().Height();
if (height >= 0) { if (height >= 0) {
return height; return height;
@ -49,6 +50,7 @@ class LockImpl : public Chain::Lock
} }
Optional<int> getBlockHeight(const uint256& hash) override Optional<int> getBlockHeight(const uint256& hash) override
{ {
LockAnnotation lock(::cs_main);
CBlockIndex* block = LookupBlockIndex(hash); CBlockIndex* block = LookupBlockIndex(hash);
if (block && ::ChainActive().Contains(block)) { if (block && ::ChainActive().Contains(block)) {
return block->nHeight; return block->nHeight;
@ -63,29 +65,34 @@ class LockImpl : public Chain::Lock
} }
uint256 getBlockHash(int height) override uint256 getBlockHash(int height) override
{ {
LockAnnotation lock(::cs_main);
CBlockIndex* block = ::ChainActive()[height]; CBlockIndex* block = ::ChainActive()[height];
assert(block != nullptr); assert(block != nullptr);
return block->GetBlockHash(); return block->GetBlockHash();
} }
int64_t getBlockTime(int height) override int64_t getBlockTime(int height) override
{ {
LockAnnotation lock(::cs_main);
CBlockIndex* block = ::ChainActive()[height]; CBlockIndex* block = ::ChainActive()[height];
assert(block != nullptr); assert(block != nullptr);
return block->GetBlockTime(); return block->GetBlockTime();
} }
int64_t getBlockMedianTimePast(int height) override int64_t getBlockMedianTimePast(int height) override
{ {
LockAnnotation lock(::cs_main);
CBlockIndex* block = ::ChainActive()[height]; CBlockIndex* block = ::ChainActive()[height];
assert(block != nullptr); assert(block != nullptr);
return block->GetMedianTimePast(); return block->GetMedianTimePast();
} }
bool haveBlockOnDisk(int height) override bool haveBlockOnDisk(int height) override
{ {
LockAnnotation lock(::cs_main);
CBlockIndex* block = ::ChainActive()[height]; CBlockIndex* block = ::ChainActive()[height];
return block && ((block->nStatus & BLOCK_HAVE_DATA) != 0) && block->nTx > 0; return block && ((block->nStatus & BLOCK_HAVE_DATA) != 0) && block->nTx > 0;
} }
Optional<int> findFirstBlockWithTimeAndHeight(int64_t time, int height, uint256* hash) override Optional<int> findFirstBlockWithTimeAndHeight(int64_t time, int height, uint256* hash) override
{ {
LockAnnotation lock(::cs_main);
CBlockIndex* block = ::ChainActive().FindEarliestAtLeast(time, height); CBlockIndex* block = ::ChainActive().FindEarliestAtLeast(time, height);
if (block) { if (block) {
if (hash) *hash = block->GetBlockHash(); if (hash) *hash = block->GetBlockHash();
@ -95,6 +102,7 @@ class LockImpl : public Chain::Lock
} }
Optional<int> findPruned(int start_height, Optional<int> stop_height) override Optional<int> findPruned(int start_height, Optional<int> stop_height) override
{ {
LockAnnotation lock(::cs_main);
if (::fPruneMode) { if (::fPruneMode) {
CBlockIndex* block = stop_height ? ::ChainActive()[*stop_height] : ::ChainActive().Tip(); CBlockIndex* block = stop_height ? ::ChainActive()[*stop_height] : ::ChainActive().Tip();
while (block && block->nHeight >= start_height) { while (block && block->nHeight >= start_height) {
@ -108,6 +116,7 @@ class LockImpl : public Chain::Lock
} }
Optional<int> findFork(const uint256& hash, Optional<int>* height) override Optional<int> findFork(const uint256& hash, Optional<int>* height) override
{ {
LockAnnotation lock(::cs_main);
const CBlockIndex* block = LookupBlockIndex(hash); const CBlockIndex* block = LookupBlockIndex(hash);
const CBlockIndex* fork = block ? ::ChainActive().FindFork(block) : nullptr; const CBlockIndex* fork = block ? ::ChainActive().FindFork(block) : nullptr;
if (height) { if (height) {
@ -122,7 +131,11 @@ class LockImpl : public Chain::Lock
} }
return nullopt; return nullopt;
} }
CBlockLocator getTipLocator() override { return ::ChainActive().GetLocator(); } CBlockLocator getTipLocator() override
{
LockAnnotation lock(::cs_main);
return ::ChainActive().GetLocator();
}
Optional<int> findLocatorFork(const CBlockLocator& locator) override Optional<int> findLocatorFork(const CBlockLocator& locator) override
{ {
LockAnnotation lock(::cs_main); LockAnnotation lock(::cs_main);

View file

@ -145,6 +145,8 @@ void TestGUI()
} }
{ {
auto locked_chain = wallet->chain().lock(); auto locked_chain = wallet->chain().lock();
LockAnnotation lock(::cs_main);
WalletRescanReserver reserver(wallet.get()); WalletRescanReserver reserver(wallet.get());
reserver.reserve(); reserver.reserve();
CWallet::ScanResult result = wallet->ScanForWalletTransactions(locked_chain->getBlockHash(0), {} /* stop_block */, reserver, true /* fUpdate */); CWallet::ScanResult result = wallet->ScanForWalletTransactions(locked_chain->getBlockHash(0), {} /* stop_block */, reserver, true /* fUpdate */);

View file

@ -8,15 +8,15 @@
#include <consensus/merkle.h> #include <consensus/merkle.h>
#include <consensus/tx_verify.h> #include <consensus/tx_verify.h>
#include <consensus/validation.h> #include <consensus/validation.h>
#include <validation.h>
#include <miner.h> #include <miner.h>
#include <policy/policy.h> #include <policy/policy.h>
#include <pubkey.h> #include <pubkey.h>
#include <script/standard.h> #include <script/standard.h>
#include <txmempool.h> #include <txmempool.h>
#include <uint256.h> #include <uint256.h>
#include <util/system.h>
#include <util/strencodings.h> #include <util/strencodings.h>
#include <util/system.h>
#include <validation.h>
#include <test/setup_common.h> #include <test/setup_common.h>
@ -82,7 +82,7 @@ struct {
{2, 0xbbbeb305}, {2, 0xfe1c810a}, {2, 0xbbbeb305}, {2, 0xfe1c810a},
}; };
static CBlockIndex CreateBlockIndex(int nHeight) static CBlockIndex CreateBlockIndex(int nHeight) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{ {
CBlockIndex index; CBlockIndex index;
index.nHeight = nHeight; index.nHeight = nHeight;

View file

@ -66,18 +66,27 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)
// Test 1: block with both of those transactions should be rejected. // Test 1: block with both of those transactions should be rejected.
block = CreateAndProcessBlock(spends, scriptPubKey); block = CreateAndProcessBlock(spends, scriptPubKey);
{
LOCK(cs_main);
BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() != block.GetHash()); BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() != block.GetHash());
}
// Test 2: ... and should be rejected if spend1 is in the memory pool // Test 2: ... and should be rejected if spend1 is in the memory pool
BOOST_CHECK(ToMemPool(spends[0])); BOOST_CHECK(ToMemPool(spends[0]));
block = CreateAndProcessBlock(spends, scriptPubKey); block = CreateAndProcessBlock(spends, scriptPubKey);
{
LOCK(cs_main);
BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() != block.GetHash()); BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() != block.GetHash());
}
mempool.clear(); mempool.clear();
// Test 3: ... and should be rejected if spend2 is in the memory pool // Test 3: ... and should be rejected if spend2 is in the memory pool
BOOST_CHECK(ToMemPool(spends[1])); BOOST_CHECK(ToMemPool(spends[1]));
block = CreateAndProcessBlock(spends, scriptPubKey); block = CreateAndProcessBlock(spends, scriptPubKey);
{
LOCK(cs_main);
BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() != block.GetHash()); BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() != block.GetHash());
}
mempool.clear(); mempool.clear();
// Final sanity test: first spend in mempool, second in block, that's OK: // Final sanity test: first spend in mempool, second in block, that's OK:
@ -85,7 +94,10 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)
oneSpend.push_back(spends[0]); oneSpend.push_back(spends[0]);
BOOST_CHECK(ToMemPool(spends[1])); BOOST_CHECK(ToMemPool(spends[1]));
block = CreateAndProcessBlock(oneSpend, scriptPubKey); block = CreateAndProcessBlock(oneSpend, scriptPubKey);
{
LOCK(cs_main);
BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() == block.GetHash()); BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() == block.GetHash());
}
// spends[1] should have been removed from the mempool when the // spends[1] should have been removed from the mempool when the
// block with spends[0] is accepted: // block with spends[0] is accepted:
BOOST_CHECK_EQUAL(mempool.size(), 0U); BOOST_CHECK_EQUAL(mempool.size(), 0U);

View file

@ -84,6 +84,7 @@ std::shared_ptr<CBlock> PrepareBlock(const CScript& coinbase_scriptPubKey)
.CreateNewBlock(coinbase_scriptPubKey) .CreateNewBlock(coinbase_scriptPubKey)
->block); ->block);
LOCK(cs_main);
block->nTime = ::ChainActive().Tip()->GetMedianTimePast() + 1; block->nTime = ::ChainActive().Tip()->GetMedianTimePast() + 1;
block->hashMerkleRoot = BlockMerkleRoot(*block); block->hashMerkleRoot = BlockMerkleRoot(*block);

View file

@ -181,6 +181,7 @@ BOOST_AUTO_TEST_CASE(processnewblock_signals_ordering)
UnregisterValidationInterface(&sub); UnregisterValidationInterface(&sub);
LOCK(cs_main);
BOOST_CHECK_EQUAL(sub.m_expected_tip, ::ChainActive().Tip()->GetBlockHash()); BOOST_CHECK_EQUAL(sub.m_expected_tip, ::ChainActive().Tip()->GetBlockHash());
} }

View file

@ -3224,7 +3224,7 @@ std::vector<unsigned char> GenerateCoinbaseCommitment(CBlock& block, const CBloc
} }
//! Returns last CBlockIndex* that is a checkpoint //! Returns last CBlockIndex* that is a checkpoint
static CBlockIndex* GetLastCheckpoint(const CCheckpointData& data) static CBlockIndex* GetLastCheckpoint(const CCheckpointData& data) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{ {
const MapCheckpoints& checkpoints = data.mapCheckpoints; const MapCheckpoints& checkpoints = data.mapCheckpoints;
@ -3248,7 +3248,7 @@ static CBlockIndex* GetLastCheckpoint(const CCheckpointData& data)
* in ConnectBlock(). * in ConnectBlock().
* Note that -reindex-chainstate skips the validation that happens here! * Note that -reindex-chainstate skips the validation that happens here!
*/ */
static bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, const CChainParams& params, const CBlockIndex* pindexPrev, int64_t nAdjustedTime) static bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, const CChainParams& params, const CBlockIndex* pindexPrev, int64_t nAdjustedTime) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{ {
assert(pindexPrev != nullptr); assert(pindexPrev != nullptr);
const int nHeight = pindexPrev->nHeight + 1; const int nHeight = pindexPrev->nHeight + 1;

View file

@ -412,7 +412,7 @@ public:
/** Replay blocks that aren't fully applied to the database. */ /** Replay blocks that aren't fully applied to the database. */
bool ReplayBlocks(const CChainParams& params, CCoinsView* view); bool ReplayBlocks(const CChainParams& params, CCoinsView* view);
inline CBlockIndex* LookupBlockIndex(const uint256& hash) inline CBlockIndex* LookupBlockIndex(const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{ {
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
BlockMap::const_iterator it = mapBlockIndex.find(hash); BlockMap::const_iterator it = mapBlockIndex.find(hash);

View file

@ -12,12 +12,12 @@
#include <consensus/validation.h> #include <consensus/validation.h>
#include <interfaces/chain.h> #include <interfaces/chain.h>
#include <policy/policy.h>
#include <rpc/server.h> #include <rpc/server.h>
#include <test/setup_common.h> #include <test/setup_common.h>
#include <validation.h> #include <validation.h>
#include <wallet/coincontrol.h> #include <wallet/coincontrol.h>
#include <wallet/test/wallet_test_fixture.h> #include <wallet/test/wallet_test_fixture.h>
#include <policy/policy.h>
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <univalue.h> #include <univalue.h>
@ -36,16 +36,15 @@ static void AddKey(CWallet& wallet, const CKey& key)
BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup) BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
{ {
auto chain = interfaces::MakeChain();
// Cap last block file size, and mine new block in a new block file. // Cap last block file size, and mine new block in a new block file.
CBlockIndex* oldTip = ::ChainActive().Tip(); CBlockIndex* oldTip = ::ChainActive().Tip();
GetBlockFileInfo(oldTip->GetBlockPos().nFile)->nSize = MAX_BLOCKFILE_SIZE; GetBlockFileInfo(oldTip->GetBlockPos().nFile)->nSize = MAX_BLOCKFILE_SIZE;
CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())); CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
CBlockIndex* newTip = ::ChainActive().Tip(); CBlockIndex* newTip = ::ChainActive().Tip();
LockAnnotation lock(::cs_main); auto chain = interfaces::MakeChain();
auto locked_chain = chain->lock(); auto locked_chain = chain->lock();
LockAnnotation lock(::cs_main);
// Verify ScanForWalletTransactions accommodates a null start block. // Verify ScanForWalletTransactions accommodates a null start block.
{ {
@ -116,16 +115,15 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
BOOST_FIXTURE_TEST_CASE(importmulti_rescan, TestChain100Setup) BOOST_FIXTURE_TEST_CASE(importmulti_rescan, TestChain100Setup)
{ {
auto chain = interfaces::MakeChain();
// Cap last block file size, and mine new block in a new block file. // Cap last block file size, and mine new block in a new block file.
CBlockIndex* oldTip = ::ChainActive().Tip(); CBlockIndex* oldTip = ::ChainActive().Tip();
GetBlockFileInfo(oldTip->GetBlockPos().nFile)->nSize = MAX_BLOCKFILE_SIZE; GetBlockFileInfo(oldTip->GetBlockPos().nFile)->nSize = MAX_BLOCKFILE_SIZE;
CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())); CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
CBlockIndex* newTip = ::ChainActive().Tip(); CBlockIndex* newTip = ::ChainActive().Tip();
LockAnnotation lock(::cs_main); auto chain = interfaces::MakeChain();
auto locked_chain = chain->lock(); auto locked_chain = chain->lock();
LockAnnotation lock(::cs_main);
// Prune the older block file. // Prune the older block file.
PruneOneBlockFile(oldTip->GetBlockPos().nFile); PruneOneBlockFile(oldTip->GetBlockPos().nFile);
@ -177,8 +175,6 @@ BOOST_FIXTURE_TEST_CASE(importmulti_rescan, TestChain100Setup)
// than or equal to key birthday. // than or equal to key birthday.
BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup) BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
{ {
auto chain = interfaces::MakeChain();
// Create two blocks with same timestamp to verify that importwallet rescan // Create two blocks with same timestamp to verify that importwallet rescan
// will pick up both blocks, not just the first. // will pick up both blocks, not just the first.
const int64_t BLOCK_TIME = ::ChainActive().Tip()->GetBlockTimeMax() + 5; const int64_t BLOCK_TIME = ::ChainActive().Tip()->GetBlockTimeMax() + 5;
@ -192,7 +188,9 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
SetMockTime(KEY_TIME); SetMockTime(KEY_TIME);
m_coinbase_txns.emplace_back(CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]); m_coinbase_txns.emplace_back(CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
auto chain = interfaces::MakeChain();
auto locked_chain = chain->lock(); auto locked_chain = chain->lock();
LockAnnotation lock(::cs_main);
std::string backup_file = (SetDataDir("importwallet_rescan") / "wallet.backup").string(); std::string backup_file = (SetDataDir("importwallet_rescan") / "wallet.backup").string();
@ -245,10 +243,14 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
BOOST_FIXTURE_TEST_CASE(coin_mark_dirty_immature_credit, TestChain100Setup) BOOST_FIXTURE_TEST_CASE(coin_mark_dirty_immature_credit, TestChain100Setup)
{ {
auto chain = interfaces::MakeChain(); auto chain = interfaces::MakeChain();
CWallet wallet(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); CWallet wallet(chain.get(), WalletLocation(), WalletDatabase::CreateDummy());
CWalletTx wtx(&wallet, m_coinbase_txns.back()); CWalletTx wtx(&wallet, m_coinbase_txns.back());
auto locked_chain = chain->lock(); auto locked_chain = chain->lock();
LockAnnotation lock(::cs_main);
LOCK(wallet.cs_wallet); LOCK(wallet.cs_wallet);
wtx.hashBlock = ::ChainActive().Tip()->GetBlockHash(); wtx.hashBlock = ::ChainActive().Tip()->GetBlockHash();
wtx.nIndex = 0; wtx.nIndex = 0;
@ -375,6 +377,8 @@ public:
blocktx = CMutableTransaction(*wallet->mapWallet.at(tx->GetHash()).tx); blocktx = CMutableTransaction(*wallet->mapWallet.at(tx->GetHash()).tx);
} }
CreateAndProcessBlock({CMutableTransaction(blocktx)}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())); CreateAndProcessBlock({CMutableTransaction(blocktx)}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
LOCK(cs_main);
LOCK(wallet->cs_wallet); LOCK(wallet->cs_wallet);
auto it = wallet->mapWallet.find(tx->GetHash()); auto it = wallet->mapWallet.find(tx->GetHash());
BOOST_CHECK(it != wallet->mapWallet.end()); BOOST_CHECK(it != wallet->mapWallet.end());