Merge bitcoin/bitcoin#21866: [Bundle 7/7] validation: Farewell, global Chainstate!

6f994882de validation: Farewell, global Chainstate! (Carl Dong)
972c5166ee qt/test: Reset chainman in ~ChainstateManager instead (Carl Dong)
6c3b5dc0c1 scripted-diff: tree-wide: Remove all review-only assertions (Carl Dong)
3e82abb8dd tree-wide: Remove stray review-only assertion (Carl Dong)
f323248aba qt/test: Use existing chainman in ::TestGUI (can be scripted-diff) (Carl Dong)
6c15de129c scripted-diff: wallet/test: Use existing chainman (Carl Dong)
ee0ab1e959 fuzz: Initialize a TestingSetup for test_one_input (Carl Dong)
0d61634c06 scripted-diff: test: Use existing chainman in unit tests (Carl Dong)
e197076219 test: Pass in CoinsTip to ValidateCheckInputsForAllFlags (Carl Dong)
4d99b61014 test/miner_tests: Pass in chain tip to CreateBlockIndex (Carl Dong)
f0dd5e6bb4 test/util: Use existing chainman in ::PrepareBlock (Carl Dong)
464c313e30 init: Use existing chainman (Carl Dong)

Pull request description:

  Based on:  #21767

  à la Mr. Sandman
  ```
  Mr. Chainman, bring me a tip (bung, bung, bung, bung)
  Make it the most work that I've ever seen (bung, bung, bung, bung)
  Rewind old tip till we're at the fork point (bung, bung, bung, bung)
  Then tell it that it's time to call Con-nectTip

  Chainman, I'm so alone (bung, bung, bung, bung)
  No local objects to call my own (bung, bung, bung, bung)
  Please make sure I have a ref
  Mr. Chainman, bring me a tip!
  ```

  This is the last bundle in the #20158 series. Thanks everyone for their diligent review.
  I would like to call attention to https://github.com/bitcoin/bitcoin/issues/21766, where a few leftover improvements were collated.

  - Remove globals:
    - `ChainstateManager g_chainman`
    - `CChainState& ChainstateActive()`
    - `CChain& ChainActive()`
  - Remove all review-only assertions.

ACKs for top commit:
  jamesob:
    reACK 6f994882de based on the contents of
  ariard:
    Code Review ACK 6f99488.
  jnewbery:
    utACK 6f994882de
  achow101:
    Code Review ACK 6f994882de
  ryanofsky:
    Code review ACK 6f994882de.

Tree-SHA512: 4052ea79360cf0efd81ad0ee3f982e1d93aab1837dcec75f875a56ceda085de078bb3099a2137935d7cc2222004ad88da94b605ef5efef35cb6bc733725debe6
This commit is contained in:
fanquake 2021-06-12 11:11:19 +08:00
commit a55904a80c
No known key found for this signature in database
GPG key ID: 2EEB9F5CC09526C1
35 changed files with 173 additions and 291 deletions

View file

@ -25,7 +25,6 @@ static void DuplicateInputs(benchmark::Bench& bench)
CMutableTransaction naughtyTx{}; CMutableTransaction naughtyTx{};
LOCK(cs_main); LOCK(cs_main);
assert(std::addressof(::ChainActive()) == std::addressof(testing_setup->m_node.chainman->ActiveChain()));
CBlockIndex* pindexPrev = testing_setup->m_node.chainman->ActiveChain().Tip(); CBlockIndex* pindexPrev = testing_setup->m_node.chainman->ActiveChain().Tip();
assert(pindexPrev != nullptr); assert(pindexPrev != nullptr);
block.nBits = GetNextWorkRequired(pindexPrev, &block, chainparams.GetConsensus()); block.nBits = GetNextWorkRequired(pindexPrev, &block, chainparams.GetConsensus());

View file

