Skip to content

Commit fd29073

Browse files
theuniryanofsky
andcommitted
validation: clean up and clarify CheckInputScripts logic
CheckInputScripts behaves differently depending on whether or not it was called with a vector for checks. Make this difference clear by calling it differently depending on whether or not control exists. Though more verbose, it should be more straightforward to understand what's happening this way. Also remove parallel_script_checks, as `if(control)` is a better test. Co-authored-by: Ryan Ofsky <ryan@ofsky.org>
1 parent 1a37507 commit fd29073

File tree

1 file changed

+13
-6
lines changed

1 file changed

+13
-6
lines changed

src/validation.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2421,7 +2421,6 @@ bool Chainstate::ConnectBlock(const CBlock& block, BlockValidationState& state,
24212421

24222422
uint256 block_hash{block.GetHash()};
24232423
assert(*pindex->phashBlock == block_hash);
2424-
const bool parallel_script_checks{m_chainman.GetCheckQueue().HasThreads()};
24252424

24262425
const auto time_start{SteadyClock::now()};
24272426
const CChainParams& params{m_chainman.GetParams()};
@@ -2612,7 +2611,7 @@ bool Chainstate::ConnectBlock(const CBlock& block, BlockValidationState& state,
26122611
// doesn't invalidate pointers into the vector, and keep txsdata in scope
26132612
// for as long as `control`.
26142613
std::optional<CCheckQueueControl<CScriptCheck>> control;
2615-
if (fScriptChecks && parallel_script_checks) control.emplace(m_chainman.GetCheckQueue());
2614+
if (auto& queue = m_chainman.GetCheckQueue(); queue.HasThreads() && fScriptChecks) control.emplace(queue);
26162615

26172616
std::vector<PrecomputedTransactionData> txsdata(block.vtx.size());
26182617

@@ -2671,18 +2670,26 @@ bool Chainstate::ConnectBlock(const CBlock& block, BlockValidationState& state,
26712670
break;
26722671
}
26732672

2674-
if (!tx.IsCoinBase())
2673+
if (!tx.IsCoinBase() && fScriptChecks)
26752674
{
2676-
std::vector<CScriptCheck> vChecks;
26772675
bool fCacheResults = fJustCheck; /* Don't cache results if we're actually connecting blocks (still consult the cache, though) */
2676+
bool tx_ok;
26782677
TxValidationState tx_state;
2679-
if (fScriptChecks && !CheckInputScripts(tx, tx_state, view, flags, fCacheResults, fCacheResults, txsdata[i], m_chainman.m_validation_cache, parallel_script_checks ? &vChecks : nullptr)) {
2678+
// If CheckInputScripts is called with a pointer to a checks vector, the resulting checks are appended to it. In that case
2679+
// they need to be added to control which runs them asynchronously. Otherwise, CheckInputScripts runs the checks before returning.
2680+
if (control) {
2681+
std::vector<CScriptCheck> vChecks;
2682+
tx_ok = CheckInputScripts(tx, tx_state, view, flags, fCacheResults, fCacheResults, txsdata[i], m_chainman.m_validation_cache, &vChecks);
2683+
if (tx_ok) control->Add(std::move(vChecks));
2684+
} else {
2685+
tx_ok = CheckInputScripts(tx, tx_state, view, flags, fCacheResults, fCacheResults, txsdata[i], m_chainman.m_validation_cache);
2686+
}
2687+
if (!tx_ok) {
26802688
// Any transaction validation failure in ConnectBlock is a block consensus failure
26812689
state.Invalid(BlockValidationResult::BLOCK_CONSENSUS,
26822690
tx_state.GetRejectReason(), tx_state.GetDebugMessage());
26832691
break;
26842692
}
2685-
if (control) control->Add(std::move(vChecks));
26862693
}
26872694

26882695
CTxUndo undoDummy;

0 commit comments

Comments
 (0)