// Copyright (c) 2020 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 <index/coinstatsindex.h> #include <test/util/index.h> #include <test/util/setup_common.h> #include <util/time.h> #include <validation.h> #include <boost/test/unit_test.hpp> BOOST_AUTO_TEST_SUITE(coinstatsindex_tests) BOOST_FIXTURE_TEST_CASE(coinstatsindex_initial_sync, TestChain100Setup) { CoinStatsIndex coin_stats_index{1 << 20, true}; CCoinsStats coin_stats{CoinStatsHashType::MUHASH}; 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, coin_stats)); // BlockUntilSyncedToCurrentChain should return false before CoinStatsIndex // is started. BOOST_CHECK(!coin_stats_index.BlockUntilSyncedToCurrentChain()); BOOST_REQUIRE(coin_stats_index.Start(m_node.chainman->ActiveChainstate())); 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, coin_stats)); // Check that CoinStatsIndex updates with new blocks. coin_stats_index.LookUpStats(block_index, coin_stats); 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()); CCoinsStats new_coin_stats{CoinStatsHashType::MUHASH}; const CBlockIndex* new_block_index; { LOCK(cs_main); new_block_index = m_node.chainman->ActiveChain().Tip(); } coin_stats_index.LookUpStats(new_block_index, new_coin_stats); BOOST_CHECK(block_index != new_block_index); // It is not safe to stop and destroy the index until it finishes handling // the last BlockConnected notification. The BlockUntilSyncedToCurrentChain() // call above is sufficient to ensure this, but the // SyncWithValidationInterfaceQueue() call below is also needed to ensure // TSAN always sees the test thread waiting for the notification thread, and // avoid potential false positive reports. SyncWithValidationInterfaceQueue(); // Shutdown sequence (c.f. Shutdown() in init.cpp) coin_stats_index.Stop(); } BOOST_AUTO_TEST_SUITE_END()