mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-05 10:17:30 -05:00
![fanquake](/assets/img/avatar_default.png)
7878f97bf1
indexes, refactor: Remove CChainState use in index CommitInternal method (Ryan Ofsky)ee3a079fab
indexes, refactor: Remove CBlockIndex* uses in index Rewind methods (Ryan Ofsky)dc971be083
indexes, refactor: Remove CBlockIndex* uses in index WriteBlock methods (Ryan Ofsky)bef4e405f3
indexes, refactor: Remove CBlockIndex* uses in index Init methods (Ryan Ofsky)addb4f2af1
indexes, refactor: Remove CBlockIndex* uses in coinstatsindex LookUpOne function (Ryan Ofsky)33b4d48cfc
indexes, refactor: Pass Chain interface instead of CChainState class to indexes (Ryan Ofsky)a0b5b4ae5a
interfaces, refactor: Add more block information to block connected notifications (Ryan Ofsky) Pull request description: Start transitioning index code away from using internal node types like `CBlockIndex` and `CChain` so index code is less coupled to node code and index code will later be able to stop locking cs_main and sync without having to deal with validationinterface race conditions, and so new indexes are easier to write and can run as plugins or separate processes. This PR contains the first 7 commits from https://github.com/bitcoin/bitcoin/pull/24230#issuecomment-1165625977 which have been split off for easier review. Previous review comments can be found in #24230 ACKs for top commit: MarcoFalke: ACK7878f97bf1
though did not review the last commit 🤼 mzumsande: Code Review ACK7878f97bf1
Tree-SHA512: f84ac2eb6dca2c305566ddeb35ea14d0b71c00860c0fd752bbcf1a0188be833d8c2a6ac9d3ef6ab5b46fbd02d7a24cbb8f60cf12464cb8ba208e22287f709989
124 lines
4.4 KiB
C++
124 lines
4.4 KiB
C++
// Copyright (c) 2020-2021 The Bitcoin Core developers
|
|
// Distributed under the MIT software license, see the accompanying
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
#include <chainparams.h>
|
|
#include <index/coinstatsindex.h>
|
|
#include <interfaces/chain.h>
|
|
#include <test/util/setup_common.h>
|
|
#include <test/util/validation.h>
|
|
#include <util/time.h>
|
|
#include <validation.h>
|
|
|
|
#include <boost/test/unit_test.hpp>
|
|
|
|
#include <chrono>
|
|
|
|
BOOST_AUTO_TEST_SUITE(coinstatsindex_tests)
|
|
|
|
static void IndexWaitSynced(BaseIndex& index)
|
|
{
|
|
// Allow the CoinStatsIndex to catch up with the block index that is syncing
|
|
// in a background thread.
|
|
const auto timeout = GetTime<std::chrono::seconds>() + 120s;
|
|
while (!index.BlockUntilSyncedToCurrentChain()) {
|
|
BOOST_REQUIRE(timeout > GetTime<std::chrono::milliseconds>());
|
|
UninterruptibleSleep(100ms);
|
|
}
|
|
}
|
|
|
|
BOOST_FIXTURE_TEST_CASE(coinstatsindex_initial_sync, TestChain100Setup)
|
|
{
|
|
CoinStatsIndex coin_stats_index{interfaces::MakeChain(m_node), 1 << 20, true};
|
|
|
|
const CBlockIndex* block_index;
|
|
{
|
|
LOCK(cs_main);
|
|
block_index = m_node.chainman->ActiveChain().Tip();
|
|
}
|
|
|
|
// CoinStatsIndex should not be found before it is started.
|
|
BOOST_CHECK(!coin_stats_index.LookUpStats(block_index));
|
|
|
|
// BlockUntilSyncedToCurrentChain should return false before CoinStatsIndex
|
|
// is started.
|
|
BOOST_CHECK(!coin_stats_index.BlockUntilSyncedToCurrentChain());
|
|
|
|
BOOST_REQUIRE(coin_stats_index.Start());
|
|
|
|
IndexWaitSynced(coin_stats_index);
|
|
|
|
// Check that CoinStatsIndex works for genesis block.
|
|
const CBlockIndex* genesis_block_index;
|
|
{
|
|
LOCK(cs_main);
|
|
genesis_block_index = m_node.chainman->ActiveChain().Genesis();
|
|
}
|
|
BOOST_CHECK(coin_stats_index.LookUpStats(genesis_block_index));
|
|
|
|
// Check that CoinStatsIndex updates with new blocks.
|
|
BOOST_CHECK(coin_stats_index.LookUpStats(block_index));
|
|
|
|
const CScript script_pub_key{CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG};
|
|
std::vector<CMutableTransaction> noTxns;
|
|
CreateAndProcessBlock(noTxns, script_pub_key);
|
|
|
|
// Let the CoinStatsIndex to catch up again.
|
|
BOOST_CHECK(coin_stats_index.BlockUntilSyncedToCurrentChain());
|
|
|
|
const CBlockIndex* new_block_index;
|
|
{
|
|
LOCK(cs_main);
|
|
new_block_index = m_node.chainman->ActiveChain().Tip();
|
|
}
|
|
BOOST_CHECK(coin_stats_index.LookUpStats(new_block_index));
|
|
|
|
BOOST_CHECK(block_index != new_block_index);
|
|
|
|
// Shutdown sequence (c.f. Shutdown() in init.cpp)
|
|
coin_stats_index.Stop();
|
|
|
|
// Rest of shutdown sequence and destructors happen in ~TestingSetup()
|
|
}
|
|
|
|
// Test shutdown between BlockConnected and ChainStateFlushed notifications,
|
|
// make sure index is not corrupted and is able to reload.
|
|
BOOST_FIXTURE_TEST_CASE(coinstatsindex_unclean_shutdown, TestChain100Setup)
|
|
{
|
|
CChainState& chainstate = Assert(m_node.chainman)->ActiveChainstate();
|
|
const CChainParams& params = Params();
|
|
{
|
|
CoinStatsIndex index{interfaces::MakeChain(m_node), 1 << 20};
|
|
BOOST_REQUIRE(index.Start());
|
|
IndexWaitSynced(index);
|
|
std::shared_ptr<const CBlock> new_block;
|
|
CBlockIndex* new_block_index = nullptr;
|
|
{
|
|
const CScript script_pub_key{CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG};
|
|
const CBlock block = this->CreateBlock({}, script_pub_key, chainstate);
|
|
|
|
new_block = std::make_shared<CBlock>(block);
|
|
|
|
LOCK(cs_main);
|
|
BlockValidationState state;
|
|
BOOST_CHECK(CheckBlock(block, state, params.GetConsensus()));
|
|
BOOST_CHECK(chainstate.AcceptBlock(new_block, state, &new_block_index, true, nullptr, nullptr));
|
|
CCoinsViewCache view(&chainstate.CoinsTip());
|
|
BOOST_CHECK(chainstate.ConnectBlock(block, state, new_block_index, view));
|
|
}
|
|
// Send block connected notification, then stop the index without
|
|
// sending a chainstate flushed notification. Prior to #24138, this
|
|
// would cause the index to be corrupted and fail to reload.
|
|
ValidationInterfaceTest::BlockConnected(index, new_block, new_block_index);
|
|
index.Stop();
|
|
}
|
|
|
|
{
|
|
CoinStatsIndex index{interfaces::MakeChain(m_node), 1 << 20};
|
|
// Make sure the index can be loaded.
|
|
BOOST_REQUIRE(index.Start());
|
|
index.Stop();
|
|
}
|
|
}
|
|
|
|
BOOST_AUTO_TEST_SUITE_END()
|