@ -340,7 +340,6 @@ void BaseIndex::Interrupt()
bool BaseIndex::Start(CChainState& active_chainstate) bool BaseIndex::Start(CChainState& active_chainstate)
{ {
assert(std::addressof(::ChainstateActive()) == std::addressof(active_chainstate));
m_chainstate = &active_chainstate; m_chainstate = &active_chainstate;
// Need to register this ValidationInterface before running Init(), so that // Need to register this ValidationInterface before running Init(), so that
// callbacks are not missed if Init sets m_synced to true. // callbacks are not missed if Init sets m_synced to true.

View file

@ -283,7 +283,7 @@ void Shutdown(NodeContext& node)
init::UnsetGlobals(); init::UnsetGlobals();
node.mempool.reset(); node.mempool.reset();
node.fee_estimator.reset(); node.fee_estimator.reset();
node.chainman = nullptr; node.chainman.reset();
node.scheduler.reset(); node.scheduler.reset();
try { try {
@ -1175,8 +1175,8 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
node.mempool = std::make_unique<CTxMemPool>(node.fee_estimator.get(), check_ratio); node.mempool = std::make_unique<CTxMemPool>(node.fee_estimator.get(), check_ratio);
assert(!node.chainman); assert(!node.chainman);
node.chainman = &g_chainman; node.chainman = std::make_unique<ChainstateManager>();
ChainstateManager& chainman = *Assert(node.chainman); ChainstateManager& chainman = *node.chainman;
assert(!node.peerman); assert(!node.peerman);
node.peerman = PeerManager::make(chainparams, *node.connman, *node.addrman, node.banman.get(), node.peerman = PeerManager::make(chainparams, *node.connman, *node.addrman, node.banman.get(),
@ -1381,7 +1381,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
// If the loaded chain has a wrong genesis, bail out immediately // If the loaded chain has a wrong genesis, bail out immediately
// (we're likely using a testnet datadir, or the other way around). // (we're likely using a testnet datadir, or the other way around).
if (!chainman.BlockIndex().empty() && if (!chainman.BlockIndex().empty() &&
!g_chainman.m_blockman.LookupBlockIndex(chainparams.GetConsensus().hashGenesisBlock)) { !chainman.m_blockman.LookupBlockIndex(chainparams.GetConsensus().hashGenesisBlock)) {
return InitError(_("Incorrect or no genesis block found. Wrong datadir for network?")); return InitError(_("Incorrect or no genesis block found. Wrong datadir for network?"));
} }
@ -1396,7 +1396,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
// If we're not mid-reindex (based on disk + args), add a genesis block on disk // If we're not mid-reindex (based on disk + args), add a genesis block on disk
// (otherwise we use the one already on disk). // (otherwise we use the one already on disk).
// This is called again in ThreadImport after the reindex completes. // This is called again in ThreadImport after the reindex completes.
if (!fReindex && !::ChainstateActive().LoadGenesisBlock(chainparams)) { if (!fReindex && !chainman.ActiveChainstate().LoadGenesisBlock(chainparams)) {
strLoadError = _("Error initializing block database"); strLoadError = _("Error initializing block database");
break; break;
} }
@ -1545,21 +1545,21 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
// ********************************************************* Step 8: start indexers // ********************************************************* Step 8: start indexers
if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) { if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) {
g_txindex = std::make_unique<TxIndex>(nTxIndexCache, false, fReindex); g_txindex = std::make_unique<TxIndex>(nTxIndexCache, false, fReindex);
if (!g_txindex->Start(::ChainstateActive())) { if (!g_txindex->Start(chainman.ActiveChainstate())) {
return false; return false;
} }
} }
for (const auto& filter_type : g_enabled_filter_types) { for (const auto& filter_type : g_enabled_filter_types) {
InitBlockFilterIndex(filter_type, filter_index_cache, false, fReindex); InitBlockFilterIndex(filter_type, filter_index_cache, false, fReindex);
if (!GetBlockFilterIndex(filter_type)->Start(::ChainstateActive())) { if (!GetBlockFilterIndex(filter_type)->Start(chainman.ActiveChainstate())) {
return false; return false;
} }
} }
if (args.GetBoolArg("-coinstatsindex", DEFAULT_COINSTATSINDEX)) { if (args.GetBoolArg("-coinstatsindex", DEFAULT_COINSTATSINDEX)) {
g_coin_stats_index = std::make_unique<CoinStatsIndex>(/* cache size */ 0, false, fReindex); g_coin_stats_index = std::make_unique<CoinStatsIndex>(/* cache size */ 0, false, fReindex);
if (!g_coin_stats_index->Start(::ChainstateActive())) { if (!g_coin_stats_index->Start(chainman.ActiveChainstate())) {
return false; return false;
} }
} }
@ -1607,7 +1607,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
// Either install a handler to notify us when genesis activates, or set fHaveGenesis directly. // Either install a handler to notify us when genesis activates, or set fHaveGenesis directly.
// No locking, as this happens before any background thread is started. // No locking, as this happens before any background thread is started.
boost::signals2::connection block_notify_genesis_wait_connection; boost::signals2::connection block_notify_genesis_wait_connection;
if (::ChainActive().Tip() == nullptr) { if (chainman.ActiveChain().Tip() == nullptr) {
block_notify_genesis_wait_connection = uiInterface.NotifyBlockTip_connect(std::bind(BlockNotifyGenesisWait, std::placeholders::_2)); block_notify_genesis_wait_connection = uiInterface.NotifyBlockTip_connect(std::bind(BlockNotifyGenesisWait, std::placeholders::_2));
} else { } else {
fHaveGenesis = true; fHaveGenesis = true;

View file

@ -45,15 +45,7 @@ void RegenerateCommitments(CBlock& block, ChainstateManager& chainman)
tx.vout.erase(tx.vout.begin() + GetWitnessCommitmentIndex(block)); tx.vout.erase(tx.vout.begin() + GetWitnessCommitmentIndex(block));
block.vtx.at(0) = MakeTransactionRef(tx); block.vtx.at(0) = MakeTransactionRef(tx);
CBlockIndex* prev_block; CBlockIndex* prev_block = WITH_LOCK(::cs_main, return chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock));
{
// TODO: Temporary scope to check correctness of refactored code.
// Should be removed manually after merge of
// https://github.com/bitcoin/bitcoin/pull/20158
LOCK(::cs_main);
assert(std::addressof(g_chainman.m_blockman) == std::addressof(chainman.m_blockman));
prev_block = chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock);
}
GenerateCoinbaseCommitment(block, prev_block, Params().GetConsensus()); GenerateCoinbaseCommitment(block, prev_block, Params().GetConsensus());
block.hashMerkleRoot = BlockMerkleRoot(block); block.hashMerkleRoot = BlockMerkleRoot(block);
@ -124,7 +116,6 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
pblocktemplate->vTxSigOpsCost.push_back(-1); // updated at end pblocktemplate->vTxSigOpsCost.push_back(-1); // updated at end
LOCK2(cs_main, m_mempool.cs); LOCK2(cs_main, m_mempool.cs);
assert(std::addressof(*::ChainActive().Tip()) == std::addressof(*m_chainstate.m_chain.Tip()));
CBlockIndex* pindexPrev = m_chainstate.m_chain.Tip(); CBlockIndex* pindexPrev = m_chainstate.m_chain.Tip();
assert(pindexPrev != nullptr); assert(pindexPrev != nullptr);
nHeight = pindexPrev->nHeight + 1; nHeight = pindexPrev->nHeight + 1;
@ -184,7 +175,6 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
pblocktemplate->vTxSigOpsCost[0] = WITNESS_SCALE_FACTOR * GetLegacySigOpCount(*pblock->vtx[0]); pblocktemplate->vTxSigOpsCost[0] = WITNESS_SCALE_FACTOR * GetLegacySigOpCount(*pblock->vtx[0]);
BlockValidationState state; BlockValidationState state;
assert(std::addressof(::ChainstateActive()) == std::addressof(m_chainstate));
if (!TestBlockValidity(state, chainparams, m_chainstate, *pblock, pindexPrev, false, false)) { if (!TestBlockValidity(state, chainparams, m_chainstate, *pblock, pindexPrev, false, false)) {
throw std::runtime_error(strprintf("%s: TestBlockValidity failed: %s", __func__, state.ToString())); throw std::runtime_error(strprintf("%s: TestBlockValidity failed: %s", __func__, state.ToString()));
} }

View file

@ -1361,7 +1361,6 @@ PeerManagerImpl::PeerManagerImpl(const CChainParams& chainparams, CConnman& conn
m_stale_tip_check_time(0), m_stale_tip_check_time(0),
m_ignore_incoming_txs(ignore_incoming_txs) m_ignore_incoming_txs(ignore_incoming_txs)
{ {
assert(std::addressof(g_chainman) == std::addressof(m_chainman));
// Initialize global variables that cannot be constructed at startup. // Initialize global variables that cannot be constructed at startup.
recentRejects.reset(new CRollingBloomFilter(120000, 0.000001)); recentRejects.reset(new CRollingBloomFilter(120000, 0.000001));

View file

@ -248,7 +248,6 @@ bool FindBlockPos(FlatFilePos& pos, unsigned int nAddSize, unsigned int nHeight,
// when the undo file is keeping up with the block file, we want to flush it explicitly // when the undo file is keeping up with the block file, we want to flush it explicitly
// when it is lagging behind (more blocks arrive than are being connected), we let the // when it is lagging behind (more blocks arrive than are being connected), we let the
// undo block write case handle it // undo block write case handle it
assert(std::addressof(::ChainActive()) == std::addressof(active_chain));
finalize_undo = (vinfoBlockFile[nFile].nHeightLast == (unsigned int)active_chain.Tip()->nHeight); finalize_undo = (vinfoBlockFile[nFile].nHeightLast == (unsigned int)active_chain.Tip()->nHeight);
nFile++; nFile++;
if (vinfoBlockFile.size() <= nFile) { if (vinfoBlockFile.size() <= nFile) {

View file

@ -13,7 +13,6 @@ void FindCoins(const NodeContext& node, std::map<COutPoint, Coin>& coins)
assert(node.mempool); assert(node.mempool);
assert(node.chainman); assert(node.chainman);
LOCK2(cs_main, node.mempool->cs); LOCK2(cs_main, node.mempool->cs);
assert(std::addressof(::ChainstateActive()) == std::addressof(node.chainman->ActiveChainstate()));
CCoinsViewCache& chain_view = node.chainman->ActiveChainstate().CoinsTip(); CCoinsViewCache& chain_view = node.chainman->ActiveChainstate().CoinsTip();
CCoinsViewMemPool mempool_view(&chain_view, *node.mempool); CCoinsViewMemPool mempool_view(&chain_view, *node.mempool);
for (auto& coin : coins) { for (auto& coin : coins) {

View file

@ -97,7 +97,6 @@ static bool GetUTXOStats(CCoinsView* view, BlockManager& blockman, CCoinsStats&
if (!pindex) { if (!pindex) {
{ {
LOCK(cs_main); LOCK(cs_main);
assert(std::addressof(g_chainman.m_blockman) == std::addressof(blockman));
pindex = blockman.LookupBlockIndex(view->GetBestBlock()); pindex = blockman.LookupBlockIndex(view->GetBestBlock());
} }
} }

View file

@ -12,6 +12,7 @@
#include <policy/fees.h> #include <policy/fees.h>
#include <scheduler.h> #include <scheduler.h>
#include <txmempool.h> #include <txmempool.h>
#include <validation.h>
NodeContext::NodeContext() {} NodeContext::NodeContext() {}
NodeContext::~NodeContext() {} NodeContext::~NodeContext() {}

View file

@ -44,7 +44,7 @@ struct NodeContext {
std::unique_ptr<CTxMemPool> mempool; std::unique_ptr<CTxMemPool> mempool;
std::unique_ptr<CBlockPolicyEstimator> fee_estimator; std::unique_ptr<CBlockPolicyEstimator> fee_estimator;
std::unique_ptr<PeerManager> peerman; std::unique_ptr<PeerManager> peerman;
ChainstateManager* chainman{nullptr}; // Currently a raw pointer because the memory is not managed by this struct std::unique_ptr<ChainstateManager> chainman;
std::unique_ptr<BanMan> banman; std::unique_ptr<BanMan> banman;
ArgsManager* args{nullptr}; // Currently a raw pointer because the memory is not managed by this struct ArgsManager* args{nullptr}; // Currently a raw pointer because the memory is not managed by this struct
std::unique_ptr<interfaces::Chain> chain; std::unique_ptr<interfaces::Chain> chain;

View file

@ -197,26 +197,16 @@ public:
int getNumBlocks() override int getNumBlocks() override
{ {
LOCK(::cs_main); LOCK(::cs_main);
assert(std::addressof(::ChainActive()) == std::addressof(chainman().ActiveChain()));
return chainman().ActiveChain().Height(); return chainman().ActiveChain().Height();
} }
uint256 getBestBlockHash() override uint256 getBestBlockHash() override
{ {
const CBlockIndex* tip; const CBlockIndex* tip = WITH_LOCK(::cs_main, return chainman().ActiveChain().Tip());
{
// TODO: Temporary scope to check correctness of refactored code.
// Should be removed manually after merge of
// https://github.com/bitcoin/bitcoin/pull/20158
LOCK(cs_main);
assert(std::addressof(::ChainActive()) == std::addressof(chainman().ActiveChain()));
tip = chainman().ActiveChain().Tip();
}
return tip ? tip->GetBlockHash() : Params().GenesisBlock().GetHash(); return tip ? tip->GetBlockHash() : Params().GenesisBlock().GetHash();
} }
int64_t getLastBlockTime() override int64_t getLastBlockTime() override
{ {
LOCK(::cs_main); LOCK(::cs_main);
assert(std::addressof(::ChainActive()) == std::addressof(chainman().ActiveChain()));
if (chainman().ActiveChain().Tip()) { if (chainman().ActiveChain().Tip()) {
return chainman().ActiveChain().Tip()->GetBlockTime(); return chainman().ActiveChain().Tip()->GetBlockTime();
} }
@ -227,22 +217,12 @@ public:
const CBlockIndex* tip; const CBlockIndex* tip;
{ {
LOCK(::cs_main); LOCK(::cs_main);
assert(std::addressof(::ChainActive()) == std::addressof(chainman().ActiveChain()));
tip = chainman().ActiveChain().Tip(); tip = chainman().ActiveChain().Tip();
} }
return GuessVerificationProgress(Params().TxData(), tip); return GuessVerificationProgress(Params().TxData(), tip);
} }
bool isInitialBlockDownload() override { bool isInitialBlockDownload() override {
const CChainState* active_chainstate; return chainman().ActiveChainstate().IsInitialBlockDownload();
{
// TODO: Temporary scope to check correctness of refactored code.
// Should be removed manually after merge of
// https://github.com/bitcoin/bitcoin/pull/20158
LOCK(::cs_main);
active_chainstate = &m_context->chainman->ActiveChainstate();
assert(std::addressof(::ChainstateActive()) == std::addressof(*active_chainstate));
}
return active_chainstate->IsInitialBlockDownload();
} }
bool getReindex() override { return ::fReindex; } bool getReindex() override { return ::fReindex; }
bool getImporting() override { return ::fImporting; } bool getImporting() override { return ::fImporting; }
@ -269,7 +249,6 @@ public:
bool getUnspentOutput(const COutPoint& output, Coin& coin) override bool getUnspentOutput(const COutPoint& output, Coin& coin) override
{ {
LOCK(::cs_main); LOCK(::cs_main);
assert(std::addressof(::ChainstateActive()) == std::addressof(chainman().ActiveChainstate()));
return chainman().ActiveChainstate().CoinsTip().GetCoin(output, coin); return chainman().ActiveChainstate().CoinsTip().GetCoin(output, coin);
} }
WalletClient& walletClient() override WalletClient& walletClient() override
@ -476,14 +455,12 @@ public:
bool checkFinalTx(const CTransaction& tx) override bool checkFinalTx(const CTransaction& tx) override
{ {
LOCK(cs_main); LOCK(cs_main);
assert(std::addressof(::ChainActive()) == std::addressof(chainman().ActiveChain()));
return CheckFinalTx(chainman().ActiveChain().Tip(), tx); return CheckFinalTx(chainman().ActiveChain().Tip(), tx);
} }
std::optional<int> findLocatorFork(const CBlockLocator& locator) override std::optional<int> findLocatorFork(const CBlockLocator& locator) override
{ {
LOCK(cs_main); LOCK(cs_main);
const CChain& active = Assert(m_node.chainman)->ActiveChain(); const CChain& active = Assert(m_node.chainman)->ActiveChain();
assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
if (CBlockIndex* fork = m_node.chainman->m_blockman.FindForkInGlobalIndex(active, locator)) { if (CBlockIndex* fork = m_node.chainman->m_blockman.FindForkInGlobalIndex(active, locator)) {
return fork->nHeight; return fork->nHeight;
} }
@ -493,7 +470,6 @@ public:
{ {
WAIT_LOCK(cs_main, lock); WAIT_LOCK(cs_main, lock);
const CChain& active = Assert(m_node.chainman)->ActiveChain(); const CChain& active = Assert(m_node.chainman)->ActiveChain();
assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
return FillBlock(m_node.chainman->m_blockman.LookupBlockIndex(hash), block, lock, active); return FillBlock(m_node.chainman->m_blockman.LookupBlockIndex(hash), block, lock, active);
} }
bool findFirstBlockWithTimeAndHeight(int64_t min_time, int min_height, const FoundBlock& block) override bool findFirstBlockWithTimeAndHeight(int64_t min_time, int min_height, const FoundBlock& block) override
@ -506,7 +482,6 @@ public:
{ {
WAIT_LOCK(cs_main, lock); WAIT_LOCK(cs_main, lock);
const CChain& active = Assert(m_node.chainman)->ActiveChain(); const CChain& active = Assert(m_node.chainman)->ActiveChain();
assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
if (const CBlockIndex* block = m_node.chainman->m_blockman.LookupBlockIndex(block_hash)) { if (const CBlockIndex* block = m_node.chainman->m_blockman.LookupBlockIndex(block_hash)) {
if (const CBlockIndex* ancestor = block->GetAncestor(ancestor_height)) { if (const CBlockIndex* ancestor = block->GetAncestor(ancestor_height)) {
return FillBlock(ancestor, ancestor_out, lock, active); return FillBlock(ancestor, ancestor_out, lock, active);
@ -518,9 +493,7 @@ public:
{ {
WAIT_LOCK(cs_main, lock); WAIT_LOCK(cs_main, lock);
const CChain& active = Assert(m_node.chainman)->ActiveChain(); const CChain& active = Assert(m_node.chainman)->ActiveChain();
assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
const CBlockIndex* block = m_node.chainman->m_blockman.LookupBlockIndex(block_hash); const CBlockIndex* block = m_node.chainman->m_blockman.LookupBlockIndex(block_hash);
assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
const CBlockIndex* ancestor = m_node.chainman->m_blockman.LookupBlockIndex(ancestor_hash); const CBlockIndex* ancestor = m_node.chainman->m_blockman.LookupBlockIndex(ancestor_hash);
if (block && ancestor && block->GetAncestor(ancestor->nHeight) != ancestor) ancestor = nullptr; if (block && ancestor && block->GetAncestor(ancestor->nHeight) != ancestor) ancestor = nullptr;
return FillBlock(ancestor, ancestor_out, lock, active); return FillBlock(ancestor, ancestor_out, lock, active);
@ -529,9 +502,7 @@ public:
{ {
WAIT_LOCK(cs_main, lock); WAIT_LOCK(cs_main, lock);
const CChain& active = Assert(m_node.chainman)->ActiveChain(); const CChain& active = Assert(m_node.chainman)->ActiveChain();
assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
const CBlockIndex* block1 = m_node.chainman->m_blockman.LookupBlockIndex(block_hash1); const CBlockIndex* block1 = m_node.chainman->m_blockman.LookupBlockIndex(block_hash1);
assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman));
const CBlockIndex* block2 = m_node.chainman->m_blockman.LookupBlockIndex(block_hash2); const CBlockIndex* block2 = m_node.chainman->m_blockman.LookupBlockIndex(block_hash2);
const CBlockIndex* ancestor = block1 && block2 ? LastCommonAncestor(block1, block2) : nullptr; const CBlockIndex* ancestor = block1 && block2 ? LastCommonAncestor(block1, block2) : nullptr;
// Using & instead of && below to avoid short circuiting and leaving // Using & instead of && below to avoid short circuiting and leaving
@ -542,7 +513,6 @@ public:
double guessVerificationProgress(const uint256& block_hash) override double guessVerificationProgress(const uint256& block_hash) override
{ {
LOCK(cs_main); LOCK(cs_main);
assert(std::addressof(g_chainman.m_blockman) == std::addressof(chainman().m_blockman));
return GuessVerificationProgress(Params().TxData(), chainman().m_blockman.LookupBlockIndex(block_hash)); return GuessVerificationProgress(Params().TxData(), chainman().m_blockman.LookupBlockIndex(block_hash));
} }
bool hasBlocks(const uint256& block_hash, int min_height, std::optional<int> max_height) override bool hasBlocks(const uint256& block_hash, int min_height, std::optional<int> max_height) override
@ -555,7 +525,6 @@ public:
// used to limit the range, and passing min_height that's too low or // used to limit the range, and passing min_height that's too low or
// max_height that's too high will not crash or change the result. // max_height that's too high will not crash or change the result.
LOCK(::cs_main); LOCK(::cs_main);
assert(std::addressof(g_chainman.m_blockman) == std::addressof(chainman().m_blockman));
if (CBlockIndex* block = chainman().m_blockman.LookupBlockIndex(block_hash)) { if (CBlockIndex* block = chainman().m_blockman.LookupBlockIndex(block_hash)) {
if (max_height && block->nHeight >= *max_height) block = block->GetAncestor(*max_height); if (max_height && block->nHeight >= *max_height) block = block->GetAncestor(*max_height);
for (; block->nStatus & BLOCK_HAVE_DATA; block = block->pprev) { for (; block->nStatus & BLOCK_HAVE_DATA; block = block->pprev) {
@ -647,16 +616,7 @@ public:
} }
bool isReadyToBroadcast() override { return !::fImporting && !::fReindex && !isInitialBlockDownload(); } bool isReadyToBroadcast() override { return !::fImporting && !::fReindex && !isInitialBlockDownload(); }
bool isInitialBlockDownload() override { bool isInitialBlockDownload() override {
const CChainState* active_chainstate; return chainman().ActiveChainstate().IsInitialBlockDownload();
{
// TODO: Temporary scope to check correctness of refactored code.
// Should be removed manually after merge of
// https://github.com/bitcoin/bitcoin/pull/20158
LOCK(::cs_main);
active_chainstate = &chainman().ActiveChainstate();
assert(std::addressof(::ChainstateActive()) == std::addressof(*active_chainstate));
}
return active_chainstate->IsInitialBlockDownload();
} }
bool shutdownRequested() override { return ShutdownRequested(); } bool shutdownRequested() override { return ShutdownRequested(); }
int64_t getAdjustedTime() override { return GetAdjustedTime(); } int64_t getAdjustedTime() override { return GetAdjustedTime(); }

View file

@ -40,7 +40,6 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t
{ // cs_main scope { // cs_main scope
assert(node.chainman); assert(node.chainman);
LOCK(cs_main); LOCK(cs_main);
assert(std::addressof(::ChainstateActive()) == std::addressof(node.chainman->ActiveChainstate()));
// If the transaction is already confirmed in the chain, don't do anything // If the transaction is already confirmed in the chain, don't do anything
// and return early. // and return early.
CCoinsViewCache &view = node.chainman->ActiveChainstate().CoinsTip(); CCoinsViewCache &view = node.chainman->ActiveChainstate().CoinsTip();

View file

@ -85,11 +85,6 @@ void AppTests::appTests()
// Reset global state to avoid interfering with later tests. // Reset global state to avoid interfering with later tests.
LogInstance().DisconnectTestLogger(); LogInstance().DisconnectTestLogger();
AbortShutdown(); AbortShutdown();
{
LOCK(cs_main);
UnloadBlockIndex(/* mempool */ nullptr, g_chainman);
g_chainman.Reset();
}
} }
//! Entry point for BitcoinGUI tests. //! Entry point for BitcoinGUI tests.

View file

@ -146,14 +146,14 @@ void TestGUI(interfaces::Node& node)
LOCK2(wallet->cs_wallet, spk_man->cs_KeyStore); LOCK2(wallet->cs_wallet, spk_man->cs_KeyStore);
wallet->SetAddressBook(GetDestinationForKey(test.coinbaseKey.GetPubKey(), wallet->m_default_address_type), "", "receive"); wallet->SetAddressBook(GetDestinationForKey(test.coinbaseKey.GetPubKey(), wallet->m_default_address_type), "", "receive");
spk_man->AddKeyPubKey(test.coinbaseKey, test.coinbaseKey.GetPubKey()); spk_man->AddKeyPubKey(test.coinbaseKey, test.coinbaseKey.GetPubKey());
wallet->SetLastBlockProcessed(105, ::ChainActive().Tip()->GetBlockHash()); wallet->SetLastBlockProcessed(105, node.context()->chainman->ActiveChain().Tip()->GetBlockHash());
} }
{ {
WalletRescanReserver reserver(*wallet); WalletRescanReserver reserver(*wallet);
reserver.reserve(); reserver.reserve();
CWallet::ScanResult result = wallet->ScanForWalletTransactions(Params().GetConsensus().hashGenesisBlock, 0 /* block height */, {} /* max height */, reserver, true /* fUpdate */); CWallet::ScanResult result = wallet->ScanForWalletTransactions(Params().GetConsensus().hashGenesisBlock, 0 /* block height */, {} /* max height */, reserver, true /* fUpdate */);
QCOMPARE(result.status, CWallet::ScanResult::SUCCESS); QCOMPARE(result.status, CWallet::ScanResult::SUCCESS);
QCOMPARE(result.last_scanned_block, ::ChainActive().Tip()->GetBlockHash()); QCOMPARE(result.last_scanned_block, node.context()->chainman->ActiveChain().Tip()->GetBlockHash());
QVERIFY(result.last_failed_block.IsNull()); QVERIFY(result.last_failed_block.IsNull());
} }
wallet->SetBroadcastTransactions(true); wallet->SetBroadcastTransactions(true);

View file

@ -125,7 +125,7 @@ static ChainstateManager* GetChainman(const std::any& context, HTTPRequest* req)
__FILE__, __LINE__, __func__, PACKAGE_BUGREPORT)); __FILE__, __LINE__, __func__, PACKAGE_BUGREPORT));
return nullptr; return nullptr;
} }
return node_context->chainman; return node_context->chainman.get();
} }
static RetFormat ParseDataFormat(std::string& param, const std::string& strReq) static RetFormat ParseDataFormat(std::string& param, const std::string& strReq)

View file

@ -84,7 +84,6 @@ ChainstateManager& EnsureChainman(const NodeContext& node)
if (!node.chainman) { if (!node.chainman) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "Node chainman not found"); throw JSONRPCError(RPC_INTERNAL_ERROR, "Node chainman not found");
} }
WITH_LOCK(::cs_main, CHECK_NONFATAL(std::addressof(g_chainman) == std::addressof(*node.chainman)));
return *node.chainman; return *node.chainman;
} }

View file

@ -114,7 +114,6 @@ static bool GenerateBlock(ChainstateManager& chainman, CBlock& block, uint64_t&
{ {
LOCK(cs_main); LOCK(cs_main);
CHECK_NONFATAL(std::addressof(::ChainActive()) == std::addressof(chainman.ActiveChain()));
IncrementExtraNonce(&block, chainman.ActiveChain().Tip(), extra_nonce); IncrementExtraNonce(&block, chainman.ActiveChain().Tip(), extra_nonce);
} }
@ -147,7 +146,6 @@ static UniValue generateBlocks(ChainstateManager& chainman, const CTxMemPool& me
{ // Don't keep cs_main locked { // Don't keep cs_main locked
LOCK(cs_main); LOCK(cs_main);
CHECK_NONFATAL(std::addressof(::ChainActive()) == std::addressof(chainman.ActiveChain()));
nHeight = chainman.ActiveChain().Height(); nHeight = chainman.ActiveChain().Height();
nHeightEnd = nHeight+nGenerate; nHeightEnd = nHeight+nGenerate;
} }

View file

@ -62,7 +62,7 @@ CBlock BuildChainTestingSetup::CreateBlock(const CBlockIndex* prev,
const CScript& scriptPubKey) const CScript& scriptPubKey)
{ {
const CChainParams& chainparams = Params(); const CChainParams& chainparams = Params();
std::unique_ptr<CBlockTemplate> pblocktemplate = BlockAssembler(::ChainstateActive(), *m_node.mempool, chainparams).CreateNewBlock(scriptPubKey); std::unique_ptr<CBlockTemplate> pblocktemplate = BlockAssembler(m_node.chainman->ActiveChainstate(), *m_node.mempool, chainparams).CreateNewBlock(scriptPubKey);
CBlock& block = pblocktemplate->block; CBlock& block = pblocktemplate->block;
block.hashPrevBlock = prev->GetBlockHash(); block.hashPrevBlock = prev->GetBlockHash();
block.nTime = prev->nTime + 1; block.nTime = prev->nTime + 1;
@ -117,9 +117,9 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
std::vector<BlockFilter> filters; std::vector<BlockFilter> filters;
std::vector<uint256> filter_hashes; std::vector<uint256> filter_hashes;
for (const CBlockIndex* block_index = ::ChainActive().Genesis(); for (const CBlockIndex* block_index = m_node.chainman->ActiveChain().Genesis();
block_index != nullptr; block_index != nullptr;
block_index = ::ChainActive().Next(block_index)) { block_index = m_node.chainman->ActiveChain().Next(block_index)) {
BOOST_CHECK(!filter_index.LookupFilter(block_index, filter)); BOOST_CHECK(!filter_index.LookupFilter(block_index, filter));
BOOST_CHECK(!filter_index.LookupFilterHeader(block_index, filter_header)); BOOST_CHECK(!filter_index.LookupFilterHeader(block_index, filter_header));
BOOST_CHECK(!filter_index.LookupFilterRange(block_index->nHeight, block_index, filters)); BOOST_CHECK(!filter_index.LookupFilterRange(block_index->nHeight, block_index, filters));
@ -131,7 +131,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
// BlockUntilSyncedToCurrentChain should return false before index is started. // BlockUntilSyncedToCurrentChain should return false before index is started.
BOOST_CHECK(!filter_index.BlockUntilSyncedToCurrentChain()); BOOST_CHECK(!filter_index.BlockUntilSyncedToCurrentChain());
BOOST_REQUIRE(filter_index.Start(::ChainstateActive())); BOOST_REQUIRE(filter_index.Start(m_node.chainman->ActiveChainstate()));
// Allow filter index to catch up with the block index. // Allow filter index to catch up with the block index.
constexpr int64_t timeout_ms = 10 * 1000; constexpr int64_t timeout_ms = 10 * 1000;
@ -145,9 +145,9 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
{ {
LOCK(cs_main); LOCK(cs_main);
const CBlockIndex* block_index; const CBlockIndex* block_index;
for (block_index = ::ChainActive().Genesis(); for (block_index = m_node.chainman->ActiveChain().Genesis();
block_index != nullptr; block_index != nullptr;
block_index = ::ChainActive().Next(block_index)) { block_index = m_node.chainman->ActiveChain().Next(block_index)) {
CheckFilterLookups(filter_index, block_index, last_header); CheckFilterLookups(filter_index, block_index, last_header);
} }
} }
@ -156,7 +156,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
const CBlockIndex* tip; const CBlockIndex* tip;
{ {
LOCK(cs_main); LOCK(cs_main);
tip = ::ChainActive().Tip(); tip = m_node.chainman->ActiveChain().Tip();
} }
CKey coinbase_key_A, coinbase_key_B; CKey coinbase_key_A, coinbase_key_B;
coinbase_key_A.MakeNewKey(true); coinbase_key_A.MakeNewKey(true);
@ -178,7 +178,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
const CBlockIndex* block_index; const CBlockIndex* block_index;
{ {
LOCK(cs_main); LOCK(cs_main);
block_index = g_chainman.m_blockman.LookupBlockIndex(block->GetHash()); block_index = m_node.chainman->m_blockman.LookupBlockIndex(block->GetHash());
} }
BOOST_CHECK(filter_index.BlockUntilSyncedToCurrentChain()); BOOST_CHECK(filter_index.BlockUntilSyncedToCurrentChain());
@ -196,7 +196,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
const CBlockIndex* block_index; const CBlockIndex* block_index;
{ {
LOCK(cs_main); LOCK(cs_main);
block_index = g_chainman.m_blockman.LookupBlockIndex(block->GetHash()); block_index = m_node.chainman->m_blockman.LookupBlockIndex(block->GetHash());
} }
BOOST_CHECK(filter_index.BlockUntilSyncedToCurrentChain()); BOOST_CHECK(filter_index.BlockUntilSyncedToCurrentChain());
@ -210,7 +210,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
const CBlockIndex* block_index; const CBlockIndex* block_index;
{ {
LOCK(cs_main); LOCK(cs_main);
block_index = g_chainman.m_blockman.LookupBlockIndex(block->GetHash()); block_index = m_node.chainman->m_blockman.LookupBlockIndex(block->GetHash());
} }
BOOST_CHECK(filter_index.BlockUntilSyncedToCurrentChain()); BOOST_CHECK(filter_index.BlockUntilSyncedToCurrentChain());
@ -231,14 +231,14 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
{ {
LOCK(cs_main); LOCK(cs_main);
block_index = g_chainman.m_blockman.LookupBlockIndex(chainA[i]->GetHash()); block_index = m_node.chainman->m_blockman.LookupBlockIndex(chainA[i]->GetHash());
} }
BOOST_CHECK(filter_index.BlockUntilSyncedToCurrentChain()); BOOST_CHECK(filter_index.BlockUntilSyncedToCurrentChain());
CheckFilterLookups(filter_index, block_index, chainA_last_header); CheckFilterLookups(filter_index, block_index, chainA_last_header);
{ {
LOCK(cs_main); LOCK(cs_main);
block_index = g_chainman.m_blockman.LookupBlockIndex(chainB[i]->GetHash()); block_index = m_node.chainman->m_blockman.LookupBlockIndex(chainB[i]->GetHash());
} }
BOOST_CHECK(filter_index.BlockUntilSyncedToCurrentChain()); BOOST_CHECK(filter_index.BlockUntilSyncedToCurrentChain());
CheckFilterLookups(filter_index, block_index, chainB_last_header); CheckFilterLookups(filter_index, block_index, chainB_last_header);
@ -250,7 +250,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
{ {
LOCK(cs_main); LOCK(cs_main);
tip = ::ChainActive().Tip(); tip = m_node.chainman->ActiveChain().Tip();
} }
BOOST_CHECK(filter_index.LookupFilterRange(0, tip, filters)); BOOST_CHECK(filter_index.LookupFilterRange(0, tip, filters));
BOOST_CHECK(filter_index.LookupFilterHashRange(0, tip, filter_hashes)); BOOST_CHECK(filter_index.LookupFilterHashRange(0, tip, filter_hashes));

View file

@ -22,7 +22,7 @@ BOOST_FIXTURE_TEST_CASE(coinstatsindex_initial_sync, TestChain100Setup)
const CBlockIndex* block_index; const CBlockIndex* block_index;
{ {
LOCK(cs_main); LOCK(cs_main);
block_index = ChainActive().Tip(); block_index = m_node.chainman->ActiveChain().Tip();
} }
// CoinStatsIndex should not be found before it is started. // CoinStatsIndex should not be found before it is started.
@ -32,7 +32,7 @@ BOOST_FIXTURE_TEST_CASE(coinstatsindex_initial_sync, TestChain100Setup)
// is started. // is started.
BOOST_CHECK(!coin_stats_index.BlockUntilSyncedToCurrentChain()); BOOST_CHECK(!coin_stats_index.BlockUntilSyncedToCurrentChain());
BOOST_REQUIRE(coin_stats_index.Start(::ChainstateActive())); BOOST_REQUIRE(coin_stats_index.Start(m_node.chainman->ActiveChainstate()));
// Allow the CoinStatsIndex to catch up with the block index that is syncing // Allow the CoinStatsIndex to catch up with the block index that is syncing
// in a background thread. // in a background thread.
@ -46,7 +46,7 @@ BOOST_FIXTURE_TEST_CASE(coinstatsindex_initial_sync, TestChain100Setup)
const CBlockIndex* genesis_block_index; const CBlockIndex* genesis_block_index;
{ {
LOCK(cs_main); LOCK(cs_main);
genesis_block_index = ChainActive().Genesis(); genesis_block_index = m_node.chainman->ActiveChain().Genesis();
} }
BOOST_CHECK(coin_stats_index.LookUpStats(genesis_block_index, coin_stats)); BOOST_CHECK(coin_stats_index.LookUpStats(genesis_block_index, coin_stats));
@ -64,7 +64,7 @@ BOOST_FIXTURE_TEST_CASE(coinstatsindex_initial_sync, TestChain100Setup)
const CBlockIndex* new_block_index; const CBlockIndex* new_block_index;
{ {
LOCK(cs_main); LOCK(cs_main);
new_block_index = ChainActive().Tip(); new_block_index = m_node.chainman->ActiveChain().Tip();
} }
coin_stats_index.LookUpStats(new_block_index, new_coin_stats); coin_stats_index.LookUpStats(new_block_index, new_coin_stats);

View file

@ -66,8 +66,8 @@ BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction)
// This test requires that we have a chain with non-zero work. // This test requires that we have a chain with non-zero work.
{ {
LOCK(cs_main); LOCK(cs_main);
BOOST_CHECK(::ChainActive().Tip() != nullptr); BOOST_CHECK(m_node.chainman->ActiveChain().Tip() != nullptr);
BOOST_CHECK(::ChainActive().Tip()->nChainWork > 0); BOOST_CHECK(m_node.chainman->ActiveChain().Tip()->nChainWork > 0);
} }
// Test starts here // Test starts here

View file

@ -27,6 +27,7 @@
#include <vector> #include <vector>
namespace { namespace {
const TestingSetup* g_setup;
const Coin EMPTY_COIN{}; const Coin EMPTY_COIN{};
bool operator==(const Coin& a, const Coin& b) bool operator==(const Coin& a, const Coin& b)
@ -39,6 +40,7 @@ bool operator==(const Coin& a, const Coin& b)
void initialize_coins_view() void initialize_coins_view()
{ {
static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>(); static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>();
g_setup = testing_setup.get();
} }
FUZZ_TARGET_INIT(coins_view, initialize_coins_view) FUZZ_TARGET_INIT(coins_view, initialize_coins_view)
@ -268,7 +270,7 @@ FUZZ_TARGET_INIT(coins_view, initialize_coins_view)
CCoinsStats stats{CoinStatsHashType::HASH_SERIALIZED}; CCoinsStats stats{CoinStatsHashType::HASH_SERIALIZED};
bool expected_code_path = false; bool expected_code_path = false;
try { try {
(void)GetUTXOStats(&coins_view_cache, WITH_LOCK(::cs_main, return std::ref(g_chainman.m_blockman)), stats); (void)GetUTXOStats(&coins_view_cache, WITH_LOCK(::cs_main, return std::ref(g_setup->m_node.chainman->m_blockman)), stats);
} catch (const std::logic_error&) { } catch (const std::logic_error&) {
expected_code_path = true; expected_code_path = true;
} }

View file

@ -13,9 +13,14 @@
#include <cstdint> #include <cstdint>
#include <vector> #include <vector>
namespace {
const TestingSetup* g_setup;
} // namespace
void initialize_load_external_block_file() void initialize_load_external_block_file()
{ {
static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>(); static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>();
g_setup = testing_setup.get();
} }
FUZZ_TARGET_INIT(load_external_block_file, initialize_load_external_block_file) FUZZ_TARGET_INIT(load_external_block_file, initialize_load_external_block_file)
@ -27,5 +32,5 @@ FUZZ_TARGET_INIT(load_external_block_file, initialize_load_external_block_file)
return; return;
} }
FlatFilePos flat_file_pos; FlatFilePos flat_file_pos;
::ChainstateActive().LoadExternalBlockFile(Params(), fuzzed_block_file, fuzzed_data_provider.ConsumeBool() ? &flat_file_pos : nullptr); g_setup->m_node.chainman->ActiveChainstate().LoadExternalBlockFile(Params(), fuzzed_block_file, fuzzed_data_provider.ConsumeBool() ? &flat_file_pos : nullptr);
} }

View file

@ -14,9 +14,14 @@
#include <cstdint> #include <cstdint>
#include <vector> #include <vector>
namespace {
const TestingSetup* g_setup;
} // namespace
void initialize_validation_load_mempool() void initialize_validation_load_mempool()
{ {
static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>(); static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>();
g_setup = testing_setup.get();
} }
FUZZ_TARGET_INIT(validation_load_mempool, initialize_validation_load_mempool) FUZZ_TARGET_INIT(validation_load_mempool, initialize_validation_load_mempool)
@ -29,6 +34,6 @@ FUZZ_TARGET_INIT(validation_load_mempool, initialize_validation_load_mempool)
auto fuzzed_fopen = [&](const fs::path&, const char*) { auto fuzzed_fopen = [&](const fs::path&, const char*) {
return fuzzed_file_provider.open(); return fuzzed_file_provider.open();
}; };
(void)LoadMempool(pool, ::ChainstateActive(), fuzzed_fopen); (void)LoadMempool(pool, g_setup->m_node.chainman->ActiveChainstate(), fuzzed_fopen);
(void)DumpMempool(pool, fuzzed_fopen, true); (void)DumpMempool(pool, fuzzed_fopen, true);
} }

View file

@ -98,7 +98,7 @@ BOOST_AUTO_TEST_CASE(findCommonAncestor)
auto* orig_tip = active.Tip(); auto* orig_tip = active.Tip();
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {
BlockValidationState state; BlockValidationState state;
ChainstateActive().InvalidateBlock(state, Params(), active.Tip()); m_node.chainman->ActiveChainstate().InvalidateBlock(state, Params(), active.Tip());
} }
BOOST_CHECK_EQUAL(active.Height(), orig_tip->nHeight - 10); BOOST_CHECK_EQUAL(active.Height(), orig_tip->nHeight - 10);
coinbaseKey.MakeNewKey(true); coinbaseKey.MakeNewKey(true);

View file

@ -45,7 +45,7 @@ BlockAssembler MinerTestingSetup::AssemblerForTest(const CChainParams& params)
options.nBlockMaxWeight = MAX_BLOCK_WEIGHT; options.nBlockMaxWeight = MAX_BLOCK_WEIGHT;
options.blockMinFeeRate = blockMinFeeRate; options.blockMinFeeRate = blockMinFeeRate;
return BlockAssembler(::ChainstateActive(), *m_node.mempool, params, options); return BlockAssembler(m_node.chainman->ActiveChainstate(), *m_node.mempool, params, options);
} }
constexpr static struct { constexpr static struct {
@ -82,11 +82,11 @@ constexpr static struct {
{2, 0xbbbeb305}, {2, 0xfe1c810a}, {2, 0xbbbeb305}, {2, 0xfe1c810a},
}; };
static CBlockIndex CreateBlockIndex(int nHeight) EXCLUSIVE_LOCKS_REQUIRED(cs_main) static CBlockIndex CreateBlockIndex(int nHeight, CBlockIndex* active_chain_tip) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{ {
CBlockIndex index; CBlockIndex index;
index.nHeight = nHeight; index.nHeight = nHeight;
index.pprev = ::ChainActive().Tip(); index.pprev = active_chain_tip;
return index; return index;
} }
@ -228,17 +228,17 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
{ {
LOCK(cs_main); LOCK(cs_main);
pblock->nVersion = 1; pblock->nVersion = 1;
pblock->nTime = ::ChainActive().Tip()->GetMedianTimePast()+1; pblock->nTime = m_node.chainman->ActiveChain().Tip()->GetMedianTimePast()+1;
CMutableTransaction txCoinbase(*pblock->vtx[0]); CMutableTransaction txCoinbase(*pblock->vtx[0]);
txCoinbase.nVersion = 1; txCoinbase.nVersion = 1;
txCoinbase.vin[0].scriptSig = CScript(); txCoinbase.vin[0].scriptSig = CScript();
txCoinbase.vin[0].scriptSig.push_back(bi.extranonce); txCoinbase.vin[0].scriptSig.push_back(bi.extranonce);
txCoinbase.vin[0].scriptSig.push_back(::ChainActive().Height()); txCoinbase.vin[0].scriptSig.push_back(m_node.chainman->ActiveChain().Height());
txCoinbase.vout.resize(1); // Ignore the (optional) segwit commitment added by CreateNewBlock (as the hardcoded nonces don't account for this) txCoinbase.vout.resize(1); // Ignore the (optional) segwit commitment added by CreateNewBlock (as the hardcoded nonces don't account for this)
txCoinbase.vout[0].scriptPubKey = CScript(); txCoinbase.vout[0].scriptPubKey = CScript();
pblock->vtx[0] = MakeTransactionRef(std::move(txCoinbase)); pblock->vtx[0] = MakeTransactionRef(std::move(txCoinbase));
if (txFirst.size() == 0) if (txFirst.size() == 0)
baseheight = ::ChainActive().Height(); baseheight = m_node.chainman->ActiveChain().Height();
if (txFirst.size() < 4) if (txFirst.size() < 4)
txFirst.push_back(pblock->vtx[0]); txFirst.push_back(pblock->vtx[0]);
pblock->hashMerkleRoot = BlockMerkleRoot(*pblock); pblock->hashMerkleRoot = BlockMerkleRoot(*pblock);
@ -364,29 +364,29 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
m_node.mempool->clear(); m_node.mempool->clear();
// subsidy changing // subsidy changing
int nHeight = ::ChainActive().Height(); int nHeight = m_node.chainman->ActiveChain().Height();
// Create an actual 209999-long block chain (without valid blocks). // Create an actual 209999-long block chain (without valid blocks).
while (::ChainActive().Tip()->nHeight < 209999) { while (m_node.chainman->ActiveChain().Tip()->nHeight < 209999) {
CBlockIndex* prev = ::ChainActive().Tip(); CBlockIndex* prev = m_node.chainman->ActiveChain().Tip();
CBlockIndex* next = new CBlockIndex(); CBlockIndex* next = new CBlockIndex();
next->phashBlock = new uint256(InsecureRand256()); next->phashBlock = new uint256(InsecureRand256());
::ChainstateActive().CoinsTip().SetBestBlock(next->GetBlockHash()); m_node.chainman->ActiveChainstate().CoinsTip().SetBestBlock(next->GetBlockHash());
next->pprev = prev; next->pprev = prev;
next->nHeight = prev->nHeight + 1; next->nHeight = prev->nHeight + 1;
next->BuildSkip(); next->BuildSkip();
::ChainActive().SetTip(next); m_node.chainman->ActiveChain().SetTip(next);
} }
BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
// Extend to a 210000-long block chain. // Extend to a 210000-long block chain.
while (::ChainActive().Tip()->nHeight < 210000) { while (m_node.chainman->ActiveChain().Tip()->nHeight < 210000) {
CBlockIndex* prev = ::ChainActive().Tip(); CBlockIndex* prev = m_node.chainman->ActiveChain().Tip();
CBlockIndex* next = new CBlockIndex(); CBlockIndex* next = new CBlockIndex();
next->phashBlock = new uint256(InsecureRand256()); next->phashBlock = new uint256(InsecureRand256());
::ChainstateActive().CoinsTip().SetBestBlock(next->GetBlockHash()); m_node.chainman->ActiveChainstate().CoinsTip().SetBestBlock(next->GetBlockHash());
next->pprev = prev; next->pprev = prev;
next->nHeight = prev->nHeight + 1; next->nHeight = prev->nHeight + 1;
next->BuildSkip(); next->BuildSkip();
::ChainActive().SetTip(next); m_node.chainman->ActiveChain().SetTip(next);
} }
BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
@ -409,16 +409,16 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
m_node.mempool->clear(); m_node.mempool->clear();
// Delete the dummy blocks again. // Delete the dummy blocks again.
while (::ChainActive().Tip()->nHeight > nHeight) { while (m_node.chainman->ActiveChain().Tip()->nHeight > nHeight) {
CBlockIndex* del = ::ChainActive().Tip(); CBlockIndex* del = m_node.chainman->ActiveChain().Tip();
::ChainActive().SetTip(del->pprev); m_node.chainman->ActiveChain().SetTip(del->pprev);
::ChainstateActive().CoinsTip().SetBestBlock(del->pprev->GetBlockHash()); m_node.chainman->ActiveChainstate().CoinsTip().SetBestBlock(del->pprev->GetBlockHash());
delete del->phashBlock; delete del->phashBlock;
delete del; delete del;
} }
// non-final txs in mempool // non-final txs in mempool
SetMockTime(::ChainActive().Tip()->GetMedianTimePast()+1); SetMockTime(m_node.chainman->ActiveChain().Tip()->GetMedianTimePast()+1);
int flags = LOCKTIME_VERIFY_SEQUENCE|LOCKTIME_MEDIAN_TIME_PAST; int flags = LOCKTIME_VERIFY_SEQUENCE|LOCKTIME_MEDIAN_TIME_PAST;
// height map // height map
std::vector<int> prevheights; std::vector<int> prevheights;
@ -430,7 +430,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx.vin[0].prevout.hash = txFirst[0]->GetHash(); // only 1 transaction tx.vin[0].prevout.hash = txFirst[0]->GetHash(); // only 1 transaction
tx.vin[0].prevout.n = 0; tx.vin[0].prevout.n = 0;
tx.vin[0].scriptSig = CScript() << OP_1; tx.vin[0].scriptSig = CScript() << OP_1;
tx.vin[0].nSequence = ::ChainActive().Tip()->nHeight + 1; // txFirst[0] is the 2nd block tx.vin[0].nSequence = m_node.chainman->ActiveChain().Tip()->nHeight + 1; // txFirst[0] is the 2nd block
prevheights[0] = baseheight + 1; prevheights[0] = baseheight + 1;
tx.vout.resize(1); tx.vout.resize(1);
tx.vout[0].nValue = BLOCKSUBSIDY-HIGHFEE; tx.vout[0].nValue = BLOCKSUBSIDY-HIGHFEE;
@ -438,53 +438,62 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx.nLockTime = 0; tx.nLockTime = 0;
hash = tx.GetHash(); hash = tx.GetHash();
m_node.mempool->addUnchecked(entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); m_node.mempool->addUnchecked(entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
BOOST_CHECK(CheckFinalTx(::ChainActive().Tip(), CTransaction(tx), flags)); // Locktime passes BOOST_CHECK(CheckFinalTx(m_node.chainman->ActiveChain().Tip(), CTransaction(tx), flags)); // Locktime passes
BOOST_CHECK(!TestSequenceLocks(CTransaction(tx), flags)); // Sequence locks fail BOOST_CHECK(!TestSequenceLocks(CTransaction(tx), flags)); // Sequence locks fail
BOOST_CHECK(SequenceLocks(CTransaction(tx), flags, prevheights, CreateBlockIndex(::ChainActive().Tip()->nHeight + 2))); // Sequence locks pass on 2nd block
{
CBlockIndex* active_chain_tip = m_node.chainman->ActiveChain().Tip();
BOOST_CHECK(SequenceLocks(CTransaction(tx), flags, prevheights, CreateBlockIndex(active_chain_tip->nHeight + 2, active_chain_tip))); // Sequence locks pass on 2nd block
}
// relative time locked // relative time locked
tx.vin[0].prevout.hash = txFirst[1]->GetHash(); tx.vin[0].prevout.hash = txFirst[1]->GetHash();
tx.vin[0].nSequence = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG | (((::ChainActive().Tip()->GetMedianTimePast()+1-::ChainActive()[1]->GetMedianTimePast()) >> CTxIn::SEQUENCE_LOCKTIME_GRANULARITY) + 1); // txFirst[1] is the 3rd block tx.vin[0].nSequence = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG | (((m_node.chainman->ActiveChain().Tip()->GetMedianTimePast()+1-m_node.chainman->ActiveChain()[1]->GetMedianTimePast()) >> CTxIn::SEQUENCE_LOCKTIME_GRANULARITY) + 1); // txFirst[1] is the 3rd block
prevheights[0] = baseheight + 2; prevheights[0] = baseheight + 2;
hash = tx.GetHash(); hash = tx.GetHash();
m_node.mempool->addUnchecked(entry.Time(GetTime()).FromTx(tx)); m_node.mempool->addUnchecked(entry.Time(GetTime()).FromTx(tx));
BOOST_CHECK(CheckFinalTx(::ChainActive().Tip(), CTransaction(tx), flags)); // Locktime passes BOOST_CHECK(CheckFinalTx(m_node.chainman->ActiveChain().Tip(), CTransaction(tx), flags)); // Locktime passes
BOOST_CHECK(!TestSequenceLocks(CTransaction(tx), flags)); // Sequence locks fail BOOST_CHECK(!TestSequenceLocks(CTransaction(tx), flags)); // Sequence locks fail
for (int i = 0; i < CBlockIndex::nMedianTimeSpan; i++) for (int i = 0; i < CBlockIndex::nMedianTimeSpan; i++)
::ChainActive().Tip()->GetAncestor(::ChainActive().Tip()->nHeight - i)->nTime += 512; //Trick the MedianTimePast m_node.chainman->ActiveChain().Tip()->GetAncestor(m_node.chainman->ActiveChain().Tip()->nHeight - i)->nTime += 512; //Trick the MedianTimePast
BOOST_CHECK(SequenceLocks(CTransaction(tx), flags, prevheights, CreateBlockIndex(::ChainActive().Tip()->nHeight + 1))); // Sequence locks pass 512 seconds later
{
CBlockIndex* active_chain_tip = m_node.chainman->ActiveChain().Tip();
BOOST_CHECK(SequenceLocks(CTransaction(tx), flags, prevheights, CreateBlockIndex(active_chain_tip->nHeight + 1, active_chain_tip))); // Sequence locks pass 512 seconds later
}
for (int i = 0; i < CBlockIndex::nMedianTimeSpan; i++) for (int i = 0; i < CBlockIndex::nMedianTimeSpan; i++)
::ChainActive().Tip()->GetAncestor(::ChainActive().Tip()->nHeight - i)->nTime -= 512; //undo tricked MTP m_node.chainman->ActiveChain().Tip()->GetAncestor(m_node.chainman->ActiveChain().Tip()->nHeight - i)->nTime -= 512; //undo tricked MTP
// absolute height locked // absolute height locked
tx.vin[0].prevout.hash = txFirst[2]->GetHash(); tx.vin[0].prevout.hash = txFirst[2]->GetHash();
tx.vin[0].nSequence = CTxIn::SEQUENCE_FINAL - 1; tx.vin[0].nSequence = CTxIn::SEQUENCE_FINAL - 1;
prevheights[0] = baseheight + 3; prevheights[0] = baseheight + 3;
tx.nLockTime = ::ChainActive().Tip()->nHeight + 1; tx.nLockTime = m_node.chainman->ActiveChain().Tip()->nHeight + 1;
hash = tx.GetHash(); hash = tx.GetHash();
m_node.mempool->addUnchecked(entry.Time(GetTime()).FromTx(tx)); m_node.mempool->addUnchecked(entry.Time(GetTime()).FromTx(tx));
BOOST_CHECK(!CheckFinalTx(::ChainActive().Tip(), CTransaction(tx), flags)); // Locktime fails BOOST_CHECK(!CheckFinalTx(m_node.chainman->ActiveChain().Tip(), CTransaction(tx), flags)); // Locktime fails
BOOST_CHECK(TestSequenceLocks(CTransaction(tx), flags)); // Sequence locks pass BOOST_CHECK(TestSequenceLocks(CTransaction(tx), flags)); // Sequence locks pass
BOOST_CHECK(IsFinalTx(CTransaction(tx), ::ChainActive().Tip()->nHeight + 2, ::ChainActive().Tip()->GetMedianTimePast())); // Locktime passes on 2nd block BOOST_CHECK(IsFinalTx(CTransaction(tx), m_node.chainman->ActiveChain().Tip()->nHeight + 2, m_node.chainman->ActiveChain().Tip()->GetMedianTimePast())); // Locktime passes on 2nd block
// absolute time locked // absolute time locked
tx.vin[0].prevout.hash = txFirst[3]->GetHash(); tx.vin[0].prevout.hash = txFirst[3]->GetHash();
tx.nLockTime = ::ChainActive().Tip()->GetMedianTimePast(); tx.nLockTime = m_node.chainman->ActiveChain().Tip()->GetMedianTimePast();
prevheights.resize(1); prevheights.resize(1);
prevheights[0] = baseheight + 4; prevheights[0] = baseheight + 4;
hash = tx.GetHash(); hash = tx.GetHash();
m_node.mempool->addUnchecked(entry.Time(GetTime()).FromTx(tx)); m_node.mempool->addUnchecked(entry.Time(GetTime()).FromTx(tx));
BOOST_CHECK(!CheckFinalTx(::ChainActive().Tip(), CTransaction(tx), flags)); // Locktime fails BOOST_CHECK(!CheckFinalTx(m_node.chainman->ActiveChain().Tip(), CTransaction(tx), flags)); // Locktime fails
BOOST_CHECK(TestSequenceLocks(CTransaction(tx), flags)); // Sequence locks pass BOOST_CHECK(TestSequenceLocks(CTransaction(tx), flags)); // Sequence locks pass
BOOST_CHECK(IsFinalTx(CTransaction(tx), ::ChainActive().Tip()->nHeight + 2, ::ChainActive().Tip()->GetMedianTimePast() + 1)); // Locktime passes 1 second later BOOST_CHECK(IsFinalTx(CTransaction(tx), m_node.chainman->ActiveChain().Tip()->nHeight + 2, m_node.chainman->ActiveChain().Tip()->GetMedianTimePast() + 1)); // Locktime passes 1 second later
// mempool-dependent transactions (not added) // mempool-dependent transactions (not added)
tx.vin[0].prevout.hash = hash; tx.vin[0].prevout.hash = hash;
prevheights[0] = ::ChainActive().Tip()->nHeight + 1; prevheights[0] = m_node.chainman->ActiveChain().Tip()->nHeight + 1;
tx.nLockTime = 0; tx.nLockTime = 0;
tx.vin[0].nSequence = 0; tx.vin[0].nSequence = 0;
BOOST_CHECK(CheckFinalTx(::ChainActive().Tip(), CTransaction(tx), flags)); // Locktime passes BOOST_CHECK(CheckFinalTx(m_node.chainman->ActiveChain().Tip(), CTransaction(tx), flags)); // Locktime passes
BOOST_CHECK(TestSequenceLocks(CTransaction(tx), flags)); // Sequence locks pass BOOST_CHECK(TestSequenceLocks(CTransaction(tx), flags)); // Sequence locks pass
tx.vin[0].nSequence = 1; tx.vin[0].nSequence = 1;
BOOST_CHECK(!TestSequenceLocks(CTransaction(tx), flags)); // Sequence locks fail BOOST_CHECK(!TestSequenceLocks(CTransaction(tx), flags)); // Sequence locks fail
@ -502,14 +511,14 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 3U); BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 3U);
// However if we advance height by 1 and time by 512, all of them should be mined // However if we advance height by 1 and time by 512, all of them should be mined
for (int i = 0; i < CBlockIndex::nMedianTimeSpan; i++) for (int i = 0; i < CBlockIndex::nMedianTimeSpan; i++)
::ChainActive().Tip()->GetAncestor(::ChainActive().Tip()->nHeight - i)->nTime += 512; //Trick the MedianTimePast m_node.chainman->ActiveChain().Tip()->GetAncestor(m_node.chainman->ActiveChain().Tip()->nHeight - i)->nTime += 512; //Trick the MedianTimePast
::ChainActive().Tip()->nHeight++; m_node.chainman->ActiveChain().Tip()->nHeight++;
SetMockTime(::ChainActive().Tip()->GetMedianTimePast() + 1); SetMockTime(m_node.chainman->ActiveChain().Tip()->GetMedianTimePast() + 1);
BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 5U); BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 5U);
::ChainActive().Tip()->nHeight--; m_node.chainman->ActiveChain().Tip()->nHeight--;
SetMockTime(0); SetMockTime(0);
m_node.mempool->clear(); m_node.mempool->clear();

View file

@ -28,7 +28,7 @@ BOOST_FIXTURE_TEST_CASE(txindex_initial_sync, TestChain100Setup)
// BlockUntilSyncedToCurrentChain should return false before txindex is started. // BlockUntilSyncedToCurrentChain should return false before txindex is started.
BOOST_CHECK(!txindex.BlockUntilSyncedToCurrentChain()); BOOST_CHECK(!txindex.BlockUntilSyncedToCurrentChain());
BOOST_REQUIRE(txindex.Start(::ChainstateActive())); BOOST_REQUIRE(txindex.Start(m_node.chainman->ActiveChainstate()));
// Allow tx index to catch up with the block index. // Allow tx index to catch up with the block index.
constexpr int64_t timeout_ms = 10 * 1000; constexpr int64_t timeout_ms = 10 * 1000;

View file

@ -37,7 +37,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_reject_coinbase, TestChain100Setup)
LOCK(cs_main); LOCK(cs_main);
unsigned int initialPoolSize = m_node.mempool->size(); unsigned int initialPoolSize = m_node.mempool->size();
const MempoolAcceptResult result = AcceptToMemoryPool(::ChainstateActive(), *m_node.mempool, MakeTransactionRef(coinbaseTx), const MempoolAcceptResult result = AcceptToMemoryPool(m_node.chainman->ActiveChainstate(), *m_node.mempool, MakeTransactionRef(coinbaseTx),
true /* bypass_limits */); true /* bypass_limits */);
BOOST_CHECK(result.m_result_type == MempoolAcceptResult::ResultType::INVALID); BOOST_CHECK(result.m_result_type == MempoolAcceptResult::ResultType::INVALID);

View file

@ -31,7 +31,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)
const auto ToMemPool = [this](const CMutableTransaction& tx) { const auto ToMemPool = [this](const CMutableTransaction& tx) {
LOCK(cs_main); LOCK(cs_main);
const MempoolAcceptResult result = AcceptToMemoryPool(::ChainstateActive(), *m_node.mempool, MakeTransactionRef(tx), const MempoolAcceptResult result = AcceptToMemoryPool(m_node.chainman->ActiveChainstate(), *m_node.mempool, MakeTransactionRef(tx),
true /* bypass_limits */); true /* bypass_limits */);
return result.m_result_type == MempoolAcceptResult::ResultType::VALID; return result.m_result_type == MempoolAcceptResult::ResultType::VALID;
}; };
@ -63,7 +63,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)
block = CreateAndProcessBlock(spends, scriptPubKey); block = CreateAndProcessBlock(spends, scriptPubKey);
{ {
LOCK(cs_main); LOCK(cs_main);
BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() != block.GetHash()); BOOST_CHECK(m_node.chainman->ActiveChain().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
@ -71,7 +71,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)
block = CreateAndProcessBlock(spends, scriptPubKey); block = CreateAndProcessBlock(spends, scriptPubKey);
{ {
LOCK(cs_main); LOCK(cs_main);
BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() != block.GetHash()); BOOST_CHECK(m_node.chainman->ActiveChain().Tip()->GetBlockHash() != block.GetHash());
} }
m_node.mempool->clear(); m_node.mempool->clear();
@ -80,7 +80,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)
block = CreateAndProcessBlock(spends, scriptPubKey); block = CreateAndProcessBlock(spends, scriptPubKey);
{ {
LOCK(cs_main); LOCK(cs_main);
BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() != block.GetHash()); BOOST_CHECK(m_node.chainman->ActiveChain().Tip()->GetBlockHash() != block.GetHash());
} }
m_node.mempool->clear(); m_node.mempool->clear();
@ -91,7 +91,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)
block = CreateAndProcessBlock(oneSpend, scriptPubKey); block = CreateAndProcessBlock(oneSpend, scriptPubKey);
{ {
LOCK(cs_main); LOCK(cs_main);
BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() == block.GetHash()); BOOST_CHECK(m_node.chainman->ActiveChain().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:
@ -109,7 +109,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)
// should fail. // should fail.
// Capture this interaction with the upgraded_nop argument: set it when evaluating // Capture this interaction with the upgraded_nop argument: set it when evaluating
// any script flag that is implemented as an upgraded NOP code. // any script flag that is implemented as an upgraded NOP code.
static void ValidateCheckInputsForAllFlags(const CTransaction &tx, uint32_t failing_flags, bool add_to_cache) EXCLUSIVE_LOCKS_REQUIRED(cs_main) static void ValidateCheckInputsForAllFlags(const CTransaction &tx, uint32_t failing_flags, bool add_to_cache, CCoinsViewCache& active_coins_tip) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{ {
PrecomputedTransactionData txdata; PrecomputedTransactionData txdata;
// If we add many more flags, this loop can get too expensive, but we can // If we add many more flags, this loop can get too expensive, but we can
@ -126,7 +126,7 @@ static void ValidateCheckInputsForAllFlags(const CTransaction &tx, uint32_t fail
// WITNESS requires P2SH // WITNESS requires P2SH
test_flags |= SCRIPT_VERIFY_P2SH; test_flags |= SCRIPT_VERIFY_P2SH;
} }
bool ret = CheckInputScripts(tx, state, &::ChainstateActive().CoinsTip(), test_flags, true, add_to_cache, txdata, nullptr); bool ret = CheckInputScripts(tx, state, &active_coins_tip, test_flags, true, add_to_cache, txdata, nullptr);
// CheckInputScripts should succeed iff test_flags doesn't intersect with // CheckInputScripts should succeed iff test_flags doesn't intersect with
// failing_flags // failing_flags
bool expected_return_value = !(test_flags & failing_flags); bool expected_return_value = !(test_flags & failing_flags);
@ -136,13 +136,13 @@ static void ValidateCheckInputsForAllFlags(const CTransaction &tx, uint32_t fail
if (ret && add_to_cache) { if (ret && add_to_cache) {
// Check that we get a cache hit if the tx was valid // Check that we get a cache hit if the tx was valid
std::vector<CScriptCheck> scriptchecks; std::vector<CScriptCheck> scriptchecks;
BOOST_CHECK(CheckInputScripts(tx, state, &::ChainstateActive().CoinsTip(), test_flags, true, add_to_cache, txdata, &scriptchecks)); BOOST_CHECK(CheckInputScripts(tx, state, &active_coins_tip, test_flags, true, add_to_cache, txdata, &scriptchecks));
BOOST_CHECK(scriptchecks.empty()); BOOST_CHECK(scriptchecks.empty());
} else { } else {
// Check that we get script executions to check, if the transaction // Check that we get script executions to check, if the transaction
// was invalid, or we didn't add to cache. // was invalid, or we didn't add to cache.
std::vector<CScriptCheck> scriptchecks; std::vector<CScriptCheck> scriptchecks;
BOOST_CHECK(CheckInputScripts(tx, state, &::ChainstateActive().CoinsTip(), test_flags, true, add_to_cache, txdata, &scriptchecks)); BOOST_CHECK(CheckInputScripts(tx, state, &active_coins_tip, test_flags, true, add_to_cache, txdata, &scriptchecks));
BOOST_CHECK_EQUAL(scriptchecks.size(), tx.vin.size()); BOOST_CHECK_EQUAL(scriptchecks.size(), tx.vin.size());
} }
} }
@ -205,20 +205,20 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
TxValidationState state; TxValidationState state;
PrecomputedTransactionData ptd_spend_tx; PrecomputedTransactionData ptd_spend_tx;
BOOST_CHECK(!CheckInputScripts(CTransaction(spend_tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, nullptr)); BOOST_CHECK(!CheckInputScripts(CTransaction(spend_tx), state, &m_node.chainman->ActiveChainstate().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, nullptr));
// If we call again asking for scriptchecks (as happens in // If we call again asking for scriptchecks (as happens in
// ConnectBlock), we should add a script check object for this -- we're // ConnectBlock), we should add a script check object for this -- we're
// not caching invalidity (if that changes, delete this test case). // not caching invalidity (if that changes, delete this test case).
std::vector<CScriptCheck> scriptchecks; std::vector<CScriptCheck> scriptchecks;
BOOST_CHECK(CheckInputScripts(CTransaction(spend_tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, &scriptchecks)); BOOST_CHECK(CheckInputScripts(CTransaction(spend_tx), state, &m_node.chainman->ActiveChainstate().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, &scriptchecks));
BOOST_CHECK_EQUAL(scriptchecks.size(), 1U); BOOST_CHECK_EQUAL(scriptchecks.size(), 1U);
// Test that CheckInputScripts returns true iff DERSIG-enforcing flags are // Test that CheckInputScripts returns true iff DERSIG-enforcing flags are
// not present. Don't add these checks to the cache, so that we can // not present. Don't add these checks to the cache, so that we can
// test later that block validation works fine in the absence of cached // test later that block validation works fine in the absence of cached
// successes. // successes.
ValidateCheckInputsForAllFlags(CTransaction(spend_tx), SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC, false); ValidateCheckInputsForAllFlags(CTransaction(spend_tx), SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC, false, m_node.chainman->ActiveChainstate().CoinsTip());
} }
// And if we produce a block with this tx, it should be valid (DERSIG not // And if we produce a block with this tx, it should be valid (DERSIG not
@ -227,8 +227,8 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
block = CreateAndProcessBlock({spend_tx}, p2pk_scriptPubKey); block = CreateAndProcessBlock({spend_tx}, p2pk_scriptPubKey);
LOCK(cs_main); LOCK(cs_main);
BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() == block.GetHash()); BOOST_CHECK(m_node.chainman->ActiveChain().Tip()->GetBlockHash() == block.GetHash());
BOOST_CHECK(::ChainstateActive().CoinsTip().GetBestBlock() == block.GetHash()); BOOST_CHECK(m_node.chainman->ActiveChainstate().CoinsTip().GetBestBlock() == block.GetHash());
// Test P2SH: construct a transaction that is valid without P2SH, and // Test P2SH: construct a transaction that is valid without P2SH, and
// then test validity with P2SH. // then test validity with P2SH.
@ -244,7 +244,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
std::vector<unsigned char> vchSig2(p2pk_scriptPubKey.begin(), p2pk_scriptPubKey.end()); std::vector<unsigned char> vchSig2(p2pk_scriptPubKey.begin(), p2pk_scriptPubKey.end());
invalid_under_p2sh_tx.vin[0].scriptSig << vchSig2; invalid_under_p2sh_tx.vin[0].scriptSig << vchSig2;
ValidateCheckInputsForAllFlags(CTransaction(invalid_under_p2sh_tx), SCRIPT_VERIFY_P2SH, true); ValidateCheckInputsForAllFlags(CTransaction(invalid_under_p2sh_tx), SCRIPT_VERIFY_P2SH, true, m_node.chainman->ActiveChainstate().CoinsTip());
} }
// Test CHECKLOCKTIMEVERIFY // Test CHECKLOCKTIMEVERIFY
@ -267,13 +267,13 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
vchSig.push_back((unsigned char)SIGHASH_ALL); vchSig.push_back((unsigned char)SIGHASH_ALL);
invalid_with_cltv_tx.vin[0].scriptSig = CScript() << vchSig << 101; invalid_with_cltv_tx.vin[0].scriptSig = CScript() << vchSig << 101;
ValidateCheckInputsForAllFlags(CTransaction(invalid_with_cltv_tx), SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, true); ValidateCheckInputsForAllFlags(CTransaction(invalid_with_cltv_tx), SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, true, m_node.chainman->ActiveChainstate().CoinsTip());
// Make it valid, and check again // Make it valid, and check again
invalid_with_cltv_tx.vin[0].scriptSig = CScript() << vchSig << 100; invalid_with_cltv_tx.vin[0].scriptSig = CScript() << vchSig << 100;
TxValidationState state; TxValidationState state;
PrecomputedTransactionData txdata; PrecomputedTransactionData txdata;
BOOST_CHECK(CheckInputScripts(CTransaction(invalid_with_cltv_tx), state, ::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, true, true, txdata, nullptr)); BOOST_CHECK(CheckInputScripts(CTransaction(invalid_with_cltv_tx), state, m_node.chainman->ActiveChainstate().CoinsTip(), SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, true, true, txdata, nullptr));
} }
// TEST CHECKSEQUENCEVERIFY // TEST CHECKSEQUENCEVERIFY
@ -295,13 +295,13 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
vchSig.push_back((unsigned char)SIGHASH_ALL); vchSig.push_back((unsigned char)SIGHASH_ALL);
invalid_with_csv_tx.vin[0].scriptSig = CScript() << vchSig << 101; invalid_with_csv_tx.vin[0].scriptSig = CScript() << vchSig << 101;
ValidateCheckInputsForAllFlags(CTransaction(invalid_with_csv_tx), SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, true); ValidateCheckInputsForAllFlags(CTransaction(invalid_with_csv_tx), SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, true, m_node.chainman->ActiveChainstate().CoinsTip());
// Make it valid, and check again // Make it valid, and check again
invalid_with_csv_tx.vin[0].scriptSig = CScript() << vchSig << 100; invalid_with_csv_tx.vin[0].scriptSig = CScript() << vchSig << 100;
TxValidationState state; TxValidationState state;
PrecomputedTransactionData txdata; PrecomputedTransactionData txdata;
BOOST_CHECK(CheckInputScripts(CTransaction(invalid_with_csv_tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, true, true, txdata, nullptr)); BOOST_CHECK(CheckInputScripts(CTransaction(invalid_with_csv_tx), state, &m_node.chainman->ActiveChainstate().CoinsTip(), SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, true, true, txdata, nullptr));
} }
// TODO: add tests for remaining script flags // TODO: add tests for remaining script flags
@ -324,11 +324,11 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
UpdateInput(valid_with_witness_tx.vin[0], sigdata); UpdateInput(valid_with_witness_tx.vin[0], sigdata);
// This should be valid under all script flags. // This should be valid under all script flags.
ValidateCheckInputsForAllFlags(CTransaction(valid_with_witness_tx), 0, true); ValidateCheckInputsForAllFlags(CTransaction(valid_with_witness_tx), 0, true, m_node.chainman->ActiveChainstate().CoinsTip());
// Remove the witness, and check that it is now invalid. // Remove the witness, and check that it is now invalid.
valid_with_witness_tx.vin[0].scriptWitness.SetNull(); valid_with_witness_tx.vin[0].scriptWitness.SetNull();
ValidateCheckInputsForAllFlags(CTransaction(valid_with_witness_tx), SCRIPT_VERIFY_WITNESS, true); ValidateCheckInputsForAllFlags(CTransaction(valid_with_witness_tx), SCRIPT_VERIFY_WITNESS, true, m_node.chainman->ActiveChainstate().CoinsTip());
} }
{ {
@ -353,7 +353,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
} }
// This should be valid under all script flags // This should be valid under all script flags
ValidateCheckInputsForAllFlags(CTransaction(tx), 0, true); ValidateCheckInputsForAllFlags(CTransaction(tx), 0, true, m_node.chainman->ActiveChainstate().CoinsTip());
// Check that if the second input is invalid, but the first input is // Check that if the second input is invalid, but the first input is
// valid, the transaction is not cached. // valid, the transaction is not cached.
@ -363,12 +363,12 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
TxValidationState state; TxValidationState state;
PrecomputedTransactionData txdata; PrecomputedTransactionData txdata;
// This transaction is now invalid under segwit, because of the second input. // This transaction is now invalid under segwit, because of the second input.
BOOST_CHECK(!CheckInputScripts(CTransaction(tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, nullptr)); BOOST_CHECK(!CheckInputScripts(CTransaction(tx), state, &m_node.chainman->ActiveChainstate().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, nullptr));
std::vector<CScriptCheck> scriptchecks; std::vector<CScriptCheck> scriptchecks;
// Make sure this transaction was not cached (ie because the first // Make sure this transaction was not cached (ie because the first
// input was valid) // input was valid)
BOOST_CHECK(CheckInputScripts(CTransaction(tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, &scriptchecks)); BOOST_CHECK(CheckInputScripts(CTransaction(tx), state, &m_node.chainman->ActiveChainstate().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, &scriptchecks));
// Should get 2 script checks back -- caching is on a whole-transaction basis. // Should get 2 script checks back -- caching is on a whole-transaction basis.
BOOST_CHECK_EQUAL(scriptchecks.size(), 2U); BOOST_CHECK_EQUAL(scriptchecks.size(), 2U);
} }

