-
-
Save jamesob/8535a4b81fc29e890ce2eff9a0fb2f1d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- /home/james/.ackr/by-date/2023-06-21.27746.sdaftuar.rework_validation_logic.1/base.diff 2023-06-21 11:17:23.507892496 -0400 | |
+++ /home/james/.ackr/by-date/2023-07-03.27746.sdaftuar.rework_validation_logic.3/base.diff 2023-07-03 13:52:58.475417323 -0400 | |
@@ -76,23 +76,10 @@ | |
BLOCK_ASSUMED_VALID = 256, | |
}; | |
diff --git a/src/node/blockstorage.cpp b/src/node/blockstorage.cpp | |
-index 1368ae6f6d..b68bbf98c3 100644 | |
+index 1368ae6f6d..09368968b2 100644 | |
--- a/src/node/blockstorage.cpp | |
+++ b/src/node/blockstorage.cpp | |
-@@ -249,6 +249,12 @@ CBlockIndex* BlockManager::InsertBlockIndex(const uint256& hash) | |
- return pindex; | |
- } | |
- | |
-+void BlockManager::AddDirty(CBlockIndex *pindex) | |
-+{ | |
-+ AssertLockHeld(cs_main); | |
-+ m_dirty_blockindex.insert(pindex); | |
-+} | |
-+ | |
- bool BlockManager::LoadBlockIndex() | |
- { | |
- if (!m_block_tree_db->LoadBlockIndexGuts(GetConsensus(), [this](const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { return this->InsertBlockIndex(hash); })) { | |
-@@ -604,7 +610,7 @@ fs::path BlockManager::GetBlockPosFilename(const FlatFilePos& pos) const | |
+@@ -604,7 +604,7 @@ fs::path BlockManager::GetBlockPosFilename(const FlatFilePos& pos) const | |
return BlockFileSeq().FileName(pos); | |
} | |
@@ -101,7 +88,7 @@ | |
{ | |
LOCK(cs_LastBlockFile); | |
-@@ -630,7 +636,7 @@ bool BlockManager::FindBlockPos(FlatFilePos& pos, unsigned int nAddSize, unsigne | |
+@@ -630,7 +630,7 @@ bool BlockManager::FindBlockPos(FlatFilePos& pos, unsigned int nAddSize, unsigne | |
// when the undo file is keeping up with the block file, we want to flush it explicitly | |
// when it is lagging behind (more blocks arrive than are being connected), we let the | |
// undo block write case handle it | |
@@ -110,7 +97,7 @@ | |
nFile++; | |
if (m_blockfile_info.size() <= nFile) { | |
m_blockfile_info.resize(nFile + 1); | |
-@@ -646,6 +652,7 @@ bool BlockManager::FindBlockPos(FlatFilePos& pos, unsigned int nAddSize, unsigne | |
+@@ -646,6 +646,7 @@ bool BlockManager::FindBlockPos(FlatFilePos& pos, unsigned int nAddSize, unsigne | |
} | |
FlushBlockFile(!fKnown, finalize_undo); | |
m_last_blockfile = nFile; | |
@@ -118,7 +105,7 @@ | |
} | |
m_blockfile_info[nFile].AddBlock(nHeight, nTime); | |
-@@ -734,8 +741,9 @@ bool BlockManager::WriteUndoDataForBlock(const CBlockUndo& blockundo, BlockValid | |
+@@ -734,8 +735,9 @@ bool BlockManager::WriteUndoDataForBlock(const CBlockUndo& blockundo, BlockValid | |
// the FindBlockPos function | |
if (_pos.nFile < m_last_blockfile && static_cast<uint32_t>(block.nHeight) == m_blockfile_info[_pos.nFile].nHeightLast) { | |
FlushUndoFile(_pos.nFile, true); | |
@@ -129,7 +116,7 @@ | |
// update nUndoPos in block index | |
block.nUndoPos = _pos.nPos; | |
block.nStatus |= BLOCK_HAVE_UNDO; | |
-@@ -824,7 +832,7 @@ bool BlockManager::ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatF | |
+@@ -824,7 +826,7 @@ bool BlockManager::ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatF | |
return true; | |
} | |
@@ -138,7 +125,7 @@ | |
{ | |
unsigned int nBlockSize = ::GetSerializeSize(block, CLIENT_VERSION); | |
FlatFilePos blockPos; | |
-@@ -837,7 +845,7 @@ FlatFilePos BlockManager::SaveBlockToDisk(const CBlock& block, int nHeight, CCha | |
+@@ -837,7 +839,7 @@ FlatFilePos BlockManager::SaveBlockToDisk(const CBlock& block, int nHeight, CCha | |
// we add BLOCK_SERIALIZATION_HEADER_SIZE only for new blocks since they will have the serialization header added when written to disk. | |
nBlockSize += static_cast<unsigned int>(BLOCK_SERIALIZATION_HEADER_SIZE); | |
} | |
@@ -147,7 +134,7 @@ | |
error("%s: FindBlockPos failed", __func__); | |
return FlatFilePos(); | |
} | |
-@@ -891,7 +899,7 @@ void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFile | |
+@@ -891,7 +893,7 @@ void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFile | |
break; // This error is logged in OpenBlockFile | |
} | |
LogPrintf("Reindexing block file blk%05u.dat...\n", (unsigned int)nFile); | |
@@ -156,7 +143,7 @@ | |
if (ShutdownRequested()) { | |
LogPrintf("Shutdown requested. Exit %s\n", __func__); | |
return; | |
-@@ -910,7 +918,7 @@ void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFile | |
+@@ -910,7 +912,7 @@ void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFile | |
FILE* file = fsbridge::fopen(path, "rb"); | |
if (file) { | |
LogPrintf("Importing blocks file %s...\n", fs::PathToString(path)); | |
@@ -166,7 +153,7 @@ | |
LogPrintf("Shutdown requested. Exit %s\n", __func__); | |
return; | |
diff --git a/src/node/blockstorage.h b/src/node/blockstorage.h | |
-index a1ebb0df0a..b77ebf354c 100644 | |
+index a1ebb0df0a..e97603e64f 100644 | |
--- a/src/node/blockstorage.h | |
+++ b/src/node/blockstorage.h | |
@@ -24,7 +24,6 @@ class BlockValidationState; | |
@@ -195,7 +182,7 @@ | |
+ // data has been written. Block data is written to block files in download | |
+ // order, but is written to undo files in validation order, which is | |
+ // usually in order by height. To avoid wasting disk space, undo files will | |
-+ // be will trimmed whenever the corresponding block file is finalized and | |
++ // be trimmed whenever the corresponding block file is finalized and | |
+ // the height of the highest block written to the block file equals the | |
+ // height of the highest block written to the undo file. This is a | |
+ // heuristic and can sometimes preemptively trim undo files that will write | |
@@ -206,17 +193,7 @@ | |
/** Global flag to indicate we should check to see if there are | |
* block/undo files that should be deleted. Set on startup | |
* or if we allocate more file space when we're in prune mode | |
-@@ -185,6 +197,9 @@ public: | |
- /** Create a new block index entry for a given block hash */ | |
- CBlockIndex* InsertBlockIndex(const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main); | |
- | |
-+ /** Add a block index to dirty list */ | |
-+ void AddDirty(CBlockIndex* pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main); | |
-+ | |
- //! Mark one block file as pruned (modify associated database entries) | |
- void PruneOneBlockFile(const int fileNumber) EXCLUSIVE_LOCKS_REQUIRED(cs_main); | |
- | |
-@@ -198,7 +213,7 @@ public: | |
+@@ -198,7 +210,7 @@ public: | |
EXCLUSIVE_LOCKS_REQUIRED(::cs_main); | |
/** Store block on disk. If dbp is not nullptr, then it provides the known position of the block within a block file on disk. */ | |
@@ -269,7 +246,7 @@ | |
} | |
diff --git a/src/test/coinstatsindex_tests.cpp b/src/test/coinstatsindex_tests.cpp | |
-index 503a58076b..b268698495 100644 | |
+index 503a58076b..8fc136d1e5 100644 | |
--- a/src/test/coinstatsindex_tests.cpp | |
+++ b/src/test/coinstatsindex_tests.cpp | |
@@ -109,7 +109,7 @@ BOOST_FIXTURE_TEST_CASE(coinstatsindex_unclean_shutdown, TestChain100Setup) | |
@@ -277,7 +254,7 @@ | |
BlockValidationState state; | |
BOOST_CHECK(CheckBlock(block, state, params.GetConsensus())); | |
- BOOST_CHECK(chainstate.AcceptBlock(new_block, state, &new_block_index, true, nullptr, nullptr, true)); | |
-+ BOOST_CHECK(AcceptBlock(new_block, *m_node.chainman, state, &new_block_index, true, nullptr, nullptr, true)); | |
++ BOOST_CHECK(m_node.chainman->AcceptBlock(new_block, state, &new_block_index, true, nullptr, nullptr, true)); | |
CCoinsViewCache view(&chainstate.CoinsTip()); | |
BOOST_CHECK(chainstate.ConnectBlock(block, state, new_block_index, view)); | |
} | |
@@ -329,14 +306,14 @@ | |
BlockValidationState state; | |
if (!node.chainman->ActiveChainstate().ActivateBestChain(state)) { | |
diff --git a/src/test/validation_chainstate_tests.cpp b/src/test/validation_chainstate_tests.cpp | |
-index 2078fcd8f8..d55cc09eef 100644 | |
+index 2078fcd8f8..fe2d2ba592 100644 | |
--- a/src/test/validation_chainstate_tests.cpp | |
+++ b/src/test/validation_chainstate_tests.cpp | |
@@ -77,6 +77,13 @@ BOOST_FIXTURE_TEST_CASE(chainstate_update_tip, TestChain100Setup) | |
// After adding some blocks to the tip, best block should have changed. | |
BOOST_CHECK(::g_best_block != curr_tip); | |
-+ // Grab block 1 from disk; we'll add it back to the background chain later. | |
++ // Grab block 1 from disk; we'll add it to the background chain later. | |
+ std::shared_ptr<CBlock> pblockone = std::make_shared<CBlock>(); | |
+ { | |
+ LOCK(::cs_main); | |
@@ -368,8 +345,8 @@ | |
BOOST_CHECK(checked); | |
- bool accepted = background_cs.AcceptBlock( | |
- pblock, state, &pindex, true, nullptr, &newblock, true); | |
-+ bool accepted = AcceptBlock( | |
-+ pblockone, chainman, state, &pindex, true, nullptr, &newblock, true); | |
++ bool accepted = chainman.AcceptBlock( | |
++ pblockone, state, &pindex, true, nullptr, &newblock, true); | |
BOOST_CHECK(accepted); | |
} | |
+ | |
@@ -562,10 +539,24 @@ | |
//! Ensure that snapshot chainstates initialize properly when found on disk. | |
diff --git a/src/validation.cpp b/src/validation.cpp | |
-index d9a0fce34f..504c547ab3 100644 | |
+index d9a0fce34f..df0f8d0bc9 100644 | |
--- a/src/validation.cpp | |
+++ b/src/validation.cpp | |
-@@ -3188,7 +3188,8 @@ bool Chainstate::ActivateBestChain(BlockValidationState& state, std::shared_ptr< | |
+@@ -1579,6 +1579,13 @@ Chainstate::Chainstate( | |
+ m_chainman(chainman), | |
+ m_from_snapshot_blockhash(from_snapshot_blockhash) {} | |
+ | |
++const CBlockIndex* Chainstate::SnapshotBase() | |
++{ | |
++ if (!m_from_snapshot_blockhash) return nullptr; | |
++ if (!m_cached_snapshot_base) m_cached_snapshot_base = Assert(m_chainman.m_blockman.LookupBlockIndex(*m_from_snapshot_blockhash)); | |
++ return m_cached_snapshot_base; | |
++} | |
++ | |
+ void Chainstate::InitCoinsDB( | |
+ size_t cache_size_bytes, | |
+ bool in_memory, | |
+@@ -3188,7 +3195,8 @@ bool Chainstate::ActivateBestChain(BlockValidationState& state, std::shared_ptr< | |
// that the best block hash is non-null. | |
if (ShutdownRequested()) break; | |
} while (pindexNewTip != pindexMostWork); | |
@@ -575,7 +566,7 @@ | |
// Write changes periodically to disk, after relay. | |
if (!FlushStateToDisk(state, FlushStateMode::PERIODIC)) { | |
-@@ -3208,17 +3209,17 @@ bool Chainstate::PreciousBlock(BlockValidationState& state, CBlockIndex* pindex) | |
+@@ -3208,17 +3216,17 @@ bool Chainstate::PreciousBlock(BlockValidationState& state, CBlockIndex* pindex) | |
// Nothing to do, this block is not at the tip. | |
return true; | |
} | |
@@ -599,7 +590,7 @@ | |
} | |
if (pindex->IsValid(BLOCK_VALID_TRANSACTIONS) && pindex->HaveTxsDownloaded()) { | |
setBlockIndexCandidates.insert(pindex); | |
-@@ -3334,7 +3335,7 @@ bool Chainstate::InvalidateBlock(BlockValidationState& state, CBlockIndex* pinde | |
+@@ -3334,7 +3342,7 @@ bool Chainstate::InvalidateBlock(BlockValidationState& state, CBlockIndex* pinde | |
to_mark_failed = invalid_walk_tip; | |
} | |
@@ -608,250 +599,137 @@ | |
{ | |
LOCK(cs_main); | |
-@@ -3404,8 +3405,31 @@ void Chainstate::ResetBlockFailureFlags(CBlockIndex *pindex) { | |
+@@ -3404,8 +3412,32 @@ void Chainstate::ResetBlockFailureFlags(CBlockIndex *pindex) { | |
} | |
} | |
+void Chainstate::TryAddBlockIndexCandidate(CBlockIndex* pindex) | |
+{ | |
+ AssertLockHeld(cs_main); | |
-+ // If the block has more work than our tip, then it should be a candidate for most-work-chain. | |
-+ if (m_chain.Tip() == nullptr || !setBlockIndexCandidates.value_comp()(pindex, m_chain.Tip())) { | |
-+ bool is_bg_chainstate = m_chainman.IsSnapshotActive() && m_chainman.IsBackgroundChainstate(this) && !m_disabled; | |
-+ if (!is_bg_chainstate) { | |
-+ // The active chainstate should always add entries that have more | |
-+ // work than the tip. | |
++ // The block only is a candidate for the most-work-chain if it has more work than our current tip. | |
++ if (m_chain.Tip() != nullptr && setBlockIndexCandidates.value_comp()(pindex, m_chain.Tip())) { | |
++ return; | |
++ } | |
++ | |
++ bool is_active_chainstate = this == &m_chainman.ActiveChainstate(); | |
++ if (is_active_chainstate) { | |
++ // The active chainstate should always add entries that have more | |
++ // work than the tip. | |
++ setBlockIndexCandidates.insert(pindex); | |
++ } else if (!m_disabled) { | |
++ // For the background chainstate, we only consider connecting blocks | |
++ // towards the snapshot base (which can't be nullptr or else we'll | |
++ // never make progress). | |
++ const CBlockIndex* snapshot_base{Assert(m_chainman.ActiveSnapshotBase())}; | |
++ if (snapshot_base->GetAncestor(pindex->nHeight) == pindex) { | |
+ setBlockIndexCandidates.insert(pindex); | |
-+ } else { | |
-+ // For the background chainstate, we only consider connecting blocks | |
-+ // towards the snapshot base (which can't be nullptr or else we'll | |
-+ // never make progress). | |
-+ const CBlockIndex* snapshot_entry = m_chainman.GetSnapshotBaseBlock(); | |
-+ assert(snapshot_entry != nullptr); | |
-+ if (snapshot_entry->GetAncestor(pindex->nHeight) == pindex) { | |
-+ setBlockIndexCandidates.insert(pindex); | |
-+ } | |
+ } | |
+ } | |
+} | |
+ | |
/** Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS). */ | |
-void Chainstate::ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pindexNew, const FlatFilePos& pos) | |
-+void ReceivedBlockTransactions(const CBlock& block, ChainstateManager& chainman, CBlockIndex* pindexNew, const FlatFilePos& pos) | |
++void ChainstateManager::ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pindexNew, const FlatFilePos& pos) | |
{ | |
AssertLockHeld(cs_main); | |
pindexNew->nTx = block.vtx.size(); | |
-@@ -3414,11 +3438,11 @@ void Chainstate::ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pin | |
+@@ -3414,7 +3446,7 @@ void Chainstate::ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pin | |
pindexNew->nDataPos = pos.nPos; | |
pindexNew->nUndoPos = 0; | |
pindexNew->nStatus |= BLOCK_HAVE_DATA; | |
- if (DeploymentActiveAt(*pindexNew, m_chainman, Consensus::DEPLOYMENT_SEGWIT)) { | |
-+ if (DeploymentActiveAt(*pindexNew, chainman, Consensus::DEPLOYMENT_SEGWIT)) { | |
++ if (DeploymentActiveAt(*pindexNew, *this, Consensus::DEPLOYMENT_SEGWIT)) { | |
pindexNew->nStatus |= BLOCK_OPT_WITNESS; | |
} | |
pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS); | |
-- m_blockman.m_dirty_blockindex.insert(pindexNew); | |
-+ chainman.m_blockman.AddDirty(pindexNew); | |
- | |
- if (pindexNew->pprev == nullptr || pindexNew->pprev->HaveTxsDownloaded()) { | |
- // If pindexNew is the genesis block or all parents are BLOCK_VALID_TRANSACTIONS. | |
-@@ -3430,21 +3454,21 @@ void Chainstate::ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pin | |
- CBlockIndex *pindex = queue.front(); | |
+@@ -3431,8 +3463,8 @@ void Chainstate::ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pin | |
queue.pop_front(); | |
pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx; | |
-- pindex->nSequenceId = nBlockSequenceId++; | |
+ pindex->nSequenceId = nBlockSequenceId++; | |
- if (m_chain.Tip() == nullptr || !setBlockIndexCandidates.value_comp()(pindex, m_chain.Tip())) { | |
-- setBlockIndexCandidates.insert(pindex); | |
-+ pindex->nSequenceId = chainman.nBlockSequenceId++; | |
-+ for (Chainstate *c : chainman.GetAll()) { | |
+- setBlockIndexCandidates.insert(pindex); | |
++ for (Chainstate *c : GetAll()) { | |
+ c->TryAddBlockIndexCandidate(pindex); | |
} | |
-- std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = m_blockman.m_blocks_unlinked.equal_range(pindex); | |
-+ std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = chainman.m_blockman.m_blocks_unlinked.equal_range(pindex); | |
+ std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = m_blockman.m_blocks_unlinked.equal_range(pindex); | |
while (range.first != range.second) { | |
- std::multimap<CBlockIndex*, CBlockIndex*>::iterator it = range.first; | |
- queue.push_back(it->second); | |
- range.first++; | |
-- m_blockman.m_blocks_unlinked.erase(it); | |
-+ chainman.m_blockman.m_blocks_unlinked.erase(it); | |
- } | |
- } | |
- } else { | |
- if (pindexNew->pprev && pindexNew->pprev->IsValid(BLOCK_VALID_TREE)) { | |
-- m_blockman.m_blocks_unlinked.insert(std::make_pair(pindexNew->pprev, pindexNew)); | |
-+ chainman.m_blockman.m_blocks_unlinked.insert(std::make_pair(pindexNew->pprev, pindexNew)); | |
- } | |
- } | |
- } | |
-@@ -3727,15 +3751,15 @@ static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& stat | |
- return true; | |
- } | |
- | |
--bool ChainstateManager::AcceptBlockHeader(const CBlockHeader& block, BlockValidationState& state, CBlockIndex** ppindex, bool min_pow_checked) | |
-+bool AcceptBlockHeader(const CBlockHeader& block, ChainstateManager& chainman, BlockValidationState& state, CBlockIndex** ppindex, bool min_pow_checked) | |
- { | |
- AssertLockHeld(cs_main); | |
- | |
- // Check for duplicate | |
- uint256 hash = block.GetHash(); | |
-- BlockMap::iterator miSelf{m_blockman.m_block_index.find(hash)}; | |
-- if (hash != GetConsensus().hashGenesisBlock) { | |
-- if (miSelf != m_blockman.m_block_index.end()) { | |
-+ BlockMap::iterator miSelf{chainman.m_blockman.m_block_index.find(hash)}; | |
-+ if (hash != chainman.GetConsensus().hashGenesisBlock) { | |
-+ if (miSelf != chainman.m_blockman.m_block_index.end()) { | |
- // Block header is already known. | |
- CBlockIndex* pindex = &(miSelf->second); | |
- if (ppindex) | |
-@@ -3747,15 +3771,15 @@ bool ChainstateManager::AcceptBlockHeader(const CBlockHeader& block, BlockValida | |
- return true; | |
- } | |
- | |
-- if (!CheckBlockHeader(block, state, GetConsensus())) { | |
-+ if (!CheckBlockHeader(block, state, chainman.GetConsensus())) { | |
- LogPrint(BCLog::VALIDATION, "%s: Consensus::CheckBlockHeader: %s, %s\n", __func__, hash.ToString(), state.ToString()); | |
- return false; | |
- } | |
- | |
- // Get prev block index | |
- CBlockIndex* pindexPrev = nullptr; | |
-- BlockMap::iterator mi{m_blockman.m_block_index.find(block.hashPrevBlock)}; | |
-- if (mi == m_blockman.m_block_index.end()) { | |
-+ BlockMap::iterator mi{chainman.m_blockman.m_block_index.find(block.hashPrevBlock)}; | |
-+ if (mi == chainman.m_blockman.m_block_index.end()) { | |
- LogPrint(BCLog::VALIDATION, "header %s has prev block not found: %s\n", hash.ToString(), block.hashPrevBlock.ToString()); | |
- return state.Invalid(BlockValidationResult::BLOCK_MISSING_PREV, "prev-blk-not-found"); | |
- } | |
-@@ -3764,7 +3788,7 @@ bool ChainstateManager::AcceptBlockHeader(const CBlockHeader& block, BlockValida | |
- LogPrint(BCLog::VALIDATION, "header %s has prev block invalid: %s\n", hash.ToString(), block.hashPrevBlock.ToString()); | |
- return state.Invalid(BlockValidationResult::BLOCK_INVALID_PREV, "bad-prevblk"); | |
- } | |
-- if (!ContextualCheckBlockHeader(block, state, m_blockman, *this, pindexPrev, m_options.adjusted_time_callback())) { | |
-+ if (!ContextualCheckBlockHeader(block, state, chainman.m_blockman, chainman, pindexPrev, chainman.m_options.adjusted_time_callback())) { | |
- LogPrint(BCLog::VALIDATION, "%s: Consensus::ContextualCheckBlockHeader: %s, %s\n", __func__, hash.ToString(), state.ToString()); | |
- return false; | |
- } | |
-@@ -3793,13 +3817,13 @@ bool ChainstateManager::AcceptBlockHeader(const CBlockHeader& block, BlockValida | |
- // hasn't been validated up to BLOCK_VALID_SCRIPTS. This is a performance | |
- // optimization, in the common case of adding a new block to the tip, | |
- // we don't need to iterate over the failed blocks list. | |
-- for (const CBlockIndex* failedit : m_failed_blocks) { | |
-+ for (const CBlockIndex* failedit : chainman.m_failed_blocks) { | |
- if (pindexPrev->GetAncestor(failedit->nHeight) == failedit) { | |
- assert(failedit->nStatus & BLOCK_FAILED_VALID); | |
- CBlockIndex* invalid_walk = pindexPrev; | |
- while (invalid_walk != failedit) { | |
- invalid_walk->nStatus |= BLOCK_FAILED_CHILD; | |
-- m_blockman.m_dirty_blockindex.insert(invalid_walk); | |
-+ chainman.m_blockman.AddDirty(invalid_walk); | |
- invalid_walk = invalid_walk->pprev; | |
- } | |
- LogPrint(BCLog::VALIDATION, "header %s has prev block invalid: %s\n", hash.ToString(), block.hashPrevBlock.ToString()); | |
-@@ -3812,7 +3836,7 @@ bool ChainstateManager::AcceptBlockHeader(const CBlockHeader& block, BlockValida | |
- LogPrint(BCLog::VALIDATION, "%s: not adding new block header %s, missing anti-dos proof-of-work validation\n", __func__, hash.ToString()); | |
- return state.Invalid(BlockValidationResult::BLOCK_HEADER_LOW_WORK, "too-little-chainwork"); | |
- } | |
-- CBlockIndex* pindex{m_blockman.AddToBlockIndex(block, m_best_header)}; | |
-+ CBlockIndex* pindex{chainman.m_blockman.AddToBlockIndex(block, chainman.m_best_header)}; | |
- | |
- if (ppindex) | |
- *ppindex = pindex; | |
-@@ -3828,7 +3852,7 @@ bool ChainstateManager::AcceptBlockHeader(const CBlockHeader& block, BlockValida | |
- const auto msg = strprintf( | |
- "Saw new header hash=%s height=%d", hash.ToString(), pindex->nHeight); | |
- | |
-- if (ActiveChainstate().IsInitialBlockDownload()) { | |
-+ if (chainman.ActiveChainstate().IsInitialBlockDownload()) { | |
- LogPrintLevel(BCLog::VALIDATION, BCLog::Level::Debug, "%s\n", msg); | |
- } else { | |
- LogPrintf("%s\n", msg); | |
-@@ -3845,8 +3869,8 @@ bool ChainstateManager::ProcessNewBlockHeaders(const std::vector<CBlockHeader>& | |
- LOCK(cs_main); | |
+@@ -3846,7 +3878,7 @@ bool ChainstateManager::ProcessNewBlockHeaders(const std::vector<CBlockHeader>& | |
for (const CBlockHeader& header : headers) { | |
CBlockIndex *pindex = nullptr; // Use a temp pindex instead of ppindex to avoid a const_cast | |
-- bool accepted{AcceptBlockHeader(header, state, &pindex, min_pow_checked)}; | |
+ bool accepted{AcceptBlockHeader(header, state, &pindex, min_pow_checked)}; | |
- ActiveChainstate().CheckBlockIndex(); | |
-+ bool accepted{AcceptBlockHeader(header, *this, state, &pindex, min_pow_checked)}; | |
+ CheckBlockIndex(); | |
if (!accepted) { | |
return false; | |
-@@ -3893,7 +3917,7 @@ void ChainstateManager::ReportHeadersPresync(const arith_uint256& work, int64_t | |
+@@ -3893,7 +3925,7 @@ void ChainstateManager::ReportHeadersPresync(const arith_uint256& work, int64_t | |
} | |
/** Store block on disk. If dbp is non-nullptr, the file is known to already reside on disk */ | |
-bool Chainstate::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockValidationState& state, CBlockIndex** ppindex, bool fRequested, const FlatFilePos* dbp, bool* fNewBlock, bool min_pow_checked) | |
-+bool AcceptBlock(const std::shared_ptr<const CBlock>& pblock, ChainstateManager& chainman, BlockValidationState& state, CBlockIndex** ppindex, bool fRequested, const FlatFilePos* dbp, bool* fNewBlock, bool min_pow_checked) | |
++bool ChainstateManager::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockValidationState& state, CBlockIndex** ppindex, bool fRequested, const FlatFilePos* dbp, bool* fNewBlock, bool min_pow_checked) | |
{ | |
const CBlock& block = *pblock; | |
-@@ -3903,8 +3927,8 @@ bool Chainstate::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockV | |
+@@ -3903,7 +3935,7 @@ bool Chainstate::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockV | |
CBlockIndex *pindexDummy = nullptr; | |
CBlockIndex *&pindex = ppindex ? *ppindex : pindexDummy; | |
- bool accepted_header{m_chainman.AcceptBlockHeader(block, state, &pindex, min_pow_checked)}; | |
-- CheckBlockIndex(); | |
-+ bool accepted_header{AcceptBlockHeader(block, chainman, state, &pindex, min_pow_checked)}; | |
-+ chainman.CheckBlockIndex(); | |
++ bool accepted_header{AcceptBlockHeader(block, state, &pindex, min_pow_checked)}; | |
+ CheckBlockIndex(); | |
if (!accepted_header) | |
- return false; | |
-@@ -3913,13 +3937,13 @@ bool Chainstate::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockV | |
+@@ -3913,13 +3945,13 @@ bool Chainstate::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockV | |
// process an unrequested block if it's new and has enough work to | |
// advance our tip, and isn't too many blocks ahead. | |
bool fAlreadyHave = pindex->nStatus & BLOCK_HAVE_DATA; | |
- bool fHasMoreOrSameWork = (m_chain.Tip() ? pindex->nChainWork >= m_chain.Tip()->nChainWork : true); | |
-+ bool fHasMoreOrSameWork = (chainman.ActiveChain().Tip() ? pindex->nChainWork >= chainman.ActiveChain().Tip()->nChainWork : true); | |
++ bool fHasMoreOrSameWork = (ActiveTip() ? pindex->nChainWork >= ActiveTip()->nChainWork : true); | |
// Blocks that are too out-of-order needlessly limit the effectiveness of | |
// pruning, because pruning will not delete block files that contain any | |
// blocks which are too close in height to the tip. Apply this test | |
// regardless of whether pruning is enabled; it should generally be safe to | |
// not process unrequested blocks. | |
- bool fTooFarAhead{pindex->nHeight > m_chain.Height() + int(MIN_BLOCKS_TO_KEEP)}; | |
-+ bool fTooFarAhead{pindex->nHeight > chainman.ActiveChain().Height() + int(MIN_BLOCKS_TO_KEEP)}; | |
++ bool fTooFarAhead{pindex->nHeight > ActiveHeight() + int(MIN_BLOCKS_TO_KEEP)}; | |
// TODO: Decouple this function from the block download logic by removing fRequested | |
// This requires some new chain data structure to efficiently look up if a | |
-@@ -3939,41 +3963,48 @@ bool Chainstate::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockV | |
+@@ -3939,13 +3971,13 @@ bool Chainstate::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockV | |
// If our tip is behind, a peer could try to send us | |
// low-work blocks on a fake chain that we would never | |
// request; don't process these. | |
- if (pindex->nChainWork < m_chainman.MinimumChainWork()) return true; | |
-+ if (pindex->nChainWork < chainman.MinimumChainWork()) return true; | |
++ if (pindex->nChainWork < MinimumChainWork()) return true; | |
} | |
- const CChainParams& params{m_chainman.GetParams()}; | |
-+ const CChainParams& params{chainman.GetParams()}; | |
++ const CChainParams& params{GetParams()}; | |
if (!CheckBlock(block, state, params.GetConsensus()) || | |
- !ContextualCheckBlock(block, state, m_chainman, pindex->pprev)) { | |
-+ !ContextualCheckBlock(block, state, chainman, pindex->pprev)) { | |
++ !ContextualCheckBlock(block, state, *this, pindex->pprev)) { | |
if (state.IsInvalid() && state.GetResult() != BlockValidationResult::BLOCK_MUTATED) { | |
pindex->nStatus |= BLOCK_FAILED_VALID; | |
-- m_blockman.m_dirty_blockindex.insert(pindex); | |
-+ chainman.m_blockman.AddDirty(pindex); | |
- } | |
- return error("%s: %s", __func__, state.ToString()); | |
- } | |
+ m_blockman.m_dirty_blockindex.insert(pindex); | |
+@@ -3955,13 +3987,13 @@ bool Chainstate::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockV | |
// Header is valid/has work, merkle tree and segwit merkle tree are good...RELAY NOW | |
// (but if it does not build on our best tip, let the SendMessages loop relay it) | |
- if (!IsInitialBlockDownload() && m_chain.Tip() == pindex->pprev) | |
-+ if (!chainman.ActiveChainstate().IsInitialBlockDownload() && chainman.ActiveChain().Tip() == pindex->pprev) | |
++ if (!ActiveChainstate().IsInitialBlockDownload() && ActiveTip() == pindex->pprev) | |
GetMainSignals().NewPoWValidBlock(pindex, pblock); | |
// Write block to history file | |
if (fNewBlock) *fNewBlock = true; | |
try { | |
- FlatFilePos blockPos{m_blockman.SaveBlockToDisk(block, pindex->nHeight, m_chain, dbp)}; | |
-+ FlatFilePos blockPos{chainman.m_blockman.SaveBlockToDisk(block, pindex->nHeight, dbp)}; | |
++ FlatFilePos blockPos{m_blockman.SaveBlockToDisk(block, pindex->nHeight, dbp)}; | |
if (blockPos.IsNull()) { | |
state.Error(strprintf("%s: Failed to find position to write new block to disk", __func__)); | |
return false; | |
- } | |
-- ReceivedBlockTransactions(block, pindex, blockPos); | |
-+ ReceivedBlockTransactions(block, chainman, pindex, blockPos); | |
- } catch (const std::runtime_error& e) { | |
+@@ -3971,7 +4003,14 @@ bool Chainstate::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockV | |
return AbortNode(state, std::string("System error: ") + e.what()); | |
} | |
@@ -863,23 +741,20 @@ | |
+ // the block files may be pruned, so we can just call this on one | |
+ // chainstate (particularly if we haven't implemented pruning with | |
+ // background validation yet). | |
-+ chainman.ActiveChainstate().FlushStateToDisk(state, FlushStateMode::NONE); | |
++ ActiveChainstate().FlushStateToDisk(state, FlushStateMode::NONE); | |
-- CheckBlockIndex(); | |
-+ chainman.CheckBlockIndex(); | |
+ CheckBlockIndex(); | |
- return true; | |
- } | |
-@@ -3999,7 +4030,7 @@ bool ChainstateManager::ProcessNewBlock(const std::shared_ptr<const CBlock>& blo | |
+@@ -3999,7 +4038,7 @@ bool ChainstateManager::ProcessNewBlock(const std::shared_ptr<const CBlock>& blo | |
bool ret = CheckBlock(*block, state, GetConsensus()); | |
if (ret) { | |
// Store to disk | |
- ret = ActiveChainstate().AcceptBlock(block, state, &pindex, force_processing, nullptr, new_block, min_pow_checked); | |
-+ ret = AcceptBlock(block, *this, state, &pindex, force_processing, nullptr, new_block, min_pow_checked); | |
++ ret = AcceptBlock(block, state, &pindex, force_processing, nullptr, new_block, min_pow_checked); | |
} | |
if (!ret) { | |
GetMainSignals().BlockChecked(*block, state); | |
-@@ -4367,10 +4398,9 @@ bool Chainstate::NeedsRedownload() const | |
+@@ -4367,10 +4406,9 @@ bool Chainstate::NeedsRedownload() const | |
return false; | |
} | |
@@ -891,7 +766,7 @@ | |
setBlockIndexCandidates.clear(); | |
} | |
-@@ -4389,62 +4419,14 @@ bool ChainstateManager::LoadBlockIndex() | |
+@@ -4389,62 +4427,14 @@ bool ChainstateManager::LoadBlockIndex() | |
std::sort(vSortedByHeight.begin(), vSortedByHeight.end(), | |
CBlockIndexHeightOnlyComparator()); | |
@@ -956,7 +831,7 @@ | |
} | |
} | |
if (pindex->nStatus & BLOCK_FAILED_MASK && (!m_best_invalid || pindex->nChainWork > m_best_invalid->nChainWork)) { | |
-@@ -4484,12 +4466,12 @@ bool Chainstate::LoadGenesisBlock() | |
+@@ -4484,12 +4474,12 @@ bool Chainstate::LoadGenesisBlock() | |
try { | |
const CBlock& block = params.GenesisBlock(); | |
@@ -967,11 +842,11 @@ | |
} | |
CBlockIndex* pindex = m_blockman.AddToBlockIndex(block, m_chainman.m_best_header); | |
- ReceivedBlockTransactions(block, pindex, blockPos); | |
-+ ReceivedBlockTransactions(block, m_chainman, pindex, blockPos); | |
++ m_chainman.ReceivedBlockTransactions(block, pindex, blockPos); | |
} catch (const std::runtime_error& e) { | |
return error("%s: failed to write genesis block: %s", __func__, e.what()); | |
} | |
-@@ -4497,18 +4479,16 @@ bool Chainstate::LoadGenesisBlock() | |
+@@ -4497,18 +4487,16 @@ bool Chainstate::LoadGenesisBlock() | |
return true; | |
} | |
@@ -992,16 +867,7 @@ | |
int nLoaded = 0; | |
try { | |
-@@ -4580,7 +4560,7 @@ void Chainstate::LoadExternalBlockFile( | |
- nRewind = blkdat.GetPos(); | |
- | |
- BlockValidationState state; | |
-- if (AcceptBlock(pblock, state, nullptr, true, dbp, nullptr, true)) { | |
-+ if (AcceptBlock(pblock, *this, state, nullptr, true, dbp, nullptr, true)) { | |
- nLoaded++; | |
- } | |
- if (state.IsError()) { | |
-@@ -4594,7 +4574,14 @@ void Chainstate::LoadExternalBlockFile( | |
+@@ -4594,7 +4582,14 @@ void Chainstate::LoadExternalBlockFile( | |
// Activate the genesis block so normal node progress can continue | |
if (hash == params.GetConsensus().hashGenesisBlock) { | |
BlockValidationState state; | |
@@ -1017,7 +883,7 @@ | |
break; | |
} | |
} | |
-@@ -4608,13 +4595,13 @@ void Chainstate::LoadExternalBlockFile( | |
+@@ -4608,13 +4603,13 @@ void Chainstate::LoadExternalBlockFile( | |
// called by concurrent network message processing. but, that is not | |
// reliable for the purpose of pruning while importing. | |
BlockValidationState state; | |
@@ -1033,15 +899,7 @@ | |
if (!blocks_with_unknown_parent) continue; | |
-@@ -4633,14 +4620,14 @@ void Chainstate::LoadExternalBlockFile( | |
- head.ToString()); | |
- LOCK(cs_main); | |
- BlockValidationState dummy; | |
-- if (AcceptBlock(pblockrecursive, dummy, nullptr, true, &it->second, nullptr, true)) { | |
-+ if (AcceptBlock(pblockrecursive, *this, dummy, nullptr, true, &it->second, nullptr, true)) { | |
- nLoaded++; | |
- queue.push_back(pblockrecursive->GetHash()); | |
- } | |
+@@ -4640,7 +4635,7 @@ void Chainstate::LoadExternalBlockFile( | |
} | |
range.first++; | |
blocks_with_unknown_parent->erase(it); | |
@@ -1050,7 +908,7 @@ | |
} | |
} | |
} catch (const std::exception& e) { | |
-@@ -4664,9 +4651,9 @@ void Chainstate::LoadExternalBlockFile( | |
+@@ -4664,9 +4659,9 @@ void Chainstate::LoadExternalBlockFile( | |
LogPrintf("Loaded %i blocks from external file in %dms\n", nLoaded, Ticks<std::chrono::milliseconds>(SteadyClock::now() - start)); | |
} | |
@@ -1062,7 +920,7 @@ | |
return; | |
} | |
-@@ -4675,7 +4662,7 @@ void Chainstate::CheckBlockIndex() | |
+@@ -4675,7 +4670,7 @@ void Chainstate::CheckBlockIndex() | |
// During a reindex, we read the genesis block and call CheckBlockIndex before ActivateBestChain, | |
// so we have the genesis block in m_blockman.m_block_index but no active chain. (A few of the | |
// tests when iterating the block tree require that m_chain has been initialized.) | |
@@ -1071,7 +929,7 @@ | |
assert(m_blockman.m_block_index.size() <= 1); | |
return; | |
} | |
-@@ -4705,12 +4692,12 @@ void Chainstate::CheckBlockIndex() | |
+@@ -4705,12 +4700,12 @@ void Chainstate::CheckBlockIndex() | |
CBlockIndex* pindexFirstNotTransactionsValid = nullptr; // Oldest ancestor of pindex which does not have BLOCK_VALID_TRANSACTIONS (regardless of being valid or not). | |
CBlockIndex* pindexFirstNotChainValid = nullptr; // Oldest ancestor of pindex which does not have BLOCK_VALID_CHAIN (regardless of being valid or not). | |
CBlockIndex* pindexFirstNotScriptsValid = nullptr; // Oldest ancestor of pindex which does not have BLOCK_VALID_SCRIPTS (regardless of being valid or not). | |
@@ -1087,7 +945,7 @@ | |
pindexFirstMissing = pindex; | |
} | |
if (pindexFirstNeverProcessed == nullptr && pindex->nTx == 0) pindexFirstNeverProcessed = pindex; | |
-@@ -4739,8 +4726,8 @@ void Chainstate::CheckBlockIndex() | |
+@@ -4739,8 +4734,8 @@ void Chainstate::CheckBlockIndex() | |
// Begin: actual consistency checks. | |
if (pindex->pprev == nullptr) { | |
// Genesis block checks. | |
@@ -1098,7 +956,7 @@ | |
} | |
if (!pindex->HaveTxsDownloaded()) assert(pindex->nSequenceId <= 0); // nSequenceId can't be set positive for blocks that aren't linked (negative is used for preciousblock) | |
// VALID_TRANSACTIONS is equivalent to nTx > 0 for all nodes (whether or not pruning has occurred). | |
-@@ -4750,7 +4737,13 @@ void Chainstate::CheckBlockIndex() | |
+@@ -4750,7 +4745,13 @@ void Chainstate::CheckBlockIndex() | |
if (!m_blockman.m_have_pruned && !pindex->IsAssumedValid()) { | |
// If we've never pruned, then HAVE_DATA should be equivalent to nTx > 0 | |
assert(!(pindex->nStatus & BLOCK_HAVE_DATA) == (pindex->nTx == 0)); | |
@@ -1113,7 +971,7 @@ | |
} else { | |
// If we have pruned, then we can only say that HAVE_DATA implies nTx > 0 | |
if (pindex->nStatus & BLOCK_HAVE_DATA) assert(pindex->nTx > 0); | |
-@@ -4780,27 +4773,32 @@ void Chainstate::CheckBlockIndex() | |
+@@ -4780,27 +4781,32 @@ void Chainstate::CheckBlockIndex() | |
// Checks for not-invalid blocks. | |
assert((pindex->nStatus & BLOCK_FAILED_MASK) == 0); // The failed mask cannot be set for blocks without invalid parents. | |
} | |
@@ -1165,7 +1023,7 @@ | |
} | |
// Check whether this block is in m_blocks_unlinked. | |
std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeUnlinked = m_blockman.m_blocks_unlinked.equal_range(pindex->pprev); | |
-@@ -4821,18 +4819,23 @@ void Chainstate::CheckBlockIndex() | |
+@@ -4821,18 +4827,23 @@ void Chainstate::CheckBlockIndex() | |
if (pindexFirstMissing == nullptr) assert(!foundInUnlinked); // We aren't missing data for any parent -- cannot be in m_blocks_unlinked. | |
if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) && pindexFirstNeverProcessed == nullptr && pindexFirstMissing != nullptr) { | |
// We HAVE_DATA for this block, have received data for all parents at some point, but we're currently missing data for some parent. | |
@@ -1194,7 +1052,7 @@ | |
} | |
} | |
} | |
-@@ -4859,6 +4862,7 @@ void Chainstate::CheckBlockIndex() | |
+@@ -4859,6 +4870,7 @@ void Chainstate::CheckBlockIndex() | |
if (pindex == pindexFirstNotTransactionsValid) pindexFirstNotTransactionsValid = nullptr; | |
if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid = nullptr; | |
if (pindex == pindexFirstNotScriptsValid) pindexFirstNotScriptsValid = nullptr; | |
@@ -1203,58 +1061,10 @@ | |
CBlockIndex* pindexPar = pindex->pprev; | |
// Find which child we just visited. | |
diff --git a/src/validation.h b/src/validation.h | |
-index cb5b291dab..6df13fdd29 100644 | |
+index cb5b291dab..911d6ef178 100644 | |
--- a/src/validation.h | |
+++ b/src/validation.h | |
-@@ -337,9 +337,46 @@ public: | |
- /** Context-independent validity checks */ | |
- bool CheckBlock(const CBlock& block, BlockValidationState& state, const Consensus::Params& consensusParams, bool fCheckPOW = true, bool fCheckMerkleRoot = true); | |
- | |
-+/** | |
-+ * If a block header hasn't already been seen, call CheckBlockHeader on it, ensure | |
-+ * that it doesn't descend from an invalid block, and then add it to m_block_index. | |
-+ * Caller must set min_pow_checked=true in order to add a new header to the | |
-+ * block index (permanent memory storage), indicating that the header is | |
-+ * known to be part of a sufficiently high-work chain (anti-dos check). | |
-+ */ | |
-+bool AcceptBlockHeader( | |
-+ const CBlockHeader& block, | |
-+ ChainstateManager& chaiman, | |
-+ BlockValidationState& state, | |
-+ CBlockIndex** ppindex, | |
-+ bool min_pow_checked) EXCLUSIVE_LOCKS_REQUIRED(cs_main); | |
-+ | |
-+/** | |
-+ * Sufficiently validate a block for disk storage (and store on disk). | |
-+ * | |
-+ * @param[in] pblock The block we want to process. | |
-+ * @param[in] fRequested Whether we requested this block from a | |
-+ * peer. | |
-+ * @param[in] dbp The location on disk, if we are importing | |
-+ * this block from prior storage. | |
-+ * @param[in] min_pow_checked True if proof-of-work anti-DoS checks have | |
-+ * been done by caller for headers chain | |
-+ * | |
-+ * @param[out] state The state of the block validation. | |
-+ * @param[out] ppindex Optional return parameter to get the | |
-+ * CBlockIndex pointer for this block. | |
-+ * @param[out] fNewBlock Optional return parameter to indicate if the | |
-+ * block is new to our storage. | |
-+ * | |
-+ * @returns False if the block or header is invalid, or if saving to disk fails (likely a fatal error); true otherwise. | |
-+ */ | |
-+bool AcceptBlock(const std::shared_ptr<const CBlock>& pblock, ChainstateManager& chainman, BlockValidationState& state, CBlockIndex** ppindex, bool fRequested, const FlatFilePos* dbp, bool* fNewBlock, bool min_pow_checked) EXCLUSIVE_LOCKS_REQUIRED(cs_main); | |
-+ | |
-+void ReceivedBlockTransactions(const CBlock& block, ChainstateManager& chainman, CBlockIndex* pindexNew, const FlatFilePos& pos) EXCLUSIVE_LOCKS_REQUIRED(cs_main); | |
-+ | |
- /** Check a block is completely valid from start to finish (only works on top of our current best block) */ | |
- bool TestBlockValidity(BlockValidationState& state, | |
-- const CChainParams& chainparams, | |
-+ const CChainParams& chainparams, | |
- Chainstate& chainstate, | |
- const CBlock& block, | |
- CBlockIndex* pindexPrev, | |
-@@ -456,17 +493,6 @@ enum class CoinsCacheSizeState | |
+@@ -456,17 +456,6 @@ enum class CoinsCacheSizeState | |
class Chainstate | |
{ | |
protected: | |
@@ -1272,7 +1082,31 @@ | |
/** | |
* The ChainState Mutex | |
* A lock that must be held when modifying this ChainState - held in ActivateBestChain() and | |
-@@ -611,37 +637,6 @@ public: | |
+@@ -502,6 +491,9 @@ protected: | |
+ //! is set to true on the snapshot chainstate. | |
+ bool m_disabled GUARDED_BY(::cs_main) {false}; | |
+ | |
++ //! Cached result of LookupBlockIndex(*m_from_snapshot_blockhash) | |
++ const CBlockIndex* m_cached_snapshot_base GUARDED_BY(::cs_main) {nullptr}; | |
++ | |
+ public: | |
+ //! Reference to a BlockManager instance which itself is shared across all | |
+ //! Chainstate instances. | |
+@@ -553,6 +545,13 @@ public: | |
+ */ | |
+ const std::optional<uint256> m_from_snapshot_blockhash; | |
+ | |
++ /** | |
++ * The base of the snapshot this chainstate was created from. | |
++ * | |
++ * nullptr if this chainstate was not created from a snapshot. | |
++ */ | |
++ const CBlockIndex* SnapshotBase() EXCLUSIVE_LOCKS_REQUIRED(::cs_main); | |
++ | |
+ //! Return true if this chainstate relies on blocks that are assumed-valid. In | |
+ //! practice this means it was created based on a UTXO snapshot. | |
+ bool reliesOnAssumedValid() { return m_from_snapshot_blockhash.has_value(); } | |
+@@ -611,37 +610,6 @@ public: | |
bool ResizeCoinsCaches(size_t coinstip_size, size_t coinsdb_size) | |
EXCLUSIVE_LOCKS_REQUIRED(::cs_main); | |
@@ -1310,16 +1144,16 @@ | |
/** | |
* Update the on-disk chain state. | |
-@@ -693,8 +688,6 @@ public: | |
+@@ -693,8 +661,6 @@ public: | |
EXCLUSIVE_LOCKS_REQUIRED(!m_chainstate_mutex) | |
LOCKS_EXCLUDED(::cs_main); | |
-- bool AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockValidationState& state, CBlockIndex** ppindex, bool fRequested, const FlatFilePos* dbp, bool* fNewBlock, bool min_pow_checked) EXCLUSIVE_LOCKS_REQUIRED(cs_main); | |
-- | |
+- bool AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockValidationState& state, CBlockIndex** ppindex, bool fRequested, const FlatFilePos* dbp, bool* fNewBlock, bool min_pow_checked) EXCLUSIVE_LOCKS_REQUIRED(cs_main); | |
+- | |
// Block (dis)connection on a given view: | |
DisconnectResult DisconnectBlock(const CBlock& block, const CBlockIndex* pindex, CCoinsViewCache& view) | |
EXCLUSIVE_LOCKS_REQUIRED(::cs_main); | |
-@@ -729,9 +722,11 @@ public: | |
+@@ -729,9 +695,11 @@ public: | |
/** Ensures we have a genesis block in the block tree, possibly writing one to disk. */ | |
bool LoadGenesisBlock(); | |
@@ -1332,7 +1166,7 @@ | |
/** Check whether we are doing an initial block download (synchronizing from disk or network) */ | |
bool IsInitialBlockDownload() const; | |
-@@ -739,13 +734,6 @@ public: | |
+@@ -739,13 +707,6 @@ public: | |
/** Find the last common block of this chain and a locator. */ | |
const CBlockIndex* FindForkInGlobalIndex(const CBlockLocator& locator) const EXCLUSIVE_LOCKS_REQUIRED(cs_main); | |
@@ -1346,34 +1180,15 @@ | |
/** Load the persisted mempool from disk */ | |
void LoadMempool(const fs::path& load_path, fsbridge::FopenFn mockable_fopen_function = fsbridge::fopen); | |
-@@ -775,7 +763,6 @@ private: | |
+@@ -775,7 +736,6 @@ private: | |
void InvalidBlockFound(CBlockIndex* pindex, const BlockValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(cs_main); | |
CBlockIndex* FindMostWorkChain() EXCLUSIVE_LOCKS_REQUIRED(cs_main); | |
-- void ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pindexNew, const FlatFilePos& pos) EXCLUSIVE_LOCKS_REQUIRED(cs_main); | |
+- void ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pindexNew, const FlatFilePos& pos) EXCLUSIVE_LOCKS_REQUIRED(cs_main); | |
bool RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& inputs) EXCLUSIVE_LOCKS_REQUIRED(cs_main); | |
-@@ -914,18 +901,6 @@ private: | |
- AutoFile& coins_file, | |
- const node::SnapshotMetadata& metadata); | |
- | |
-- /** | |
-- * If a block header hasn't already been seen, call CheckBlockHeader on it, ensure | |
-- * that it doesn't descend from an invalid block, and then add it to m_block_index. | |
-- * Caller must set min_pow_checked=true in order to add a new header to the | |
-- * block index (permanent memory storage), indicating that the header is | |
-- * known to be part of a sufficiently high-work chain (anti-dos check). | |
-- */ | |
-- bool AcceptBlockHeader( | |
-- const CBlockHeader& block, | |
-- BlockValidationState& state, | |
-- CBlockIndex** ppindex, | |
-- bool min_pow_checked) EXCLUSIVE_LOCKS_REQUIRED(cs_main); | |
- friend Chainstate; | |
- | |
- /** Most recent headers presync progress update, for rate-limiting. */ | |
-@@ -962,6 +937,13 @@ public: | |
+@@ -962,6 +922,13 @@ public: | |
kernel::Notifications& GetNotifications() const { return m_options.notifications; }; | |
int StopAtHeight() const { return m_options.stop_at_height; }; | |
@@ -1387,7 +1202,7 @@ | |
/** | |
* Alias for ::cs_main. | |
* Should be used in new code to make it easier to make ::cs_main a member | |
-@@ -981,6 +963,25 @@ public: | |
+@@ -981,6 +948,25 @@ public: | |
//! chainstate to avoid duplicating block metadata. | |
node::BlockManager m_blockman; | |
@@ -1413,23 +1228,15 @@ | |
/** | |
* In order to efficiently track invalidity of headers, we keep the set of | |
* blocks which we tried to connect and found to be invalid here (ie which | |
-@@ -1071,6 +1072,12 @@ public: | |
- //! that a background validation chainstate is also in use. | |
- bool IsSnapshotActive() const; | |
+@@ -1079,6 +1065,42 @@ public: | |
+ return m_snapshot_chainstate && m_ibd_chainstate && m_ibd_chainstate->m_disabled; | |
+ } | |
-+ //! @returns true if the chainstate is the background chainstate | |
-+ bool IsBackgroundChainstate(const Chainstate *chainstate) const EXCLUSIVE_LOCKS_REQUIRED(::cs_main) | |
++ const CBlockIndex* ActiveSnapshotBase() const EXCLUSIVE_LOCKS_REQUIRED(::cs_main) | |
+ { | |
-+ return chainstate == m_ibd_chainstate.get(); | |
++ return m_active_chainstate ? m_active_chainstate->SnapshotBase() : nullptr; | |
+ } | |
+ | |
- std::optional<uint256> SnapshotBlockhash() const; | |
- | |
- //! Is there a snapshot in use and has it been fully validated? | |
-@@ -1079,6 +1086,37 @@ public: | |
- return m_snapshot_chainstate && m_ibd_chainstate && m_ibd_chainstate->m_disabled; | |
- } | |
- | |
+ /** | |
+ * Import blocks from an external file | |
+ * | |
@@ -1463,4 +1270,34 @@ | |
+ | |
/** | |
* Process an incoming block. This only returns after the best known valid | |
- * block is made active. Note that it does not, however, guarantee that the | |
\ No newline at end of file | |
+ * block is made active. Note that it does not, however, guarantee that the | |
+@@ -1118,6 +1140,29 @@ public: | |
+ */ | |
+ bool ProcessNewBlockHeaders(const std::vector<CBlockHeader>& block, bool min_pow_checked, BlockValidationState& state, const CBlockIndex** ppindex = nullptr) LOCKS_EXCLUDED(cs_main); | |
+ | |
++ /** | |
++ * Sufficiently validate a block for disk storage (and store on disk). | |
++ * | |
++ * @param[in] pblock The block we want to process. | |
++ * @param[in] fRequested Whether we requested this block from a | |
++ * peer. | |
++ * @param[in] dbp The location on disk, if we are importing | |
++ * this block from prior storage. | |
++ * @param[in] min_pow_checked True if proof-of-work anti-DoS checks have | |
++ * been done by caller for headers chain | |
++ * | |
++ * @param[out] state The state of the block validation. | |
++ * @param[out] ppindex Optional return parameter to get the | |
++ * CBlockIndex pointer for this block. | |
++ * @param[out] fNewBlock Optional return parameter to indicate if the | |
++ * block is new to our storage. | |
++ * | |
++ * @returns False if the block or header is invalid, or if saving to disk fails (likely a fatal error); true otherwise. | |
++ */ | |
++ bool AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockValidationState& state, CBlockIndex** ppindex, bool fRequested, const FlatFilePos* dbp, bool* fNewBlock, bool min_pow_checked) EXCLUSIVE_LOCKS_REQUIRED(cs_main); | |
++ | |
++ void ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pindexNew, const FlatFilePos& pos) EXCLUSIVE_LOCKS_REQUIRED(cs_main); | |
++ | |
+ /** | |
+ * Try to add a transaction to the memory pool. | |
+ * | |
\ No newline at end of file |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment