Changeset View
Changeset View
Standalone View
Standalone View
src/test/validation_chainstatemanager_tests.cpp
Show All 21 Lines | |||||
//! First create a legacy (IBD) chainstate, then create a snapshot chainstate. | //! First create a legacy (IBD) chainstate, then create a snapshot chainstate. | ||||
BOOST_AUTO_TEST_CASE(chainstatemanager) { | BOOST_AUTO_TEST_CASE(chainstatemanager) { | ||||
ChainstateManager manager; | ChainstateManager manager; | ||||
std::vector<CChainState *> chainstates; | std::vector<CChainState *> chainstates; | ||||
const CChainParams &chainparams = Params(); | const CChainParams &chainparams = Params(); | ||||
// Create a legacy (IBD) chainstate. | // Create a legacy (IBD) chainstate. | ||||
// | // | ||||
ENTER_CRITICAL_SECTION(cs_main); | CChainState &c1 = | ||||
CChainState &c1 = manager.InitializeChainstate(); | *WITH_LOCK(::cs_main, return &manager.InitializeChainstate()); | ||||
LEAVE_CRITICAL_SECTION(cs_main); | |||||
chainstates.push_back(&c1); | chainstates.push_back(&c1); | ||||
c1.InitCoinsDB( | c1.InitCoinsDB( | ||||
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, | /* cache_size_bytes */ 1 << 23, /* in_memory */ true, | ||||
/* should_wipe */ false); | /* should_wipe */ false); | ||||
WITH_LOCK(::cs_main, c1.InitCoinsCache()); | WITH_LOCK(::cs_main, c1.InitCoinsCache(1 << 23)); | ||||
BOOST_CHECK(!manager.IsSnapshotActive()); | BOOST_CHECK(!manager.IsSnapshotActive()); | ||||
BOOST_CHECK(!manager.IsSnapshotValidated()); | BOOST_CHECK(!manager.IsSnapshotValidated()); | ||||
BOOST_CHECK(!manager.IsBackgroundIBD(&c1)); | BOOST_CHECK(!manager.IsBackgroundIBD(&c1)); | ||||
auto all = manager.GetAll(); | auto all = manager.GetAll(); | ||||
BOOST_CHECK_EQUAL_COLLECTIONS(all.begin(), all.end(), chainstates.begin(), | BOOST_CHECK_EQUAL_COLLECTIONS(all.begin(), all.end(), chainstates.begin(), | ||||
chainstates.end()); | chainstates.end()); | ||||
auto &active_chain = manager.ActiveChain(); | auto &active_chain = manager.ActiveChain(); | ||||
BOOST_CHECK_EQUAL(&active_chain, &c1.m_chain); | BOOST_CHECK_EQUAL(&active_chain, &c1.m_chain); | ||||
BOOST_CHECK_EQUAL(manager.ActiveHeight(), -1); | BOOST_CHECK_EQUAL(manager.ActiveHeight(), -1); | ||||
auto active_tip = manager.ActiveTip(); | auto active_tip = manager.ActiveTip(); | ||||
auto exp_tip = c1.m_chain.Tip(); | auto exp_tip = c1.m_chain.Tip(); | ||||
BOOST_CHECK_EQUAL(active_tip, exp_tip); | BOOST_CHECK_EQUAL(active_tip, exp_tip); | ||||
auto &validated_cs = manager.ValidatedChainstate(); | auto &validated_cs = manager.ValidatedChainstate(); | ||||
BOOST_CHECK_EQUAL(&validated_cs, &c1); | BOOST_CHECK_EQUAL(&validated_cs, &c1); | ||||
// Create a snapshot-based chainstate. | // Create a snapshot-based chainstate. | ||||
// | // | ||||
ENTER_CRITICAL_SECTION(cs_main); | ENTER_CRITICAL_SECTION(cs_main); | ||||
CChainState &c2 = manager.InitializeChainstate(BlockHash(GetRandHash())); | CChainState &c2 = *WITH_LOCK( | ||||
::cs_main, | |||||
return &manager.InitializeChainstate(BlockHash{GetRandHash()})); | |||||
LEAVE_CRITICAL_SECTION(cs_main); | LEAVE_CRITICAL_SECTION(cs_main); | ||||
chainstates.push_back(&c2); | chainstates.push_back(&c2); | ||||
c2.InitCoinsDB( | c2.InitCoinsDB( | ||||
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, | /* cache_size_bytes */ 1 << 23, /* in_memory */ true, | ||||
/* should_wipe */ false); | /* should_wipe */ false); | ||||
WITH_LOCK(::cs_main, c2.InitCoinsCache()); | WITH_LOCK(::cs_main, c2.InitCoinsCache(1 << 23)); | ||||
// Unlike c1, which doesn't have any blocks. Gets us different tip, height. | // Unlike c1, which doesn't have any blocks. Gets us different tip, height. | ||||
c2.LoadGenesisBlock(chainparams); | c2.LoadGenesisBlock(chainparams); | ||||
BlockValidationState _; | BlockValidationState _; | ||||
BOOST_CHECK(c2.ActivateBestChain(GetConfig(), _, nullptr)); | BOOST_CHECK(c2.ActivateBestChain(GetConfig(), _, nullptr)); | ||||
BOOST_CHECK(manager.IsSnapshotActive()); | BOOST_CHECK(manager.IsSnapshotActive()); | ||||
BOOST_CHECK(!manager.IsSnapshotValidated()); | BOOST_CHECK(!manager.IsSnapshotValidated()); | ||||
BOOST_CHECK(manager.IsBackgroundIBD(&c1)); | BOOST_CHECK(manager.IsBackgroundIBD(&c1)); | ||||
Show All 27 Lines | BOOST_AUTO_TEST_CASE(chainstatemanager) { | ||||
// Let scheduler events finish running to avoid accessing memory that is | // Let scheduler events finish running to avoid accessing memory that is | ||||
// going to be unloaded | // going to be unloaded | ||||
SyncWithValidationInterfaceQueue(); | SyncWithValidationInterfaceQueue(); | ||||
WITH_LOCK(::cs_main, manager.Unload()); | WITH_LOCK(::cs_main, manager.Unload()); | ||||
} | } | ||||
//! Test rebalancing the caches associated with each chainstate. | |||||
BOOST_AUTO_TEST_CASE(chainstatemanager_rebalance_caches) { | |||||
ChainstateManager manager; | |||||
size_t max_cache = 10000; | |||||
manager.m_total_coinsdb_cache = max_cache; | |||||
manager.m_total_coinstip_cache = max_cache; | |||||
std::vector<CChainState *> chainstates; | |||||
// Create a legacy (IBD) chainstate. | |||||
// | |||||
ENTER_CRITICAL_SECTION(cs_main); | |||||
CChainState &c1 = manager.InitializeChainstate(); | |||||
LEAVE_CRITICAL_SECTION(cs_main); | |||||
chainstates.push_back(&c1); | |||||
c1.InitCoinsDB( | |||||
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, | |||||
/* should_wipe */ false); | |||||
{ | |||||
LOCK(::cs_main); | |||||
c1.InitCoinsCache(1 << 23); | |||||
c1.CoinsTip().SetBestBlock(BlockHash{InsecureRand256()}); | |||||
manager.MaybeRebalanceCaches(); | |||||
} | |||||
BOOST_CHECK_EQUAL(c1.m_coinstip_cache_size_bytes, max_cache); | |||||
BOOST_CHECK_EQUAL(c1.m_coinsdb_cache_size_bytes, max_cache); | |||||
// Create a snapshot-based chainstate. | |||||
// | |||||
ENTER_CRITICAL_SECTION(cs_main); | |||||
CChainState &c2 = manager.InitializeChainstate(BlockHash{GetRandHash()}); | |||||
LEAVE_CRITICAL_SECTION(cs_main); | |||||
chainstates.push_back(&c2); | |||||
c2.InitCoinsDB( | |||||
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, | |||||
/* should_wipe */ false); | |||||
{ | |||||
LOCK(::cs_main); | |||||
c2.InitCoinsCache(1 << 23); | |||||
c2.CoinsTip().SetBestBlock(BlockHash{InsecureRand256()}); | |||||
manager.MaybeRebalanceCaches(); | |||||
} | |||||
// Since both chainstates are considered to be in initial block download, | |||||
// the snapshot chainstate should take priority. | |||||
BOOST_CHECK_CLOSE(c1.m_coinstip_cache_size_bytes, max_cache * 0.05, 1); | |||||
BOOST_CHECK_CLOSE(c1.m_coinsdb_cache_size_bytes, max_cache * 0.05, 1); | |||||
BOOST_CHECK_CLOSE(c2.m_coinstip_cache_size_bytes, max_cache * 0.95, 1); | |||||
BOOST_CHECK_CLOSE(c2.m_coinsdb_cache_size_bytes, max_cache * 0.95, 1); | |||||
} | |||||
BOOST_AUTO_TEST_SUITE_END() | BOOST_AUTO_TEST_SUITE_END() |