View file

@ -74,12 +74,12 @@ CTxIn MineBlock(const NodeContext& node, const CScript& coinbase_scriptPubKey)
std::shared_ptr<CBlock> PrepareBlock(const NodeContext& node, const CScript& coinbase_scriptPubKey) std::shared_ptr<CBlock> PrepareBlock(const NodeContext& node, const CScript& coinbase_scriptPubKey)
{ {
auto block = std::make_shared<CBlock>( auto block = std::make_shared<CBlock>(
BlockAssembler{::ChainstateActive(), *Assert(node.mempool), Params()} BlockAssembler{Assert(node.chainman)->ActiveChainstate(), *Assert(node.mempool), Params()}
.CreateNewBlock(coinbase_scriptPubKey) .CreateNewBlock(coinbase_scriptPubKey)
->block); ->block);
LOCK(cs_main); LOCK(cs_main);
block->nTime = ::ChainActive().Tip()->GetMedianTimePast() + 1; block->nTime = Assert(node.chainman)->ActiveChain().Tip()->GetMedianTimePast() + 1;
block->hashMerkleRoot = BlockMerkleRoot(*block); block->hashMerkleRoot = BlockMerkleRoot(*block);
return block; return block;

View file

@ -146,7 +146,7 @@ ChainTestingSetup::ChainTestingSetup(const std::string& chainName, const std::ve
m_node.fee_estimator = std::make_unique<CBlockPolicyEstimator>(); m_node.fee_estimator = std::make_unique<CBlockPolicyEstimator>();
m_node.mempool = std::make_unique<CTxMemPool>(m_node.fee_estimator.get(), 1); m_node.mempool = std::make_unique<CTxMemPool>(m_node.fee_estimator.get(), 1);
m_node.chainman = &::g_chainman; m_node.chainman = std::make_unique<ChainstateManager>();
// Start script-checking threads. Set g_parallel_script_checks to true so they are used. // Start script-checking threads. Set g_parallel_script_checks to true so they are used.
constexpr int script_check_threads = 2; constexpr int script_check_threads = 2;
@ -168,7 +168,7 @@ ChainTestingSetup::~ChainTestingSetup()
m_node.mempool.reset(); m_node.mempool.reset();
m_node.scheduler.reset(); m_node.scheduler.reset();
m_node.chainman->Reset(); m_node.chainman->Reset();
m_node.chainman = nullptr; m_node.chainman.reset();
pblocktree.reset(); pblocktree.reset();
} }
@ -181,17 +181,17 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector<const
RegisterAllCoreRPCCommands(tableRPC); RegisterAllCoreRPCCommands(tableRPC);
m_node.chainman->InitializeChainstate(*m_node.mempool); m_node.chainman->InitializeChainstate(*m_node.mempool);
::ChainstateActive().InitCoinsDB( m_node.chainman->ActiveChainstate().InitCoinsDB(
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false); /* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
assert(!::ChainstateActive().CanFlushToDisk()); assert(!m_node.chainman->ActiveChainstate().CanFlushToDisk());
::ChainstateActive().InitCoinsCache(1 << 23); m_node.chainman->ActiveChainstate().InitCoinsCache(1 << 23);
assert(::ChainstateActive().CanFlushToDisk()); assert(m_node.chainman->ActiveChainstate().CanFlushToDisk());
if (!::ChainstateActive().LoadGenesisBlock(chainparams)) { if (!m_node.chainman->ActiveChainstate().LoadGenesisBlock(chainparams)) {
throw std::runtime_error("LoadGenesisBlock failed."); throw std::runtime_error("LoadGenesisBlock failed.");
} }
BlockValidationState state; BlockValidationState state;
if (!::ChainstateActive().ActivateBestChain(state, chainparams)) { if (!m_node.chainman->ActiveChainstate().ActivateBestChain(state, chainparams)) {
throw std::runtime_error(strprintf("ActivateBestChain failed. (%s)", state.ToString())); throw std::runtime_error(strprintf("ActivateBestChain failed. (%s)", state.ToString()));
} }
@ -241,7 +241,7 @@ CBlock TestChain100Setup::CreateAndProcessBlock(const std::vector<CMutableTransa
{ {
const CChainParams& chainparams = Params(); const CChainParams& chainparams = Params();
CTxMemPool empty_pool; CTxMemPool empty_pool;
CBlock block = BlockAssembler(::ChainstateActive(), empty_pool, chainparams).CreateNewBlock(scriptPubKey)->block; CBlock block = BlockAssembler(m_node.chainman->ActiveChainstate(), empty_pool, chainparams).CreateNewBlock(scriptPubKey)->block;
Assert(block.vtx.size() == 1); Assert(block.vtx.size() == 1);
for (const CMutableTransaction& tx : txns) { for (const CMutableTransaction& tx : txns) {
@ -300,7 +300,7 @@ CMutableTransaction TestChain100Setup::CreateValidMempoolTransaction(CTransactio
// If submit=true, add transaction to the mempool. // If submit=true, add transaction to the mempool.
if (submit) { if (submit) {
LOCK(cs_main); LOCK(cs_main);
const MempoolAcceptResult result = AcceptToMemoryPool(::ChainstateActive(), *m_node.mempool.get(), MakeTransactionRef(mempool_txn), /* bypass_limits */ false); const MempoolAcceptResult result = AcceptToMemoryPool(m_node.chainman->ActiveChainstate(), *m_node.mempool.get(), MakeTransactionRef(mempool_txn), /* bypass_limits */ false);
assert(result.m_result_type == MempoolAcceptResult::ResultType::VALID); assert(result.m_result_type == MempoolAcceptResult::ResultType::VALID);
} }

