mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-03-21 05:00:10 +01:00
validation: introduce unused ChainstateManager
ChainstateManager is responsible for creating and managing multiple chainstates, and will provide a high-level interface for accessing the appropriate chainstate based upon a certain use. Incorporates feedback from Marco Falke. Additional documentation written by Russ Yanofsky. Co-authored-by: Russell Yanofsky <russ@yanofsky.org>
This commit is contained in:
committed by
James O'Beirne
parent
8e2ecfe249
commit
89cdf4d569
@@ -20,6 +20,7 @@
|
||||
#include <index/txindex.h>
|
||||
#include <logging.h>
|
||||
#include <logging/timer.h>
|
||||
#include <optional.h>
|
||||
#include <policy/fees.h>
|
||||
#include <policy/policy.h>
|
||||
#include <policy/settings.h>
|
||||
@@ -4950,6 +4951,14 @@ void CChainState::CheckBlockIndex(const Consensus::Params& consensusParams)
|
||||
assert(nNodes == forward.size());
|
||||
}
|
||||
|
||||
std::string CChainState::ToString()
|
||||
{
|
||||
CBlockIndex* tip = m_chain.Tip();
|
||||
return strprintf("Chainstate [%s] @ height %d (%s)",
|
||||
m_from_snapshot_blockhash.IsNull() ? "ibd" : "snapshot",
|
||||
tip ? tip->nHeight : -1, tip ? tip->GetBlockHash().ToString() : "null");
|
||||
}
|
||||
|
||||
std::string CBlockFileInfo::ToString() const
|
||||
{
|
||||
return strprintf("CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s)", nBlocks, nSize, nHeightFirst, nHeightLast, FormatISO8601Date(nTimeFirst), FormatISO8601Date(nTimeLast));
|
||||
@@ -5144,3 +5153,90 @@ public:
|
||||
}
|
||||
};
|
||||
static CMainCleanup instance_of_cmaincleanup;
|
||||
|
||||
Optional<uint256> ChainstateManager::SnapshotBlockhash() const {
|
||||
if (m_active_chainstate != nullptr) {
|
||||
// If a snapshot chainstate exists, it will always be our active.
|
||||
return m_active_chainstate->m_from_snapshot_blockhash;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<CChainState*> ChainstateManager::GetAll()
|
||||
{
|
||||
std::vector<CChainState*> out;
|
||||
|
||||
if (!IsSnapshotValidated() && m_ibd_chainstate) {
|
||||
out.push_back(m_ibd_chainstate.get());
|
||||
}
|
||||
|
||||
if (m_snapshot_chainstate) {
|
||||
out.push_back(m_snapshot_chainstate.get());
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
CChainState& ChainstateManager::InitializeChainstate(const uint256& snapshot_blockhash)
|
||||
{
|
||||
bool is_snapshot = !snapshot_blockhash.IsNull();
|
||||
std::unique_ptr<CChainState>& to_modify =
|
||||
is_snapshot ? m_snapshot_chainstate : m_ibd_chainstate;
|
||||
|
||||
if (to_modify) {
|
||||
throw std::logic_error("should not be overwriting a chainstate");
|
||||
}
|
||||
|
||||
to_modify.reset(new CChainState(snapshot_blockhash));
|
||||
|
||||
// Snapshot chainstates and initial IBD chaintates always become active.
|
||||
if (is_snapshot || (!is_snapshot && !m_active_chainstate)) {
|
||||
LogPrintf("Switching active chainstate to %s\n", to_modify->ToString());
|
||||
m_active_chainstate = to_modify.get();
|
||||
} else {
|
||||
throw std::logic_error("unexpected chainstate activation");
|
||||
}
|
||||
|
||||
return *to_modify;
|
||||
}
|
||||
|
||||
CChain& ChainstateManager::ActiveChain() const
|
||||
{
|
||||
assert(m_active_chainstate);
|
||||
return m_active_chainstate->m_chain;
|
||||
}
|
||||
|
||||
bool ChainstateManager::IsSnapshotActive() const
|
||||
{
|
||||
return m_snapshot_chainstate && m_active_chainstate == m_snapshot_chainstate.get();
|
||||
}
|
||||
|
||||
CChainState& ChainstateManager::ValidatedChainstate() const
|
||||
{
|
||||
if (m_snapshot_chainstate && IsSnapshotValidated()) {
|
||||
return *m_snapshot_chainstate.get();
|
||||
}
|
||||
assert(m_ibd_chainstate);
|
||||
return *m_ibd_chainstate.get();
|
||||
}
|
||||
|
||||
bool ChainstateManager::IsBackgroundIBD(CChainState* chainstate) const
|
||||
{
|
||||
return (m_snapshot_chainstate && chainstate == m_ibd_chainstate.get());
|
||||
}
|
||||
|
||||
void ChainstateManager::Unload()
|
||||
{
|
||||
for (CChainState* chainstate : this->GetAll()) {
|
||||
chainstate->m_chain.SetTip(nullptr);
|
||||
chainstate->UnloadBlockIndex();
|
||||
}
|
||||
}
|
||||
|
||||
void ChainstateManager::Reset()
|
||||
{
|
||||
m_ibd_chainstate.reset();
|
||||
m_snapshot_chainstate.reset();
|
||||
m_active_chainstate = nullptr;
|
||||
m_snapshot_validated = false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user