mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-20 07:09:15 +01:00
Merge bitcoin/bitcoin#25704: refactor: Remove almost all validation option globals
aaaa7bd0baiwyu: Add missing includes (MacroFake)fa9ebec096Remove g_parallel_script_checks (MacroFake)fa7c834b9fMove ::fCheckBlockIndex into ChainstateManager (MacroFake)fa43188d86Move ::fCheckpointsEnabled into ChainstateManager (MacroFake)cccca83099Move ::nMinimumChainWork into ChainstateManager (MacroFake)fa29d0b57cMove ::hashAssumeValid into ChainstateManager (MacroFake)faf44876dbMove ::nMaxTipAge into ChainstateManager (MacroFake) Pull request description: It seems preferable to assign globals to a class (in this case `ChainstateManager`), than to leave them dangling. This should clarify scope for code-readers, as well as clarifying unit test behaviour. ACKs for top commit: dergoegge: Code review ACKaaaa7bd0baryanofsky: Code review ACKaaaa7bd0ba. No changes since last review, other than rebase aureleoules: reACKaaaa7bd0baTree-SHA512: 83ec3ba0fb4f1dad95810d4bd4e578454e0718dc1bdd3a794cc4e48aa819b6f5dad4ac4edab3719bdfd5f89cbe23c2740a50fd56c1ff81c99e521c5f6d4e898d
This commit is contained in:
@@ -120,13 +120,6 @@ RecursiveMutex cs_main;
|
||||
GlobalMutex g_best_block_mutex;
|
||||
std::condition_variable g_best_block_cv;
|
||||
uint256 g_best_block;
|
||||
bool g_parallel_script_checks{false};
|
||||
bool fCheckBlockIndex = false;
|
||||
bool fCheckpointsEnabled = DEFAULT_CHECKPOINTS_ENABLED;
|
||||
int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE;
|
||||
|
||||
uint256 hashAssumeValid;
|
||||
arith_uint256 nMinimumChainWork;
|
||||
|
||||
const CBlockIndex* Chainstate::FindForkInGlobalIndex(const CBlockLocator& locator) const
|
||||
{
|
||||
@@ -1545,10 +1538,12 @@ bool Chainstate::IsInitialBlockDownload() const
|
||||
return true;
|
||||
if (m_chain.Tip() == nullptr)
|
||||
return true;
|
||||
if (m_chain.Tip()->nChainWork < nMinimumChainWork)
|
||||
if (m_chain.Tip()->nChainWork < m_chainman.MinimumChainWork()) {
|
||||
return true;
|
||||
if (m_chain.Tip()->GetBlockTime() < (GetTime() - nMaxTipAge))
|
||||
}
|
||||
if (m_chain.Tip()->Time() < NodeClock::now() - m_chainman.m_options.max_tip_age) {
|
||||
return true;
|
||||
}
|
||||
LogPrintf("Leaving InitialBlockDownload (latching to false)\n");
|
||||
m_cached_finished_ibd.store(true, std::memory_order_relaxed);
|
||||
return false;
|
||||
@@ -1994,6 +1989,7 @@ bool Chainstate::ConnectBlock(const CBlock& block, BlockValidationState& state,
|
||||
|
||||
uint256 block_hash{block.GetHash()};
|
||||
assert(*pindex->phashBlock == block_hash);
|
||||
const bool parallel_script_checks{scriptcheckqueue.HasThreads()};
|
||||
|
||||
const auto time_start{SteadyClock::now()};
|
||||
const CChainParams& params{m_chainman.GetParams()};
|
||||
@@ -2036,17 +2032,17 @@ bool Chainstate::ConnectBlock(const CBlock& block, BlockValidationState& state,
|
||||
}
|
||||
|
||||
bool fScriptChecks = true;
|
||||
if (!hashAssumeValid.IsNull()) {
|
||||
if (!m_chainman.AssumedValidBlock().IsNull()) {
|
||||
// We've been configured with the hash of a block which has been externally verified to have a valid history.
|
||||
// A suitable default value is included with the software and updated from time to time. Because validity
|
||||
// relative to a piece of software is an objective fact these defaults can be easily reviewed.
|
||||
// This setting doesn't force the selection of any particular chain but makes validating some faster by
|
||||
// effectively caching the result of part of the verification.
|
||||
BlockMap::const_iterator it = m_blockman.m_block_index.find(hashAssumeValid);
|
||||
BlockMap::const_iterator it{m_blockman.m_block_index.find(m_chainman.AssumedValidBlock())};
|
||||
if (it != m_blockman.m_block_index.end()) {
|
||||
if (it->second.GetAncestor(pindex->nHeight) == pindex &&
|
||||
m_chainman.m_best_header->GetAncestor(pindex->nHeight) == pindex &&
|
||||
m_chainman.m_best_header->nChainWork >= nMinimumChainWork) {
|
||||
m_chainman.m_best_header->nChainWork >= m_chainman.MinimumChainWork()) {
|
||||
// This block is a member of the assumed verified chain and an ancestor of the best header.
|
||||
// Script verification is skipped when connecting blocks under the
|
||||
// assumevalid block. Assuming the assumevalid block is valid this
|
||||
@@ -2059,7 +2055,7 @@ bool Chainstate::ConnectBlock(const CBlock& block, BlockValidationState& state,
|
||||
// it hard to hide the implication of the demand. This also avoids having release candidates
|
||||
// that are hardly doing any signature verification at all in testing without having to
|
||||
// artificially set the default assumed verified block further back.
|
||||
// The test against nMinimumChainWork prevents the skipping when denied access to any chain at
|
||||
// The test against the minimum chain work prevents the skipping when denied access to any chain at
|
||||
// least as good as the expected chain.
|
||||
fScriptChecks = (GetBlockProofEquivalentTime(*m_chainman.m_best_header, *pindex, *m_chainman.m_best_header, params.GetConsensus()) <= 60 * 60 * 24 * 7 * 2);
|
||||
}
|
||||
@@ -2183,7 +2179,7 @@ bool Chainstate::ConnectBlock(const CBlock& block, BlockValidationState& state,
|
||||
// in multiple threads). Preallocate the vector size so a new allocation
|
||||
// doesn't invalidate pointers into the vector, and keep txsdata in scope
|
||||
// for as long as `control`.
|
||||
CCheckQueueControl<CScriptCheck> control(fScriptChecks && g_parallel_script_checks ? &scriptcheckqueue : nullptr);
|
||||
CCheckQueueControl<CScriptCheck> control(fScriptChecks && parallel_script_checks ? &scriptcheckqueue : nullptr);
|
||||
std::vector<PrecomputedTransactionData> txsdata(block.vtx.size());
|
||||
|
||||
std::vector<int> prevheights;
|
||||
@@ -2242,7 +2238,7 @@ bool Chainstate::ConnectBlock(const CBlock& block, BlockValidationState& state,
|
||||
std::vector<CScriptCheck> vChecks;
|
||||
bool fCacheResults = fJustCheck; /* Don't cache results if we're actually connecting blocks (still consult the cache, though) */
|
||||
TxValidationState tx_state;
|
||||
if (fScriptChecks && !CheckInputScripts(tx, tx_state, view, flags, fCacheResults, fCacheResults, txsdata[i], g_parallel_script_checks ? &vChecks : nullptr)) {
|
||||
if (fScriptChecks && !CheckInputScripts(tx, tx_state, view, flags, fCacheResults, fCacheResults, txsdata[i], parallel_script_checks ? &vChecks : nullptr)) {
|
||||
// Any transaction validation failure in ConnectBlock is a block consensus failure
|
||||
state.Invalid(BlockValidationResult::BLOCK_CONSENSUS,
|
||||
tx_state.GetRejectReason(), tx_state.GetDebugMessage());
|
||||
@@ -3532,7 +3528,7 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidatio
|
||||
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "bad-diffbits", "incorrect proof of work");
|
||||
|
||||
// Check against checkpoints
|
||||
if (fCheckpointsEnabled) {
|
||||
if (chainman.m_options.checkpoints_enabled) {
|
||||
// Don't accept any forks from the main chain prior to last checkpoint.
|
||||
// GetLastCheckpoint finds the last checkpoint in MapCheckpoints that's in our
|
||||
// BlockIndex().
|
||||
@@ -3846,7 +3842,7 @@ 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 < nMinimumChainWork) return true;
|
||||
if (pindex->nChainWork < m_chainman.MinimumChainWork()) return true;
|
||||
}
|
||||
|
||||
const CChainParams& params{m_chainman.GetParams()};
|
||||
@@ -4517,7 +4513,7 @@ void Chainstate::LoadExternalBlockFile(
|
||||
|
||||
void Chainstate::CheckBlockIndex()
|
||||
{
|
||||
if (!fCheckBlockIndex) {
|
||||
if (!m_chainman.ShouldCheckBlockIndex()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -5251,6 +5247,22 @@ void ChainstateManager::ResetChainstates()
|
||||
m_active_chainstate = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply default chain params to nullopt members.
|
||||
* This helps to avoid coding errors around the accidental use of the compare
|
||||
* operators that accept nullopt, thus ignoring the intended default value.
|
||||
*/
|
||||
static ChainstateManager::Options&& Flatten(ChainstateManager::Options&& opts)
|
||||
{
|
||||
if (!opts.check_block_index.has_value()) opts.check_block_index = opts.chainparams.DefaultConsistencyChecks();
|
||||
if (!opts.minimum_chain_work.has_value()) opts.minimum_chain_work = UintToArith256(opts.chainparams.GetConsensus().nMinimumChainWork);
|
||||
if (!opts.assumed_valid_block.has_value()) opts.assumed_valid_block = opts.chainparams.GetConsensus().defaultAssumeValid;
|
||||
Assert(opts.adjusted_time_callback);
|
||||
return std::move(opts);
|
||||
}
|
||||
|
||||
ChainstateManager::ChainstateManager(Options options) : m_options{Flatten(std::move(options))} {}
|
||||
|
||||
ChainstateManager::~ChainstateManager()
|
||||
{
|
||||
LOCK(::cs_main);
|
||||
|
||||
Reference in New Issue
Block a user