mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-03 09:43:55 +02:00
Merge #17737: Add ChainstateManager, remove BlockManager global
c9017ce3bcprotect g_chainman with cs_main (James O'Beirne)2b081c4568test: add basic tests for ChainstateManager (James O'Beirne)4ae29f5f0cuse ChainstateManager to initialize chainstate (James O'Beirne)5b690f0aaerefactor: move RewindBlockIndex to CChainState (James O'Beirne)89cdf4d569validation: introduce unused ChainstateManager (James O'Beirne)8e2ecfe249validation: add CChainState.m_from_snapshot_blockhash (James O'Beirne) Pull request description: This is part of the [assumeutxo project](https://github.com/bitcoin/bitcoin/projects/11): Parent PR: #15606 Issue: #15605 Specification: https://github.com/jamesob/assumeutxo-docs/tree/master/proposal --- This changeset introduces `ChainstateManager`, which is responsible for creating and managing access to multiple chainstates. Until we allow chainstate creation from UTXO snapshots (next assumeutxo PR?) it's basically unnecessary, but it is a prerequisite for background IBD support. Changes are also made to the initialization process to make use of `g_chainman` and thus clear the way for multiple chainstates being loaded on startup. One immediate benefit of this change is that we no longer have the `g_blockman` global, but instead have the ChainstateManager inject a reference of its shared BlockManager into any chainstate it creates. Another immediate benefit is that uses of `ChainActive()` and `ChainstateActive()` are now covered by lock annotations. Because use of `g_chainman` is annotated to require cs_main, these two functions subsequently follow. Because of whitespace changes, this diff looks bigger than it is. E.g., 4813167d98 is most easily reviewed with ```sh git show --color-moved=dimmed_zebra -w 4813167d98 ``` ACKs for top commit: MarcoFalke: re-ACKc9017ce3bc📙 fjahr: Code Review Re-ACKc9017ce3bcariard: Code Review ACKc9017ceryanofsky: Code review ACKc9017ce3bc. No changes since last review other than a straight rebase Tree-SHA512: 3f250d0dc95d4bfd70852ef1e39e081a4a9b71a4453f276e6d474c2ae06ad6ae6a32b4173084fe499e1e9af72dd9007f4a8a375c63ce9ac472ffeaada41ab508
This commit is contained in:
@@ -114,7 +114,8 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha
|
||||
GetMainSignals().RegisterBackgroundSignalScheduler(*g_rpc_node->scheduler);
|
||||
|
||||
pblocktree.reset(new CBlockTreeDB(1 << 20, true));
|
||||
g_chainstate = MakeUnique<CChainState>();
|
||||
|
||||
g_chainman.InitializeChainstate();
|
||||
::ChainstateActive().InitCoinsDB(
|
||||
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
|
||||
assert(!::ChainstateActive().CanFlushToDisk());
|
||||
@@ -161,7 +162,7 @@ TestingSetup::~TestingSetup()
|
||||
m_node.mempool = nullptr;
|
||||
m_node.scheduler.reset();
|
||||
UnloadBlockIndex();
|
||||
g_chainstate.reset();
|
||||
g_chainman.Reset();
|
||||
pblocktree.reset();
|
||||
}
|
||||
|
||||
|
||||
104
src/test/validation_chainstatemanager_tests.cpp
Normal file
104
src/test/validation_chainstatemanager_tests.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
// Copyright (c) 2019 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 <random.h>
|
||||
#include <uint256.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <sync.h>
|
||||
#include <test/util/setup_common.h>
|
||||
#include <validation.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(validation_chainstatemanager_tests, TestingSetup)
|
||||
|
||||
//! Basic tests for ChainstateManager.
|
||||
//!
|
||||
//! First create a legacy (IBD) chainstate, then create a snapshot chainstate.
|
||||
BOOST_AUTO_TEST_CASE(chainstatemanager)
|
||||
{
|
||||
ChainstateManager manager;
|
||||
std::vector<CChainState*> chainstates;
|
||||
const CChainParams& chainparams = Params();
|
||||
|
||||
// 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);
|
||||
WITH_LOCK(::cs_main, c1.InitCoinsCache());
|
||||
|
||||
BOOST_CHECK(!manager.IsSnapshotActive());
|
||||
BOOST_CHECK(!manager.IsSnapshotValidated());
|
||||
BOOST_CHECK(!manager.IsBackgroundIBD(&c1));
|
||||
auto all = manager.GetAll();
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(all.begin(), all.end(), chainstates.begin(), chainstates.end());
|
||||
|
||||
auto& active_chain = manager.ActiveChain();
|
||||
BOOST_CHECK_EQUAL(&active_chain, &c1.m_chain);
|
||||
|
||||
BOOST_CHECK_EQUAL(manager.ActiveHeight(), -1);
|
||||
|
||||
auto active_tip = manager.ActiveTip();
|
||||
auto exp_tip = c1.m_chain.Tip();
|
||||
BOOST_CHECK_EQUAL(active_tip, exp_tip);
|
||||
|
||||
auto& validated_cs = manager.ValidatedChainstate();
|
||||
BOOST_CHECK_EQUAL(&validated_cs, &c1);
|
||||
|
||||
// Create a snapshot-based chainstate.
|
||||
//
|
||||
ENTER_CRITICAL_SECTION(cs_main);
|
||||
CChainState& c2 = manager.InitializeChainstate(GetRandHash());
|
||||
LEAVE_CRITICAL_SECTION(cs_main);
|
||||
chainstates.push_back(&c2);
|
||||
c2.InitCoinsDB(
|
||||
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
|
||||
WITH_LOCK(::cs_main, c2.InitCoinsCache());
|
||||
// Unlike c1, which doesn't have any blocks. Gets us different tip, height.
|
||||
c2.LoadGenesisBlock(chainparams);
|
||||
BlockValidationState _;
|
||||
BOOST_CHECK(c2.ActivateBestChain(_, chainparams, nullptr));
|
||||
|
||||
BOOST_CHECK(manager.IsSnapshotActive());
|
||||
BOOST_CHECK(!manager.IsSnapshotValidated());
|
||||
BOOST_CHECK(manager.IsBackgroundIBD(&c1));
|
||||
BOOST_CHECK(!manager.IsBackgroundIBD(&c2));
|
||||
auto all2 = manager.GetAll();
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(all2.begin(), all2.end(), chainstates.begin(), chainstates.end());
|
||||
|
||||
auto& active_chain2 = manager.ActiveChain();
|
||||
BOOST_CHECK_EQUAL(&active_chain2, &c2.m_chain);
|
||||
|
||||
BOOST_CHECK_EQUAL(manager.ActiveHeight(), 0);
|
||||
|
||||
auto active_tip2 = manager.ActiveTip();
|
||||
auto exp_tip2 = c2.m_chain.Tip();
|
||||
BOOST_CHECK_EQUAL(active_tip2, exp_tip2);
|
||||
|
||||
// Ensure that these pointers actually correspond to different
|
||||
// CCoinsViewCache instances.
|
||||
BOOST_CHECK(exp_tip != exp_tip2);
|
||||
|
||||
auto& validated_cs2 = manager.ValidatedChainstate();
|
||||
BOOST_CHECK_EQUAL(&validated_cs2, &c1);
|
||||
|
||||
auto& validated_chain = manager.ValidatedChain();
|
||||
BOOST_CHECK_EQUAL(&validated_chain, &c1.m_chain);
|
||||
|
||||
auto validated_tip = manager.ValidatedTip();
|
||||
exp_tip = c1.m_chain.Tip();
|
||||
BOOST_CHECK_EQUAL(validated_tip, exp_tip);
|
||||
|
||||
// Avoid triggering the address sanitizer.
|
||||
WITH_LOCK(::cs_main, manager.Unload());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
Reference in New Issue
Block a user