Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | |||||
#include <util/system.h> | #include <util/system.h> | ||||
#include <util/translation.h> | #include <util/translation.h> | ||||
#include <validationinterface.h> | #include <validationinterface.h> | ||||
#include <warnings.h> | #include <warnings.h> | ||||
#include <boost/algorithm/string/replace.hpp> | #include <boost/algorithm/string/replace.hpp> | ||||
#include <boost/thread.hpp> // boost::this_thread::interruption_point() (mingw) | #include <boost/thread.hpp> // boost::this_thread::interruption_point() (mingw) | ||||
#include <optional> | |||||
#include <string> | #include <string> | ||||
#include <thread> | #include <thread> | ||||
#define MICRO 0.000001 | #define MICRO 0.000001 | ||||
#define MILLI 0.001 | #define MILLI 0.001 | ||||
namespace { | namespace { | ||||
BlockManager g_blockman; | BlockManager g_blockman; | ||||
▲ Show 20 Lines • Show All 5,506 Lines • ▼ Show 20 Lines | while (pindex != nullptr) { | ||||
} | } | ||||
} | } | ||||
} | } | ||||
// Check that we actually traversed the entire map. | // Check that we actually traversed the entire map. | ||||
assert(nNodes == forward.size()); | 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 { | std::string CBlockFileInfo::ToString() const { | ||||
return strprintf( | return strprintf( | ||||
"CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s)", | "CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s)", | ||||
nBlocks, nSize, nHeightFirst, nHeightLast, | nBlocks, nSize, nHeightFirst, nHeightLast, | ||||
FormatISO8601DateTime(nTimeFirst), FormatISO8601DateTime(nTimeLast)); | FormatISO8601DateTime(nTimeFirst), FormatISO8601DateTime(nTimeLast)); | ||||
} | } | ||||
CBlockFileInfo *GetBlockFileInfo(size_t n) { | CBlockFileInfo *GetBlockFileInfo(size_t n) { | ||||
▲ Show 20 Lines • Show All 213 Lines • ▼ Show 20 Lines | ~CMainCleanup() { | ||||
for (const std::pair<const BlockHash, CBlockIndex *> &it : | for (const std::pair<const BlockHash, CBlockIndex *> &it : | ||||
g_blockman.m_block_index) { | g_blockman.m_block_index) { | ||||
delete it.second; | delete it.second; | ||||
} | } | ||||
g_blockman.m_block_index.clear(); | g_blockman.m_block_index.clear(); | ||||
} | } | ||||
}; | }; | ||||
static CMainCleanup instance_of_cmaincleanup; | static CMainCleanup instance_of_cmaincleanup; | ||||
std::optional<BlockHash> 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 BlockHash &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; | |||||
} |