View file

@ -84,8 +84,8 @@ std::shared_ptr<CBlock> MinerTestingSetup::Block(const uint256& prev_hash)
std::shared_ptr<CBlock> MinerTestingSetup::FinalizeBlock(std::shared_ptr<CBlock> pblock) std::shared_ptr<CBlock> MinerTestingSetup::FinalizeBlock(std::shared_ptr<CBlock> pblock)
{ {
LOCK(cs_main); // For g_chainman.m_blockman.LookupBlockIndex LOCK(cs_main); // For m_node.chainman->m_blockman.LookupBlockIndex
GenerateCoinbaseCommitment(*pblock, g_chainman.m_blockman.LookupBlockIndex(pblock->hashPrevBlock), Params().GetConsensus()); GenerateCoinbaseCommitment(*pblock, m_node.chainman->m_blockman.LookupBlockIndex(pblock->hashPrevBlock), Params().GetConsensus());
pblock->hashMerkleRoot = BlockMerkleRoot(*pblock); pblock->hashMerkleRoot = BlockMerkleRoot(*pblock);
@ -162,7 +162,7 @@ BOOST_AUTO_TEST_CASE(processnewblock_signals_ordering)
const CBlockIndex* initial_tip = nullptr; const CBlockIndex* initial_tip = nullptr;
{ {
LOCK(cs_main); LOCK(cs_main);
initial_tip = ::ChainActive().Tip(); initial_tip = m_node.chainman->ActiveChain().Tip();
} }
auto sub = std::make_shared<TestSubscriber>(initial_tip->GetBlockHash()); auto sub = std::make_shared<TestSubscriber>(initial_tip->GetBlockHash());
RegisterSharedValidationInterface(sub); RegisterSharedValidationInterface(sub);
@ -198,7 +198,7 @@ BOOST_AUTO_TEST_CASE(processnewblock_signals_ordering)
UnregisterSharedValidationInterface(sub); UnregisterSharedValidationInterface(sub);
LOCK(cs_main); LOCK(cs_main);
BOOST_CHECK_EQUAL(sub->m_expected_tip, ::ChainActive().Tip()->GetBlockHash()); BOOST_CHECK_EQUAL(sub->m_expected_tip, m_node.chainman->ActiveChain().Tip()->GetBlockHash());
} }
/** /**
@ -232,7 +232,7 @@ BOOST_AUTO_TEST_CASE(mempool_locks_reorg)
// Run the test multiple times // Run the test multiple times
for (int test_runs = 3; test_runs > 0; --test_runs) { for (int test_runs = 3; test_runs > 0; --test_runs) {
BOOST_CHECK_EQUAL(last_mined->GetHash(), ::ChainActive().Tip()->GetBlockHash()); BOOST_CHECK_EQUAL(last_mined->GetHash(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
// Later on split from here // Later on split from here
const uint256 split_hash{last_mined->hashPrevBlock}; const uint256 split_hash{last_mined->hashPrevBlock};
@ -273,7 +273,7 @@ BOOST_AUTO_TEST_CASE(mempool_locks_reorg)
{ {
LOCK(cs_main); LOCK(cs_main);
for (const auto& tx : txs) { for (const auto& tx : txs) {
const MempoolAcceptResult result = AcceptToMemoryPool(::ChainstateActive(), *m_node.mempool, tx, false /* bypass_limits */); const MempoolAcceptResult result = AcceptToMemoryPool(m_node.chainman->ActiveChainstate(), *m_node.mempool, tx, false /* bypass_limits */);
BOOST_REQUIRE(result.m_result_type == MempoolAcceptResult::ResultType::VALID); BOOST_REQUIRE(result.m_result_type == MempoolAcceptResult::ResultType::VALID);
} }
} }
@ -306,7 +306,7 @@ BOOST_AUTO_TEST_CASE(mempool_locks_reorg)
} }
LOCK(cs_main); LOCK(cs_main);
// We are done with the reorg, so the tip must have changed // We are done with the reorg, so the tip must have changed
assert(tip_init != ::ChainActive().Tip()->GetBlockHash()); assert(tip_init != m_node.chainman->ActiveChain().Tip()->GetBlockHash());
}}; }};
// Submit the reorg in this thread to invalidate and remove the txs from the tx pool // Submit the reorg in this thread to invalidate and remove the txs from the tx pool
@ -314,7 +314,7 @@ BOOST_AUTO_TEST_CASE(mempool_locks_reorg)
ProcessBlock(b); ProcessBlock(b);
} }
// Check that the reorg was eventually successful // Check that the reorg was eventually successful
BOOST_CHECK_EQUAL(last_mined->GetHash(), ::ChainActive().Tip()->GetBlockHash()); BOOST_CHECK_EQUAL(last_mined->GetHash(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
// We can join the other thread, which returns when the reorg was successful // We can join the other thread, which returns when the reorg was successful
rpc_thread.join(); rpc_thread.join();

View file

@ -513,7 +513,6 @@ void CTxMemPool::removeForReorg(CChainState& active_chainstate, int flags)
for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
const CTransaction& tx = it->GetTx(); const CTransaction& tx = it->GetTx();
LockPoints lp = it->GetLockPoints(); LockPoints lp = it->GetLockPoints();
assert(std::addressof(::ChainstateActive()) == std::addressof(active_chainstate));
bool validLP = TestLockPointValidity(active_chainstate.m_chain, &lp); bool validLP = TestLockPointValidity(active_chainstate.m_chain, &lp);
CCoinsViewMemPool view_mempool(&active_chainstate.CoinsTip(), *this); CCoinsViewMemPool view_mempool(&active_chainstate.CoinsTip(), *this);
if (!CheckFinalTx(active_chainstate.m_chain.Tip(), tx, flags) if (!CheckFinalTx(active_chainstate.m_chain.Tip(), tx, flags)
@ -638,10 +637,8 @@ void CTxMemPool::check(CChainState& active_chainstate) const
uint64_t innerUsage = 0; uint64_t innerUsage = 0;
CCoinsViewCache& active_coins_tip = active_chainstate.CoinsTip(); CCoinsViewCache& active_coins_tip = active_chainstate.CoinsTip();
assert(std::addressof(::ChainstateActive().CoinsTip()) == std::addressof(active_coins_tip)); // TODO: REVIEW-ONLY, REMOVE IN FUTURE COMMIT
CCoinsViewCache mempoolDuplicate(const_cast<CCoinsViewCache*>(&active_coins_tip)); CCoinsViewCache mempoolDuplicate(const_cast<CCoinsViewCache*>(&active_coins_tip));
const int64_t spendheight = active_chainstate.m_chain.Height() + 1; const int64_t spendheight = active_chainstate.m_chain.Height() + 1;
assert(g_chainman.m_blockman.GetSpendHeight(mempoolDuplicate) == spendheight); // TODO: REVIEW-ONLY, REMOVE IN FUTURE COMMIT
std::list<const CTxMemPoolEntry*> waitingOnDependants; std::list<const CTxMemPoolEntry*> waitingOnDependants;
for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {

View file

@ -101,21 +101,6 @@ bool CBlockIndexWorkComparator::operator()(const CBlockIndex *pa, const CBlockIn
return false; return false;
} }
ChainstateManager g_chainman;
CChainState& ChainstateActive()
{
LOCK(::cs_main);
assert(g_chainman.m_active_chainstate);
return *g_chainman.m_active_chainstate;
}
CChain& ChainActive()
{
LOCK(::cs_main);
return ::ChainstateActive().m_chain;
}
/** /**
* Mutex to guard access to validation specific variables, such as reading * Mutex to guard access to validation specific variables, such as reading
* or changing the chainstate. * or changing the chainstate.
@ -161,7 +146,6 @@ void FlushBlockFile(bool fFinalize = false, bool finalize_undo = false);
CBlockIndex* BlockManager::LookupBlockIndex(const uint256& hash) const CBlockIndex* BlockManager::LookupBlockIndex(const uint256& hash) const
{ {
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
assert(std::addressof(g_chainman.BlockIndex()) == std::addressof(m_block_index));
BlockMap::const_iterator it = m_block_index.find(hash); BlockMap::const_iterator it = m_block_index.find(hash);
return it == m_block_index.end() ? nullptr : it->second; return it == m_block_index.end() ? nullptr : it->second;
} }
@ -170,7 +154,6 @@ CBlockIndex* BlockManager::FindForkInGlobalIndex(const CChain& chain, const CBlo
{ {
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
assert(std::addressof(g_chainman.m_blockman) == std::addressof(*this));
// Find the latest block common to locator and chain - we expect that // Find the latest block common to locator and chain - we expect that
// locator.vHave is sorted descending by height. // locator.vHave is sorted descending by height.
for (const uint256& hash : locator.vHave) { for (const uint256& hash : locator.vHave) {
@ -198,7 +181,6 @@ bool CheckFinalTx(const CBlockIndex* active_chain_tip, const CTransaction &tx, i
{ {
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
assert(active_chain_tip); // TODO: Make active_chain_tip a reference assert(active_chain_tip); // TODO: Make active_chain_tip a reference
assert(std::addressof(*::ChainActive().Tip()) == std::addressof(*active_chain_tip));
// By convention a negative value for flags indicates that the // By convention a negative value for flags indicates that the
// current network-enforced consensus rules should be used. In // current network-enforced consensus rules should be used. In
@ -237,7 +219,6 @@ bool TestLockPointValidity(CChain& active_chain, const LockPoints* lp)
if (lp->maxInputBlock) { if (lp->maxInputBlock) {
// Check whether ::ChainActive() is an extension of the block at which the LockPoints // Check whether ::ChainActive() is an extension of the block at which the LockPoints
// calculation was valid. If not LockPoints are no longer valid // calculation was valid. If not LockPoints are no longer valid
assert(std::addressof(::ChainActive()) == std::addressof(active_chain));
if (!active_chain.Contains(lp->maxInputBlock)) { if (!active_chain.Contains(lp->maxInputBlock)) {
return false; return false;
} }
@ -331,7 +312,6 @@ static void LimitMempoolSize(CTxMemPool& pool, CCoinsViewCache& coins_cache, siz
std::vector<COutPoint> vNoSpendsRemaining; std::vector<COutPoint> vNoSpendsRemaining;
pool.TrimToSize(limit, &vNoSpendsRemaining); pool.TrimToSize(limit, &vNoSpendsRemaining);
assert(std::addressof(::ChainstateActive().CoinsTip()) == std::addressof(coins_cache));
for (const COutPoint& removed : vNoSpendsRemaining) for (const COutPoint& removed : vNoSpendsRemaining)
coins_cache.Uncache(removed); coins_cache.Uncache(removed);
} }
@ -339,7 +319,6 @@ static void LimitMempoolSize(CTxMemPool& pool, CCoinsViewCache& coins_cache, siz
static bool IsCurrentForFeeEstimation(CChainState& active_chainstate) EXCLUSIVE_LOCKS_REQUIRED(cs_main) static bool IsCurrentForFeeEstimation(CChainState& active_chainstate) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{ {
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
assert(std::addressof(::ChainstateActive()) == std::addressof(active_chainstate));
if (active_chainstate.IsInitialBlockDownload()) if (active_chainstate.IsInitialBlockDownload())
return false; return false;
if (active_chainstate.m_chain.Tip()->GetBlockTime() < count_seconds(GetTime<std::chrono::seconds>() - MAX_FEE_ESTIMATION_TIP_AGE)) if (active_chainstate.m_chain.Tip()->GetBlockTime() < count_seconds(GetTime<std::chrono::seconds>() - MAX_FEE_ESTIMATION_TIP_AGE))
@ -366,7 +345,6 @@ static void UpdateMempoolForReorg(CChainState& active_chainstate, CTxMemPool& me
{ {
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
AssertLockHeld(mempool.cs); AssertLockHeld(mempool.cs);
assert(std::addressof(::ChainstateActive()) == std::addressof(active_chainstate));
std::vector<uint256> vHashUpdate; std::vector<uint256> vHashUpdate;
// disconnectpool's insertion_order index sorts the entries from // disconnectpool's insertion_order index sorts the entries from
// oldest to newest, but the oldest entry will be the last tx from the // oldest to newest, but the oldest entry will be the last tx from the
@ -433,7 +411,6 @@ static bool CheckInputsFromMempoolAndCache(const CTransaction& tx, TxValidationS
assert(txFrom->vout.size() > txin.prevout.n); assert(txFrom->vout.size() > txin.prevout.n);
assert(txFrom->vout[txin.prevout.n] == coin.out); assert(txFrom->vout[txin.prevout.n] == coin.out);
} else { } else {
assert(std::addressof(::ChainstateActive().CoinsTip()) == std::addressof(coins_tip));
const Coin& coinFromUTXOSet = coins_tip.AccessCoin(txin.prevout); const Coin& coinFromUTXOSet = coins_tip.AccessCoin(txin.prevout);
assert(!coinFromUTXOSet.IsSpent()); assert(!coinFromUTXOSet.IsSpent());
assert(coinFromUTXOSet.out == coin.out); assert(coinFromUTXOSet.out == coin.out);
@ -454,7 +431,6 @@ public:
m_limit_ancestor_size(gArgs.GetArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT)*1000), m_limit_ancestor_size(gArgs.GetArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT)*1000),
m_limit_descendants(gArgs.GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT)), m_limit_descendants(gArgs.GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT)),
m_limit_descendant_size(gArgs.GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT)*1000) { m_limit_descendant_size(gArgs.GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT)*1000) {
assert(std::addressof(::ChainstateActive()) == std::addressof(m_active_chainstate));
} }
// We put the arguments we're handed into a struct, so we can pass them // We put the arguments we're handed into a struct, so we can pass them
@ -607,7 +583,6 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
// Only accept nLockTime-using transactions that can be mined in the next // Only accept nLockTime-using transactions that can be mined in the next
// block; we don't want our mempool filled up with transactions that can't // block; we don't want our mempool filled up with transactions that can't
// be mined yet. // be mined yet.
assert(std::addressof(::ChainActive()) == std::addressof(m_active_chainstate.m_chain));
if (!CheckFinalTx(m_active_chainstate.m_chain.Tip(), tx, STANDARD_LOCKTIME_VERIFY_FLAGS)) if (!CheckFinalTx(m_active_chainstate.m_chain.Tip(), tx, STANDARD_LOCKTIME_VERIFY_FLAGS))
return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, "non-final"); return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, "non-final");
@ -663,7 +638,6 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
LockPoints lp; LockPoints lp;
m_view.SetBackend(m_viewmempool); m_view.SetBackend(m_viewmempool);
assert(std::addressof(::ChainstateActive().CoinsTip()) == std::addressof(m_active_chainstate.CoinsTip()));
const CCoinsViewCache& coins_cache = m_active_chainstate.CoinsTip(); const CCoinsViewCache& coins_cache = m_active_chainstate.CoinsTip();
// do all inputs exist? // do all inputs exist?
for (const CTxIn& txin : tx.vin) { for (const CTxIn& txin : tx.vin) {
@ -701,18 +675,15 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
// be mined yet. // be mined yet.
// Pass in m_view which has all of the relevant inputs cached. Note that, since m_view's // Pass in m_view which has all of the relevant inputs cached. Note that, since m_view's
// backend was removed, it no longer pulls coins from the mempool. // backend was removed, it no longer pulls coins from the mempool.
assert(std::addressof(::ChainstateActive()) == std::addressof(m_active_chainstate));
if (!CheckSequenceLocks(m_active_chainstate.m_chain.Tip(), m_view, tx, STANDARD_LOCKTIME_VERIFY_FLAGS, &lp)) if (!CheckSequenceLocks(m_active_chainstate.m_chain.Tip(), m_view, tx, STANDARD_LOCKTIME_VERIFY_FLAGS, &lp))
return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, "non-BIP68-final"); return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, "non-BIP68-final");
assert(std::addressof(g_chainman.m_blockman) == std::addressof(m_active_chainstate.m_blockman));
if (!Consensus::CheckTxInputs(tx, state, m_view, m_active_chainstate.m_blockman.GetSpendHeight(m_view), ws.m_base_fees)) { if (!Consensus::CheckTxInputs(tx, state, m_view, m_active_chainstate.m_blockman.GetSpendHeight(m_view), ws.m_base_fees)) {
return false; // state filled in by CheckTxInputs return false; // state filled in by CheckTxInputs
} }
// Check for non-standard pay-to-script-hash in inputs // Check for non-standard pay-to-script-hash in inputs
const auto& params = args.m_chainparams.GetConsensus(); const auto& params = args.m_chainparams.GetConsensus();
assert(std::addressof(::ChainActive()) == std::addressof(m_active_chainstate.m_chain));
auto taproot_state = VersionBitsState(m_active_chainstate.m_chain.Tip(), params, Consensus::DEPLOYMENT_TAPROOT, versionbitscache); auto taproot_state = VersionBitsState(m_active_chainstate.m_chain.Tip(), params, Consensus::DEPLOYMENT_TAPROOT, versionbitscache);
if (fRequireStandard && !AreInputsStandard(tx, m_view, taproot_state == ThresholdState::ACTIVE)) { if (fRequireStandard && !AreInputsStandard(tx, m_view, taproot_state == ThresholdState::ACTIVE)) {
return state.Invalid(TxValidationResult::TX_INPUTS_NOT_STANDARD, "bad-txns-nonstandard-inputs"); return state.Invalid(TxValidationResult::TX_INPUTS_NOT_STANDARD, "bad-txns-nonstandard-inputs");
@ -739,7 +710,6 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
} }
} }
assert(std::addressof(::ChainActive()) == std::addressof(m_active_chainstate.m_chain));
entry.reset(new CTxMemPoolEntry(ptx, ws.m_base_fees, nAcceptTime, m_active_chainstate.m_chain.Height(), entry.reset(new CTxMemPoolEntry(ptx, ws.m_base_fees, nAcceptTime, m_active_chainstate.m_chain.Height(),
fSpendsCoinbase, nSigOpsCost, lp)); fSpendsCoinbase, nSigOpsCost, lp));
unsigned int nSize = entry->GetTxSize(); unsigned int nSize = entry->GetTxSize();
@ -992,9 +962,7 @@ bool MemPoolAccept::ConsensusScriptChecks(const ATMPArgs& args, Workspace& ws, P
// There is a similar check in CreateNewBlock() to prevent creating // There is a similar check in CreateNewBlock() to prevent creating
// invalid blocks (using TestBlockValidity), however allowing such // invalid blocks (using TestBlockValidity), however allowing such
// transactions into the mempool can be exploited as a DoS attack. // transactions into the mempool can be exploited as a DoS attack.
assert(std::addressof(::ChainActive()) == std::addressof(m_active_chainstate.m_chain));
unsigned int currentBlockScriptVerifyFlags = GetBlockScriptFlags(m_active_chainstate.m_chain.Tip(), chainparams.GetConsensus()); unsigned int currentBlockScriptVerifyFlags = GetBlockScriptFlags(m_active_chainstate.m_chain.Tip(), chainparams.GetConsensus());
assert(std::addressof(::ChainstateActive().CoinsTip()) == std::addressof(m_active_chainstate.CoinsTip()));
if (!CheckInputsFromMempoolAndCache(tx, state, m_view, m_pool, currentBlockScriptVerifyFlags, txdata, m_active_chainstate.CoinsTip())) { if (!CheckInputsFromMempoolAndCache(tx, state, m_view, m_pool, currentBlockScriptVerifyFlags, txdata, m_active_chainstate.CoinsTip())) {
return error("%s: BUG! PLEASE REPORT THIS! CheckInputScripts failed against latest-block but not STANDARD flags %s, %s", return error("%s: BUG! PLEASE REPORT THIS! CheckInputScripts failed against latest-block but not STANDARD flags %s, %s",
__func__, hash.ToString(), state.ToString()); __func__, hash.ToString(), state.ToString());
@ -1035,7 +1003,6 @@ bool MemPoolAccept::Finalize(const ATMPArgs& args, Workspace& ws)
// - it's not being re-added during a reorg which bypasses typical mempool fee limits // - it's not being re-added during a reorg which bypasses typical mempool fee limits
// - the node is not behind // - the node is not behind
// - the transaction is not dependent on any other transactions in the mempool // - the transaction is not dependent on any other transactions in the mempool
assert(std::addressof(::ChainstateActive()) == std::addressof(m_active_chainstate));
bool validForFeeEstimation = !fReplacementTransaction && !bypass_limits && IsCurrentForFeeEstimation(m_active_chainstate) && m_pool.HasNoInputsOf(tx); bool validForFeeEstimation = !fReplacementTransaction && !bypass_limits && IsCurrentForFeeEstimation(m_active_chainstate) && m_pool.HasNoInputsOf(tx);
// Store transaction in memory // Store transaction in memory
@ -1043,7 +1010,6 @@ bool MemPoolAccept::Finalize(const ATMPArgs& args, Workspace& ws)
// trim mempool and check if tx was trimmed // trim mempool and check if tx was trimmed
if (!bypass_limits) { if (!bypass_limits) {
assert(std::addressof(::ChainstateActive().CoinsTip()) == std::addressof(m_active_chainstate.CoinsTip()));
LimitMempoolSize(m_pool, m_active_chainstate.CoinsTip(), gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, std::chrono::hours{gArgs.GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY)}); LimitMempoolSize(m_pool, m_active_chainstate.CoinsTip(), gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, std::chrono::hours{gArgs.GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY)});
if (!m_pool.exists(hash)) if (!m_pool.exists(hash))
return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "mempool full"); return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "mempool full");
@ -1146,7 +1112,6 @@ static MempoolAcceptResult AcceptToMemoryPoolWithTime(const CChainParams& chainp
MemPoolAccept::ATMPArgs args { chainparams, nAcceptTime, bypass_limits, coins_to_uncache, MemPoolAccept::ATMPArgs args { chainparams, nAcceptTime, bypass_limits, coins_to_uncache,
test_accept, /* m_allow_bip125_replacement */ true }; test_accept, /* m_allow_bip125_replacement */ true };
assert(std::addressof(::ChainstateActive()) == std::addressof(active_chainstate));
const MempoolAcceptResult result = MemPoolAccept(pool, active_chainstate).AcceptSingleTransaction(tx, args); const MempoolAcceptResult result = MemPoolAccept(pool, active_chainstate).AcceptSingleTransaction(tx, args);
if (result.m_result_type != MempoolAcceptResult::ResultType::VALID) { if (result.m_result_type != MempoolAcceptResult::ResultType::VALID) {
// Remove coins that were not present in the coins cache before calling // Remove coins that were not present in the coins cache before calling
@ -1166,7 +1131,6 @@ static MempoolAcceptResult AcceptToMemoryPoolWithTime(const CChainParams& chainp
MempoolAcceptResult AcceptToMemoryPool(CChainState& active_chainstate, CTxMemPool& pool, const CTransactionRef& tx, MempoolAcceptResult AcceptToMemoryPool(CChainState& active_chainstate, CTxMemPool& pool, const CTransactionRef& tx,
bool bypass_limits, bool test_accept) bool bypass_limits, bool test_accept)
{ {
assert(std::addressof(::ChainstateActive()) == std::addressof(active_chainstate));
return AcceptToMemoryPoolWithTime(Params(), pool, active_chainstate, tx, GetTime(), bypass_limits, test_accept); return AcceptToMemoryPoolWithTime(Params(), pool, active_chainstate, tx, GetTime(), bypass_limits, test_accept);
} }
@ -1182,7 +1146,6 @@ PackageMempoolAcceptResult ProcessNewPackage(CChainState& active_chainstate, CTx
const CChainParams& chainparams = Params(); const CChainParams& chainparams = Params();
MemPoolAccept::ATMPArgs args { chainparams, GetTime(), /* bypass_limits */ false, coins_to_uncache, MemPoolAccept::ATMPArgs args { chainparams, GetTime(), /* bypass_limits */ false, coins_to_uncache,
test_accept, /* m_allow_bip125_replacement */ false }; test_accept, /* m_allow_bip125_replacement */ false };
assert(std::addressof(::ChainstateActive()) == std::addressof(active_chainstate));
const PackageMempoolAcceptResult result = MemPoolAccept(pool, active_chainstate).AcceptMultipleTransactions(package, args); const PackageMempoolAcceptResult result = MemPoolAccept(pool, active_chainstate).AcceptMultipleTransactions(package, args);
// Uncache coins pertaining to transactions that were not submitted to the mempool. // Uncache coins pertaining to transactions that were not submitted to the mempool.
@ -1321,7 +1284,6 @@ static void AlertNotify(const std::string& strMessage)
void CChainState::CheckForkWarningConditions() void CChainState::CheckForkWarningConditions()
{ {
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
// Before we get past initial download, we cannot reliably alert about forks // Before we get past initial download, we cannot reliably alert about forks
// (we assume we don't get stuck on a fork before finishing our initial sync) // (we assume we don't get stuck on a fork before finishing our initial sync)
@ -1340,7 +1302,6 @@ void CChainState::CheckForkWarningConditions()
// Called both upon regular invalid block discovery *and* InvalidateBlock // Called both upon regular invalid block discovery *and* InvalidateBlock
void CChainState::InvalidChainFound(CBlockIndex* pindexNew) void CChainState::InvalidChainFound(CBlockIndex* pindexNew)
{ {
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
if (!pindexBestInvalid || pindexNew->nChainWork > pindexBestInvalid->nChainWork) if (!pindexBestInvalid || pindexNew->nChainWork > pindexBestInvalid->nChainWork)
pindexBestInvalid = pindexNew; pindexBestInvalid = pindexNew;
if (pindexBestHeader != nullptr && pindexBestHeader->GetAncestor(pindexNew->nHeight) == pindexNew) { if (pindexBestHeader != nullptr && pindexBestHeader->GetAncestor(pindexNew->nHeight) == pindexNew) {
@ -1401,7 +1362,6 @@ bool CScriptCheck::operator()() {
int BlockManager::GetSpendHeight(const CCoinsViewCache& inputs) int BlockManager::GetSpendHeight(const CCoinsViewCache& inputs)
{ {
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
assert(std::addressof(g_chainman.m_blockman) == std::addressof(*this));
CBlockIndex* pindexPrev = LookupBlockIndex(inputs.GetBestBlock()); CBlockIndex* pindexPrev = LookupBlockIndex(inputs.GetBestBlock());
return pindexPrev->nHeight + 1; return pindexPrev->nHeight + 1;
} }
@ -2285,7 +2245,6 @@ static void UpdateTip(CTxMemPool& mempool, const CBlockIndex* pindexNew, const C
} }
bilingual_str warning_messages; bilingual_str warning_messages;
assert(std::addressof(::ChainstateActive()) == std::addressof(active_chainstate));
if (!active_chainstate.IsInitialBlockDownload()) { if (!active_chainstate.IsInitialBlockDownload()) {
const CBlockIndex* pindex = pindexNew; const CBlockIndex* pindex = pindexNew;
for (int bit = 0; bit < VERSIONBITS_NUM_BITS; bit++) { for (int bit = 0; bit < VERSIONBITS_NUM_BITS; bit++) {
@ -2301,7 +2260,6 @@ static void UpdateTip(CTxMemPool& mempool, const CBlockIndex* pindexNew, const C
} }
} }
} }
assert(std::addressof(::ChainstateActive()) == std::addressof(active_chainstate));
LogPrintf("%s: new best=%s height=%d version=0x%08x log2_work=%f tx=%lu date='%s' progress=%f cache=%.1fMiB(%utxo)%s\n", __func__, LogPrintf("%s: new best=%s height=%d version=0x%08x log2_work=%f tx=%lu date='%s' progress=%f cache=%.1fMiB(%utxo)%s\n", __func__,
pindexNew->GetBlockHash().ToString(), pindexNew->nHeight, pindexNew->nVersion, pindexNew->GetBlockHash().ToString(), pindexNew->nHeight, pindexNew->nVersion,
log(pindexNew->nChainWork.getdouble())/log(2.0), (unsigned long)pindexNew->nChainTx, log(pindexNew->nChainWork.getdouble())/log(2.0), (unsigned long)pindexNew->nChainTx,
@ -2561,7 +2519,6 @@ bool CChainState::ActivateBestChainStep(BlockValidationState& state, const CChai
{ {
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
AssertLockHeld(m_mempool.cs); AssertLockHeld(m_mempool.cs);
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
const CBlockIndex* pindexOldTip = m_chain.Tip(); const CBlockIndex* pindexOldTip = m_chain.Tip();
const CBlockIndex* pindexFork = m_chain.FindFork(pindexMostWork); const CBlockIndex* pindexFork = m_chain.FindFork(pindexMostWork);
@ -2661,7 +2618,6 @@ static bool NotifyHeaderTip(CChainState& chainstate) LOCKS_EXCLUDED(cs_main) {
if (pindexHeader != pindexHeaderOld) { if (pindexHeader != pindexHeaderOld) {
fNotify = true; fNotify = true;
assert(std::addressof(::ChainstateActive()) == std::addressof(chainstate));
fInitialBlockDownload = chainstate.IsInitialBlockDownload(); fInitialBlockDownload = chainstate.IsInitialBlockDownload();
pindexHeaderOld = pindexHeader; pindexHeaderOld = pindexHeader;
} }
@ -2872,7 +2828,6 @@ bool CChainState::InvalidateBlock(BlockValidationState& state, const CChainParam
// transactions back to the mempool if disconnecting was successful, // transactions back to the mempool if disconnecting was successful,
// and we're not doing a very deep invalidation (in which case // and we're not doing a very deep invalidation (in which case
// keeping the mempool up to date is probably futile anyway). // keeping the mempool up to date is probably futile anyway).
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
UpdateMempoolForReorg(*this, m_mempool, disconnectpool, /* fAddToMempool = */ (++disconnected <= 10) && ret); UpdateMempoolForReorg(*this, m_mempool, disconnectpool, /* fAddToMempool = */ (++disconnected <= 10) && ret);
if (!ret) return false; if (!ret) return false;
assert(invalid_walk_tip->pprev == m_chain.Tip()); assert(invalid_walk_tip->pprev == m_chain.Tip());
@ -3203,7 +3158,6 @@ CBlockIndex* BlockManager::GetLastCheckpoint(const CCheckpointData& data)
for (const MapCheckpoints::value_type& i : reverse_iterate(checkpoints)) for (const MapCheckpoints::value_type& i : reverse_iterate(checkpoints))
{ {
const uint256& hash = i.second; const uint256& hash = i.second;
assert(std::addressof(g_chainman.m_blockman) == std::addressof(*this));
CBlockIndex* pindex = LookupBlockIndex(hash); CBlockIndex* pindex = LookupBlockIndex(hash);
if (pindex) { if (pindex) {
return pindex; return pindex;
@ -3236,7 +3190,6 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidatio
// Don't accept any forks from the main chain prior to last checkpoint. // Don't accept any forks from the main chain prior to last checkpoint.
// GetLastCheckpoint finds the last checkpoint in MapCheckpoints that's in our // GetLastCheckpoint finds the last checkpoint in MapCheckpoints that's in our
// BlockIndex(). // BlockIndex().
assert(std::addressof(g_chainman.m_blockman) == std::addressof(blockman));
CBlockIndex* pcheckpoint = blockman.GetLastCheckpoint(params.Checkpoints()); CBlockIndex* pcheckpoint = blockman.GetLastCheckpoint(params.Checkpoints());
if (pcheckpoint && nHeight < pcheckpoint->nHeight) { if (pcheckpoint && nHeight < pcheckpoint->nHeight) {
LogPrintf("ERROR: %s: forked chain older than last checkpoint (height %d)\n", __func__, nHeight); LogPrintf("ERROR: %s: forked chain older than last checkpoint (height %d)\n", __func__, nHeight);
@ -3440,7 +3393,6 @@ bool BlockManager::AcceptBlockHeader(const CBlockHeader& block, BlockValidationS
// Exposed wrapper for AcceptBlockHeader // Exposed wrapper for AcceptBlockHeader
bool ChainstateManager::ProcessNewBlockHeaders(const std::vector<CBlockHeader>& headers, BlockValidationState& state, const CChainParams& chainparams, const CBlockIndex** ppindex) bool ChainstateManager::ProcessNewBlockHeaders(const std::vector<CBlockHeader>& headers, BlockValidationState& state, const CChainParams& chainparams, const CBlockIndex** ppindex)
{ {
assert(std::addressof(::ChainstateActive()) == std::addressof(ActiveChainstate()));
AssertLockNotHeld(cs_main); AssertLockNotHeld(cs_main);
{ {
LOCK(cs_main); LOCK(cs_main);
@ -3531,7 +3483,6 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, Block
// Write block to history file // Write block to history file
if (fNewBlock) *fNewBlock = true; if (fNewBlock) *fNewBlock = true;
assert(std::addressof(::ChainActive()) == std::addressof(m_chain));
try { try {
FlatFilePos blockPos = SaveBlockToDisk(block, pindex->nHeight, m_chain, chainparams, dbp); FlatFilePos blockPos = SaveBlockToDisk(block, pindex->nHeight, m_chain, chainparams, dbp);
if (blockPos.IsNull()) { if (blockPos.IsNull()) {
@ -3553,7 +3504,6 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, Block
bool ChainstateManager::ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<const CBlock>& block, bool force_processing, bool* new_block) bool ChainstateManager::ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<const CBlock>& block, bool force_processing, bool* new_block)
{ {
AssertLockNotHeld(cs_main); AssertLockNotHeld(cs_main);
assert(std::addressof(::ChainstateActive()) == std::addressof(ActiveChainstate()));
{ {
CBlockIndex *pindex = nullptr; CBlockIndex *pindex = nullptr;
@ -3598,7 +3548,6 @@ bool TestBlockValidity(BlockValidationState& state,
bool fCheckMerkleRoot) bool fCheckMerkleRoot)
{ {
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
assert(std::addressof(::ChainstateActive()) == std::addressof(chainstate));
assert(pindexPrev && pindexPrev == chainstate.m_chain.Tip()); assert(pindexPrev && pindexPrev == chainstate.m_chain.Tip());
CCoinsViewCache viewNew(&chainstate.CoinsTip()); CCoinsViewCache viewNew(&chainstate.CoinsTip());
uint256 block_hash(block.GetHash()); uint256 block_hash(block.GetHash());
@ -3608,7 +3557,6 @@ bool TestBlockValidity(BlockValidationState& state,
indexDummy.phashBlock = &block_hash; indexDummy.phashBlock = &block_hash;
// NOTE: CheckBlockHeader is called by CheckBlock // NOTE: CheckBlockHeader is called by CheckBlock
assert(std::addressof(g_chainman.m_blockman) == std::addressof(chainstate.m_blockman));
if (!ContextualCheckBlockHeader(block, state, chainstate.m_blockman, chainparams, pindexPrev, GetAdjustedTime())) if (!ContextualCheckBlockHeader(block, state, chainstate.m_blockman, chainparams, pindexPrev, GetAdjustedTime()))
return error("%s: Consensus::ContextualCheckBlockHeader: %s", __func__, state.ToString()); return error("%s: Consensus::ContextualCheckBlockHeader: %s", __func__, state.ToString());
if (!CheckBlock(block, state, chainparams.GetConsensus(), fCheckPOW, fCheckMerkleRoot)) if (!CheckBlock(block, state, chainparams.GetConsensus(), fCheckPOW, fCheckMerkleRoot))
@ -3688,7 +3636,6 @@ void PruneBlockFilesManual(CChainState& active_chainstate, int nManualPruneHeigh
{ {
BlockValidationState state; BlockValidationState state;
const CChainParams& chainparams = Params(); const CChainParams& chainparams = Params();
assert(std::addressof(::ChainstateActive()) == std::addressof(active_chainstate));
if (!active_chainstate.FlushStateToDisk( if (!active_chainstate.FlushStateToDisk(
chainparams, state, FlushStateMode::NONE, nManualPruneHeight)) { chainparams, state, FlushStateMode::NONE, nManualPruneHeight)) {
LogPrintf("%s: failed to flush state (%s)\n", __func__, state.ToString()); LogPrintf("%s: failed to flush state (%s)\n", __func__, state.ToString());
@ -3842,7 +3789,6 @@ void BlockManager::Unload() {
bool CChainState::LoadBlockIndexDB(const CChainParams& chainparams) bool CChainState::LoadBlockIndexDB(const CChainParams& chainparams)
{ {
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
if (!m_blockman.LoadBlockIndex( if (!m_blockman.LoadBlockIndex(
chainparams.GetConsensus(), *pblocktree, chainparams.GetConsensus(), *pblocktree,
setBlockIndexCandidates)) { setBlockIndexCandidates)) {
@ -3899,7 +3845,6 @@ bool CChainState::LoadBlockIndexDB(const CChainParams& chainparams)
void CChainState::LoadMempool(const ArgsManager& args) void CChainState::LoadMempool(const ArgsManager& args)
{ {
if (args.GetArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) { if (args.GetArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) {
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
::LoadMempool(m_mempool, *this); ::LoadMempool(m_mempool, *this);
} }
m_mempool.SetIsLoaded(!ShutdownRequested()); m_mempool.SetIsLoaded(!ShutdownRequested());
@ -3951,7 +3896,6 @@ bool CVerifyDB::VerifyDB(
{ {
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
assert(std::addressof(::ChainstateActive()) == std::addressof(chainstate));
if (chainstate.m_chain.Tip() == nullptr || chainstate.m_chain.Tip()->pprev == nullptr) if (chainstate.m_chain.Tip() == nullptr || chainstate.m_chain.Tip()->pprev == nullptr)
return true; return true;
@ -4220,7 +4164,6 @@ bool CChainState::LoadGenesisBlock(const CChainParams& chainparams)
if (m_blockman.m_block_index.count(chainparams.GenesisBlock().GetHash())) if (m_blockman.m_block_index.count(chainparams.GenesisBlock().GetHash()))
return true; return true;
assert(std::addressof(::ChainActive()) == std::addressof(m_chain));
try { try {
const CBlock& block = chainparams.GenesisBlock(); const CBlock& block = chainparams.GenesisBlock();
FlatFilePos blockPos = SaveBlockToDisk(block, 0, m_chain, chainparams, nullptr); FlatFilePos blockPos = SaveBlockToDisk(block, 0, m_chain, chainparams, nullptr);
@ -4284,7 +4227,6 @@ void CChainState::LoadExternalBlockFile(const CChainParams& chainparams, FILE* f
{ {
LOCK(cs_main); LOCK(cs_main);
// detect out of order blocks, and store them for later // detect out of order blocks, and store them for later
assert(std::addressof(g_chainman.m_blockman) == std::addressof(m_blockman));
if (hash != chainparams.GetConsensus().hashGenesisBlock && !m_blockman.LookupBlockIndex(block.hashPrevBlock)) { if (hash != chainparams.GetConsensus().hashGenesisBlock && !m_blockman.LookupBlockIndex(block.hashPrevBlock)) {
LogPrint(BCLog::REINDEX, "%s: Out of order block %s, parent %s not known\n", __func__, hash.ToString(), LogPrint(BCLog::REINDEX, "%s: Out of order block %s, parent %s not known\n", __func__, hash.ToString(),
block.hashPrevBlock.ToString()); block.hashPrevBlock.ToString());
@ -4294,11 +4236,9 @@ void CChainState::LoadExternalBlockFile(const CChainParams& chainparams, FILE* f
} }
// process in case the block isn't known yet // process in case the block isn't known yet
assert(std::addressof(g_chainman.m_blockman) == std::addressof(m_blockman));
CBlockIndex* pindex = m_blockman.LookupBlockIndex(hash); CBlockIndex* pindex = m_blockman.LookupBlockIndex(hash);
if (!pindex || (pindex->nStatus & BLOCK_HAVE_DATA) == 0) { if (!pindex || (pindex->nStatus & BLOCK_HAVE_DATA) == 0) {
BlockValidationState state; BlockValidationState state;
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
if (AcceptBlock(pblock, state, chainparams, nullptr, true, dbp, nullptr)) { if (AcceptBlock(pblock, state, chainparams, nullptr, true, dbp, nullptr)) {
nLoaded++; nLoaded++;
} }
@ -4313,13 +4253,11 @@ void CChainState::LoadExternalBlockFile(const CChainParams& chainparams, FILE* f
// Activate the genesis block so normal node progress can continue // Activate the genesis block so normal node progress can continue
if (hash == chainparams.GetConsensus().hashGenesisBlock) { if (hash == chainparams.GetConsensus().hashGenesisBlock) {
BlockValidationState state; BlockValidationState state;
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
if (!ActivateBestChain(state, chainparams, nullptr)) { if (!ActivateBestChain(state, chainparams, nullptr)) {
break; break;
} }
} }
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
NotifyHeaderTip(*this); NotifyHeaderTip(*this);
// Recursively process earlier encountered successors of this block // Recursively process earlier encountered successors of this block
@ -4338,7 +4276,6 @@ void CChainState::LoadExternalBlockFile(const CChainParams& chainparams, FILE* f
head.ToString()); head.ToString());
LOCK(cs_main); LOCK(cs_main);
BlockValidationState dummy; BlockValidationState dummy;
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
if (AcceptBlock(pblockrecursive, dummy, chainparams, nullptr, true, &it->second, nullptr)) if (AcceptBlock(pblockrecursive, dummy, chainparams, nullptr, true, &it->second, nullptr))
{ {
nLoaded++; nLoaded++;
@ -4347,7 +4284,6 @@ void CChainState::LoadExternalBlockFile(const CChainParams& chainparams, FILE* f
} }
range.first++; range.first++;
mapBlocksUnknownParent.erase(it); mapBlocksUnknownParent.erase(it);
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
NotifyHeaderTip(*this); NotifyHeaderTip(*this);
} }
} }
@ -4628,7 +4564,6 @@ bool LoadMempool(CTxMemPool& pool, CChainState& active_chainstate, FopenFn mocka
} }
if (nTime > nNow - nExpiryTimeout) { if (nTime > nNow - nExpiryTimeout) {
LOCK(cs_main); LOCK(cs_main);
assert(std::addressof(::ChainstateActive()) == std::addressof(active_chainstate));
if (AcceptToMemoryPoolWithTime(chainparams, pool, active_chainstate, tx, nTime, false /* bypass_limits */, if (AcceptToMemoryPoolWithTime(chainparams, pool, active_chainstate, tx, nTime, false /* bypass_limits */,
false /* test_accept */).m_result_type == MempoolAcceptResult::ResultType::VALID) { false /* test_accept */).m_result_type == MempoolAcceptResult::ResultType::VALID) {
++count; ++count;

View file

@ -891,10 +891,6 @@ private:
CAutoFile& coins_file, CAutoFile& coins_file,
const SnapshotMetadata& metadata); const SnapshotMetadata& metadata);
// For access to m_active_chainstate.
friend CChainState& ChainstateActive();
friend CChain& ChainActive();
public: public:
std::thread m_load_block; std::thread m_load_block;
//! A single BlockManager instance is shared across each constructed //! A single BlockManager instance is shared across each constructed
@ -1017,17 +1013,14 @@ public:
//! Check to see if caches are out of balance and if so, call //! Check to see if caches are out of balance and if so, call
//! ResizeCoinsCaches() as needed. //! ResizeCoinsCaches() as needed.
void MaybeRebalanceCaches() EXCLUSIVE_LOCKS_REQUIRED(::cs_main); void MaybeRebalanceCaches() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
~ChainstateManager() {
LOCK(::cs_main);
UnloadBlockIndex(/* mempool */ nullptr, *this);
Reset();
}
}; };
/** DEPRECATED! Please use node.chainman instead. May only be used in validation.cpp internally */
extern ChainstateManager g_chainman GUARDED_BY(::cs_main);
/** Please prefer the identical ChainstateManager::ActiveChainstate */
CChainState& ChainstateActive();
/** Please prefer the identical ChainstateManager::ActiveChain */
CChain& ChainActive();
/** Global variable that points to the active block tree (protected by cs_main) */ /** Global variable that points to the active block tree (protected by cs_main) */
extern std::unique_ptr<CBlockTreeDB> pblocktree; extern std::unique_ptr<CBlockTreeDB> pblocktree;

View file

@ -83,17 +83,17 @@ 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)
{ {
// 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 = m_node.chainman->ActiveChain().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 = m_node.chainman->ActiveChain().Tip();
// Verify ScanForWalletTransactions fails to read an unknown start block. // Verify ScanForWalletTransactions fails to read an unknown start block.
{ {
CWallet wallet(m_node.chain.get(), "", CreateDummyWalletDatabase()); CWallet wallet(m_node.chain.get(), "", CreateDummyWalletDatabase());
{ {
LOCK(wallet.cs_wallet); LOCK(wallet.cs_wallet);
wallet.SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash()); wallet.SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
} }
AddKey(wallet, coinbaseKey); AddKey(wallet, coinbaseKey);
WalletRescanReserver reserver(wallet); WalletRescanReserver reserver(wallet);
@ -112,7 +112,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
CWallet wallet(m_node.chain.get(), "", CreateDummyWalletDatabase()); CWallet wallet(m_node.chain.get(), "", CreateDummyWalletDatabase());
{ {
LOCK(wallet.cs_wallet); LOCK(wallet.cs_wallet);
wallet.SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash()); wallet.SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
} }
AddKey(wallet, coinbaseKey); AddKey(wallet, coinbaseKey);
WalletRescanReserver reserver(wallet); WalletRescanReserver reserver(wallet);
@ -138,7 +138,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
CWallet wallet(m_node.chain.get(), "", CreateDummyWalletDatabase()); CWallet wallet(m_node.chain.get(), "", CreateDummyWalletDatabase());
{ {
LOCK(wallet.cs_wallet); LOCK(wallet.cs_wallet);
wallet.SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash()); wallet.SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
} }
AddKey(wallet, coinbaseKey); AddKey(wallet, coinbaseKey);
WalletRescanReserver reserver(wallet); WalletRescanReserver reserver(wallet);
@ -163,7 +163,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
CWallet wallet(m_node.chain.get(), "", CreateDummyWalletDatabase()); CWallet wallet(m_node.chain.get(), "", CreateDummyWalletDatabase());
{ {
LOCK(wallet.cs_wallet); LOCK(wallet.cs_wallet);
wallet.SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash()); wallet.SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
} }
AddKey(wallet, coinbaseKey); AddKey(wallet, coinbaseKey);
WalletRescanReserver reserver(wallet); WalletRescanReserver reserver(wallet);
@ -180,10 +180,10 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
BOOST_FIXTURE_TEST_CASE(importmulti_rescan, TestChain100Setup) BOOST_FIXTURE_TEST_CASE(importmulti_rescan, TestChain100Setup)
{ {
// 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 = m_node.chainman->ActiveChain().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 = m_node.chainman->ActiveChain().Tip();
// Prune the older block file. // Prune the older block file.
{ {
@ -242,7 +242,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
{ {
// 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 = m_node.chainman->ActiveChain().Tip()->GetBlockTimeMax() + 5;
SetMockTime(BLOCK_TIME); SetMockTime(BLOCK_TIME);
m_coinbase_txns.emplace_back(CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]); m_coinbase_txns.emplace_back(CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
m_coinbase_txns.emplace_back(CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]); m_coinbase_txns.emplace_back(CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
@ -265,7 +265,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
spk_man->AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey()); spk_man->AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey());
AddWallet(wallet); AddWallet(wallet);
wallet->SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash()); wallet->SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
} }
JSONRPCRequest request; JSONRPCRequest request;
request.params.setArray(); request.params.setArray();
@ -286,7 +286,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
request.params.setArray(); request.params.setArray();
request.params.push_back(backup_file); request.params.push_back(backup_file);
AddWallet(wallet); AddWallet(wallet);
wallet->SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash()); wallet->SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
::importwallet().HandleRequest(request); ::importwallet().HandleRequest(request);
RemoveWallet(wallet, std::nullopt); RemoveWallet(wallet, std::nullopt);
@ -313,9 +313,9 @@ BOOST_FIXTURE_TEST_CASE(coin_mark_dirty_immature_credit, TestChain100Setup)
CWalletTx wtx(&wallet, m_coinbase_txns.back()); CWalletTx wtx(&wallet, m_coinbase_txns.back());
LOCK2(wallet.cs_wallet, spk_man->cs_KeyStore); LOCK2(wallet.cs_wallet, spk_man->cs_KeyStore);
wallet.SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash()); wallet.SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
CWalletTx::Confirmation confirm(CWalletTx::Status::CONFIRMED, ::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash(), 0); CWalletTx::Confirmation confirm(CWalletTx::Status::CONFIRMED, m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash(), 0);
wtx.m_confirm = confirm; wtx.m_confirm = confirm;
// Call GetImmatureCredit() once before adding the key to the wallet to // Call GetImmatureCredit() once before adding the key to the wallet to
@ -483,16 +483,16 @@ public:
wallet = std::make_unique<CWallet>(m_node.chain.get(), "", CreateMockWalletDatabase()); wallet = std::make_unique<CWallet>(m_node.chain.get(), "", CreateMockWalletDatabase());
{ {
LOCK2(wallet->cs_wallet, ::cs_main); LOCK2(wallet->cs_wallet, ::cs_main);
wallet->SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash()); wallet->SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
} }
wallet->LoadWallet(); wallet->LoadWallet();
AddKey(*wallet, coinbaseKey); AddKey(*wallet, coinbaseKey);
WalletRescanReserver reserver(*wallet); WalletRescanReserver reserver(*wallet);
reserver.reserve(); reserver.reserve();
CWallet::ScanResult result = wallet->ScanForWalletTransactions(::ChainActive().Genesis()->GetBlockHash(), 0 /* start_height */, {} /* max_height */, reserver, false /* update */); CWallet::ScanResult result = wallet->ScanForWalletTransactions(m_node.chainman->ActiveChain().Genesis()->GetBlockHash(), 0 /* start_height */, {} /* max_height */, reserver, false /* update */);
BOOST_CHECK_EQUAL(result.status, CWallet::ScanResult::SUCCESS); BOOST_CHECK_EQUAL(result.status, CWallet::ScanResult::SUCCESS);
BOOST_CHECK_EQUAL(result.last_scanned_block, ::ChainActive().Tip()->GetBlockHash()); BOOST_CHECK_EQUAL(result.last_scanned_block, m_node.chainman->ActiveChain().Tip()->GetBlockHash());
BOOST_CHECK_EQUAL(*result.last_scanned_height, ::ChainActive().Height()); BOOST_CHECK_EQUAL(*result.last_scanned_height, m_node.chainman->ActiveChain().Height());
BOOST_CHECK(result.last_failed_block.IsNull()); BOOST_CHECK(result.last_failed_block.IsNull());
} }
@ -521,10 +521,10 @@ public:
CreateAndProcessBlock({CMutableTransaction(blocktx)}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())); CreateAndProcessBlock({CMutableTransaction(blocktx)}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
LOCK(wallet->cs_wallet); LOCK(wallet->cs_wallet);
wallet->SetLastBlockProcessed(wallet->GetLastBlockHeight() + 1, ::ChainActive().Tip()->GetBlockHash()); wallet->SetLastBlockProcessed(wallet->GetLastBlockHeight() + 1, m_node.chainman->ActiveChain().Tip()->GetBlockHash());
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());
CWalletTx::Confirmation confirm(CWalletTx::Status::CONFIRMED, ::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash(), 1); CWalletTx::Confirmation confirm(CWalletTx::Status::CONFIRMED, m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash(), 1);
it->second.m_confirm = confirm; it->second.m_confirm = confirm;
return it->second; return it->second;
} }