init: add utxo snapshot detection

Add functionality for activating a snapshot-based chainstate if one is
detected on-disk.

Also cautiously initialize chainstate cache usages so that we don't
somehow blow past our cache allowances during initialization, then
rebalance at the end of init.

Co-authored-by: Russell Yanofsky <russ@yanofsky.org>
This commit is contained in:
James O'Beirne
2022-04-20 17:40:01 -04:00
parent f9f1735f13
commit 252abd1e8b
7 changed files with 87 additions and 34 deletions

View File

@@ -4744,28 +4744,15 @@ std::vector<Chainstate*> ChainstateManager::GetAll()
return out;
}
Chainstate& ChainstateManager::InitializeChainstate(
CTxMemPool* mempool, const std::optional<uint256>& snapshot_blockhash)
Chainstate& ChainstateManager::InitializeChainstate(CTxMemPool* mempool)
{
AssertLockHeld(::cs_main);
bool is_snapshot = snapshot_blockhash.has_value();
std::unique_ptr<Chainstate>& to_modify =
is_snapshot ? m_snapshot_chainstate : m_ibd_chainstate;
assert(!m_ibd_chainstate);
assert(!m_active_chainstate);
if (to_modify) {
throw std::logic_error("should not be overwriting a chainstate");
}
to_modify.reset(new Chainstate(mempool, m_blockman, *this, 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;
m_ibd_chainstate = std::make_unique<Chainstate>(mempool, m_blockman, *this);
m_active_chainstate = m_ibd_chainstate.get();
return *m_active_chainstate;
}
const AssumeutxoData* ExpectedAssumeutxo(
@@ -5134,3 +5121,31 @@ ChainstateManager::~ChainstateManager()
i.clear();
}
}
bool ChainstateManager::DetectSnapshotChainstate(CTxMemPool* mempool)
{
assert(!m_snapshot_chainstate);
std::optional<fs::path> path = node::FindSnapshotChainstateDir();
if (!path) {
return false;
}
std::optional<uint256> base_blockhash = node::ReadSnapshotBaseBlockhash(*path);
if (!base_blockhash) {
return false;
}
LogPrintf("[snapshot] detected active snapshot chainstate (%s) - loading\n",
fs::PathToString(*path));
this->ActivateExistingSnapshot(mempool, *base_blockhash);
return true;
}
Chainstate& ChainstateManager::ActivateExistingSnapshot(CTxMemPool* mempool, uint256 base_blockhash)
{
assert(!m_snapshot_chainstate);
m_snapshot_chainstate =
std::make_unique<Chainstate>(mempool, m_blockman, *this, base_blockhash);
LogPrintf("[snapshot] switching active chainstate to %s\n", m_snapshot_chainstate->ToString());
m_active_chainstate = m_snapshot_chainstate.get();
return *m_snapshot_chainstate;
}