[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()) {
TestingSetup test{CBaseChainParams::REGTEST};
{
LOCK(cs_main);
assert(::ChainActive().Height() == 0);
const bool witness_enabled{IsWitnessEnabled(::ChainActive().Tip(), Params().GetConsensus())};
assert(witness_enabled);

View file

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

View file

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

View file

@ -145,6 +145,8 @@ void TestGUI()
}
{
auto locked_chain = wallet->chain().lock();
LockAnnotation lock(::cs_main);
WalletRescanReserver reserver(wallet.get());
reserver.reserve();
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/tx_verify.h>
#include <consensus/validation.h>
#include <validation.h>
#include <miner.h>
#include <policy/policy.h>
#include <pubkey.h>
#include <script/standard.h>
#include <txmempool.h>
#include <uint256.h>
#include <util/system.h>
#include <util/strencodings.h>
#include <util/system.h>
#include <validation.h>
#include <test/setup_common.h>
@ -82,7 +82,7 @@ struct {
{2, 0xbbbeb305}, {2, 0xfe1c810a},
};
static CBlockIndex CreateBlockIndex(int nHeight)
static CBlockIndex CreateBlockIndex(int nHeight) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
CBlockIndex index;
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.
block = CreateAndProcessBlock(spends, scriptPubKey);
{
LOCK(cs_main);
BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() != block.GetHash());
}
// Test 2: ... and should be rejected if spend1 is in the memory pool
BOOST_CHECK(ToMemPool(spends[0]));
block = CreateAndProcessBlock(spends, scriptPubKey);
{
LOCK(cs_main);
BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() != block.GetHash());
}
mempool.clear();
// Test 3: ... and should be rejected if spend2 is in the memory pool
BOOST_CHECK(ToMemPool(spends[1]));
block = CreateAndProcessBlock(spends, scriptPubKey);
{
LOCK(cs_main);
BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() != block.GetHash());
}
mempool.clear();
// 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]);
BOOST_CHECK(ToMemPool(spends[1]));
block = CreateAndProcessBlock(oneSpend, scriptPubKey);
{
LOCK(cs_main);
BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() == block.GetHash());
}
// spends[1] should have been removed from the mempool when the
// block with spends[0] is accepted:
BOOST_CHECK_EQUAL(mempool.size(), 0U);

View file

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

View file

@ -181,6 +181,7 @@ BOOST_AUTO_TEST_CASE(processnewblock_signals_ordering)
UnregisterValidationInterface(&sub);
LOCK(cs_main);
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
static CBlockIndex* GetLastCheckpoint(const CCheckpointData& data)
static CBlockIndex* GetLastCheckpoint(const CCheckpointData& data) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
const MapCheckpoints& checkpoints = data.mapCheckpoints;
@ -3248,7 +3248,7 @@ static CBlockIndex* GetLastCheckpoint(const CCheckpointData& data)
* in ConnectBlock().
* 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);
const int nHeight = pindexPrev->nHeight + 1;

View file

@ -412,7 +412,7 @@ public:
/** Replay blocks that aren't fully applied to the database. */
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);
BlockMap::const_iterator it = mapBlockIndex.find(hash);

View file

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