mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 04:22:55 +01:00
perf: pass around a cached block hash during block validation (#5613)
this change saw a ~38% performance improvement in header sync reindex reproduce via `time ./src/qt/dash-qt --nowallet --testnet --reindex --stopatheight=5` On Develop this took average of 1:48 to finish, on this branch it took 1:07 ## Issue being fixed or feature implemented Slow header / block validation ## What was done? Pass around cached block hash ## How Has This Been Tested? Reindexed testnet ## Breaking Changes None ## Checklist: _Go over all the following points, and put an `x` in all the boxes that apply._ - [x] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have added or updated relevant unit/integration/functional/e2e tests - [ ] I have made corresponding changes to the documentation - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_ Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
This commit is contained in:
parent
13b99e2401
commit
7ad7cbf98a
@ -3566,13 +3566,12 @@ void CChainState::ResetBlockFailureFlags(CBlockIndex *pindex) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CBlockIndex* BlockManager::AddToBlockIndex(const CBlockHeader& block, enum BlockStatus nStatus)
|
CBlockIndex* BlockManager::AddToBlockIndex(const CBlockHeader& block, const uint256& hash, enum BlockStatus nStatus)
|
||||||
{
|
{
|
||||||
assert(!(nStatus & BLOCK_FAILED_MASK)); // no failed blocks allowed
|
assert(!(nStatus & BLOCK_FAILED_MASK)); // no failed blocks allowed
|
||||||
AssertLockHeld(cs_main);
|
AssertLockHeld(cs_main);
|
||||||
|
|
||||||
// Check for duplicate
|
// Check for duplicate
|
||||||
uint256 hash = block.GetHash();
|
|
||||||
BlockMap::iterator it = m_block_index.find(hash);
|
BlockMap::iterator it = m_block_index.find(hash);
|
||||||
if (it != m_block_index.end())
|
if (it != m_block_index.end())
|
||||||
return it->second;
|
return it->second;
|
||||||
@ -3737,16 +3736,16 @@ static bool FindUndoPos(BlockValidationState &state, int nFile, FlatFilePos &pos
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool CheckBlockHeader(const CBlockHeader& block, BlockValidationState& state, const Consensus::Params& consensusParams, bool fCheckPOW = true)
|
static bool CheckBlockHeader(const CBlockHeader& block, const uint256& hash, BlockValidationState& state, const Consensus::Params& consensusParams, bool fCheckPOW = true)
|
||||||
{
|
{
|
||||||
// Check proof of work matches claimed amount
|
// Check proof of work matches claimed amount
|
||||||
if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits, consensusParams))
|
if (fCheckPOW && !CheckProofOfWork(hash, block.nBits, consensusParams))
|
||||||
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "high-hash", "proof of work failed");
|
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "high-hash", "proof of work failed");
|
||||||
|
|
||||||
// Check DevNet
|
// Check DevNet
|
||||||
if (!consensusParams.hashDevnetGenesisBlock.IsNull() &&
|
if (!consensusParams.hashDevnetGenesisBlock.IsNull() &&
|
||||||
block.hashPrevBlock == consensusParams.hashGenesisBlock &&
|
block.hashPrevBlock == consensusParams.hashGenesisBlock &&
|
||||||
block.GetHash() != consensusParams.hashDevnetGenesisBlock) {
|
hash != consensusParams.hashDevnetGenesisBlock) {
|
||||||
LogPrintf("ERROR: CheckBlockHeader(): wrong devnet genesis\n");
|
LogPrintf("ERROR: CheckBlockHeader(): wrong devnet genesis\n");
|
||||||
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "devnet-genesis");
|
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "devnet-genesis");
|
||||||
}
|
}
|
||||||
@ -3765,7 +3764,7 @@ bool CheckBlock(const CBlock& block, BlockValidationState& state, const Consensu
|
|||||||
|
|
||||||
// Check that the header is valid (particularly PoW). This is mostly
|
// Check that the header is valid (particularly PoW). This is mostly
|
||||||
// redundant with the call in AcceptBlockHeader.
|
// redundant with the call in AcceptBlockHeader.
|
||||||
if (!CheckBlockHeader(block, state, consensusParams, fCheckPOW))
|
if (!CheckBlockHeader(block, block.GetHash(), state, consensusParams, fCheckPOW))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Check the merkle root.
|
// Check the merkle root.
|
||||||
@ -4005,7 +4004,7 @@ bool BlockManager::AcceptBlockHeader(const CBlockHeader& block, BlockValidationS
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CheckBlockHeader(block, state, chainparams.GetConsensus())) {
|
if (!CheckBlockHeader(block, hash, state, chainparams.GetConsensus())) {
|
||||||
LogPrint(BCLog::VALIDATION, "%s: Consensus::CheckBlockHeader: %s, %s\n", __func__, hash.ToString(), state.ToString());
|
LogPrint(BCLog::VALIDATION, "%s: Consensus::CheckBlockHeader: %s, %s\n", __func__, hash.ToString(), state.ToString());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -4075,14 +4074,14 @@ bool BlockManager::AcceptBlockHeader(const CBlockHeader& block, BlockValidationS
|
|||||||
|
|
||||||
if (llmq::chainLocksHandler->HasConflictingChainLock(pindexPrev->nHeight + 1, hash)) {
|
if (llmq::chainLocksHandler->HasConflictingChainLock(pindexPrev->nHeight + 1, hash)) {
|
||||||
if (pindex == nullptr) {
|
if (pindex == nullptr) {
|
||||||
AddToBlockIndex(block, BLOCK_CONFLICT_CHAINLOCK);
|
AddToBlockIndex(block, hash, BLOCK_CONFLICT_CHAINLOCK);
|
||||||
}
|
}
|
||||||
LogPrintf("ERROR: %s: header %s conflicts with chainlock\n", __func__, hash.ToString());
|
LogPrintf("ERROR: %s: header %s conflicts with chainlock\n", __func__, hash.ToString());
|
||||||
return state.Invalid(BlockValidationResult::BLOCK_CHAINLOCK, "bad-chainlock");
|
return state.Invalid(BlockValidationResult::BLOCK_CHAINLOCK, "bad-chainlock");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pindex == nullptr)
|
if (pindex == nullptr)
|
||||||
pindex = AddToBlockIndex(block);
|
pindex = AddToBlockIndex(block, hash);
|
||||||
|
|
||||||
if (ppindex)
|
if (ppindex)
|
||||||
*ppindex = pindex;
|
*ppindex = pindex;
|
||||||
@ -5058,7 +5057,7 @@ bool CChainState::AddGenesisBlock(const CBlock& block, BlockValidationState& sta
|
|||||||
FlatFilePos blockPos = SaveBlockToDisk(block, 0, m_chain, m_params, nullptr);
|
FlatFilePos blockPos = SaveBlockToDisk(block, 0, m_chain, m_params, nullptr);
|
||||||
if (blockPos.IsNull())
|
if (blockPos.IsNull())
|
||||||
return error("%s: writing genesis block to disk failed (%s)", __func__, state.ToString());
|
return error("%s: writing genesis block to disk failed (%s)", __func__, state.ToString());
|
||||||
CBlockIndex* pindex = m_blockman.AddToBlockIndex(block);
|
CBlockIndex* pindex = m_blockman.AddToBlockIndex(block, block.GetHash());
|
||||||
ReceivedBlockTransactions(block, pindex, blockPos);
|
ReceivedBlockTransactions(block, pindex, blockPos);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -447,7 +447,7 @@ public:
|
|||||||
/** Clear all data members. */
|
/** Clear all data members. */
|
||||||
void Unload() EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
void Unload() EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||||
|
|
||||||
CBlockIndex* AddToBlockIndex(const CBlockHeader& block, enum BlockStatus nStatus = BLOCK_VALID_TREE) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
CBlockIndex* AddToBlockIndex(const CBlockHeader& block, const uint256& hash, enum BlockStatus nStatus = BLOCK_VALID_TREE) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||||
/** Create a new block index entry for a given block hash */
|
/** Create a new block index entry for a given block hash */
|
||||||
CBlockIndex* InsertBlockIndex(const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
CBlockIndex* InsertBlockIndex(const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user