mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-04-03 20:35:17 +02:00
validation: indexing changes for assumeutxo
When using an assumedvalid chainstate, only process validationinterface callbacks from the background chainstate within indexes. This ensures that all indexes are built in-order. Later, we can possibly designate indexes which can be built out of order and continue their operation during snapshot use. Once the background sync has completed, restart the indexes so that they continue to index the now-validated snapshot chainstate.
This commit is contained in:
committed by
James O'Beirne
parent
1fffdd76a1
commit
373cf91531
@@ -79,9 +79,15 @@ BaseIndex::~BaseIndex()
|
||||
|
||||
bool BaseIndex::Init()
|
||||
{
|
||||
AssertLockNotHeld(cs_main);
|
||||
|
||||
// May need reset if index is being restarted.
|
||||
m_interrupt.reset();
|
||||
|
||||
// m_chainstate member gives indexing code access to node internals. It is
|
||||
// removed in followup https://github.com/bitcoin/bitcoin/pull/24230
|
||||
m_chainstate = &m_chain->context()->chainman->ActiveChainstate();
|
||||
m_chainstate = WITH_LOCK(::cs_main,
|
||||
return &m_chain->context()->chainman->GetChainstateForIndexing());
|
||||
// Register to validation interface before setting the 'm_synced' flag, so that
|
||||
// callbacks are not missed once m_synced is true.
|
||||
RegisterValidationInterface(this);
|
||||
@@ -92,7 +98,8 @@ bool BaseIndex::Init()
|
||||
}
|
||||
|
||||
LOCK(cs_main);
|
||||
CChain& active_chain = m_chainstate->m_chain;
|
||||
CChain& index_chain = m_chainstate->m_chain;
|
||||
|
||||
if (locator.IsNull()) {
|
||||
SetBestBlockIndex(nullptr);
|
||||
} else {
|
||||
@@ -114,7 +121,7 @@ bool BaseIndex::Init()
|
||||
// Note: this will latch to true immediately if the user starts up with an empty
|
||||
// datadir and an index enabled. If this is the case, indexation will happen solely
|
||||
// via `BlockConnected` signals until, possibly, the next restart.
|
||||
m_synced = start_block == active_chain.Tip();
|
||||
m_synced = start_block == index_chain.Tip();
|
||||
m_init = true;
|
||||
return true;
|
||||
}
|
||||
@@ -143,6 +150,8 @@ void BaseIndex::ThreadSync()
|
||||
std::chrono::steady_clock::time_point last_locator_write_time{0s};
|
||||
while (true) {
|
||||
if (m_interrupt) {
|
||||
LogPrintf("%s: m_interrupt set; exiting ThreadSync\n", GetName());
|
||||
|
||||
SetBestBlockIndex(pindex);
|
||||
// No need to handle errors in Commit. If it fails, the error will be already be
|
||||
// logged. The best way to recover is to continue, as index cannot be corrupted by
|
||||
@@ -252,6 +261,17 @@ bool BaseIndex::Rewind(const CBlockIndex* current_tip, const CBlockIndex* new_ti
|
||||
|
||||
void BaseIndex::BlockConnected(ChainstateRole role, const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex)
|
||||
{
|
||||
// Ignore events from the assumed-valid chain; we will process its blocks
|
||||
// (sequentially) after it is fully verified by the background chainstate. This
|
||||
// is to avoid any out-of-order indexing.
|
||||
//
|
||||
// TODO at some point we could parameterize whether a particular index can be
|
||||
// built out of order, but for now just do the conservative simple thing.
|
||||
if (role == ChainstateRole::ASSUMEDVALID) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore BlockConnected signals until we have fully indexed the chain.
|
||||
if (!m_synced) {
|
||||
return;
|
||||
}
|
||||
@@ -298,6 +318,12 @@ void BaseIndex::BlockConnected(ChainstateRole role, const std::shared_ptr<const
|
||||
|
||||
void BaseIndex::ChainStateFlushed(ChainstateRole role, const CBlockLocator& locator)
|
||||
{
|
||||
// Ignore events from the assumed-valid chain; we will process its blocks
|
||||
// (sequentially) after it is fully verified by the background chainstate.
|
||||
if (role == ChainstateRole::ASSUMEDVALID) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_synced) {
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user