Skip to content

Commit dbc4425

Browse files
committed
Remove UTXO updates in ConnectBlock
1 parent df101c9 commit dbc4425

File tree

1 file changed

+0
-161
lines changed

1 file changed

+0
-161
lines changed

src/validation.cpp

Lines changed: 0 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -2568,171 +2568,10 @@ bool Chainstate::ConnectBlock(const CBlock& block, BlockValidationState& state,
25682568
m_prev_script_checks_logged = fScriptChecks;
25692569
}
25702570

2571-
CBlockUndo blockundo;
2572-
2573-
// Precomputed transaction data pointers must not be invalidated
2574-
// until after `control` has run the script checks (potentially
2575-
// in multiple threads). Preallocate the vector size so a new allocation
2576-
// doesn't invalidate pointers into the vector, and keep txsdata in scope
2577-
// for as long as `control`.
2578-
std::optional<CCheckQueueControl<CScriptCheck>> control;
2579-
if (auto& queue = m_chainman.GetCheckQueue(); queue.HasThreads() && fScriptChecks) control.emplace(queue);
2580-
2581-
std::vector<PrecomputedTransactionData> txsdata(block.vtx.size());
2582-
2583-
std::vector<int> prevheights;
2584-
CAmount nFees = 0;
2585-
int nInputs = 0;
2586-
int64_t nSigOpsCost = 0;
2587-
blockundo.vtxundo.reserve(block.vtx.size() - 1);
2588-
for (unsigned int i = 0; i < block.vtx.size(); i++)
2589-
{
2590-
if (!state.IsValid()) break;
2591-
const CTransaction &tx = *(block.vtx[i]);
2592-
2593-
nInputs += tx.vin.size();
2594-
2595-
if (!tx.IsCoinBase())
2596-
{
2597-
CAmount txfee = 0;
2598-
TxValidationState tx_state;
2599-
if (!Consensus::CheckTxInputs(tx, tx_state, view, pindex->nHeight, txfee)) {
2600-
// Any transaction validation failure in ConnectBlock is a block consensus failure
2601-
state.Invalid(BlockValidationResult::BLOCK_CONSENSUS,
2602-
tx_state.GetRejectReason(),
2603-
tx_state.GetDebugMessage() + " in transaction " + tx.GetHash().ToString());
2604-
break;
2605-
}
2606-
nFees += txfee;
2607-
if (!MoneyRange(nFees)) {
2608-
state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-txns-accumulated-fee-outofrange",
2609-
"accumulated fee in the block out of range");
2610-
break;
2611-
}
2612-
2613-
// Check that transaction is BIP68 final
2614-
// BIP68 lock checks (as opposed to nLockTime checks) must
2615-
// be in ConnectBlock because they require the UTXO set
2616-
prevheights.resize(tx.vin.size());
2617-
for (size_t j = 0; j < tx.vin.size(); j++) {
2618-
prevheights[j] = view.AccessCoin(tx.vin[j].prevout).nHeight;
2619-
}
2620-
2621-
if (!SequenceLocks(tx, nLockTimeFlags, prevheights, *pindex)) {
2622-
state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-txns-nonfinal",
2623-
"contains a non-BIP68-final transaction " + tx.GetHash().ToString());
2624-
break;
2625-
}
2626-
}
2627-
2628-
// GetTransactionSigOpCost counts 3 types of sigops:
2629-
// * legacy (always)
2630-
// * p2sh (when P2SH enabled in flags and excludes coinbase)
2631-
// * witness (when witness enabled in flags and excludes coinbase)
2632-
nSigOpsCost += GetTransactionSigOpCost(tx, view, flags);
2633-
if (nSigOpsCost > MAX_BLOCK_SIGOPS_COST) {
2634-
state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-blk-sigops", "too many sigops");
2635-
break;
2636-
}
2637-
2638-
if (!tx.IsCoinBase() && fScriptChecks)
2639-
{
2640-
bool fCacheResults = fJustCheck; /* Don't cache results if we're actually connecting blocks (still consult the cache, though) */
2641-
bool tx_ok;
2642-
TxValidationState tx_state;
2643-
// If CheckInputScripts is called with a pointer to a checks vector, the resulting checks are appended to it. In that case
2644-
// they need to be added to control which runs them asynchronously. Otherwise, CheckInputScripts runs the checks before returning.
2645-
if (control) {
2646-
std::vector<CScriptCheck> vChecks;
2647-
tx_ok = CheckInputScripts(tx, tx_state, view, flags, fCacheResults, fCacheResults, txsdata[i], m_chainman.m_validation_cache, &vChecks);
2648-
if (tx_ok) control->Add(std::move(vChecks));
2649-
} else {
2650-
tx_ok = CheckInputScripts(tx, tx_state, view, flags, fCacheResults, fCacheResults, txsdata[i], m_chainman.m_validation_cache);
2651-
}
2652-
if (!tx_ok) {
2653-
// Any transaction validation failure in ConnectBlock is a block consensus failure
2654-
state.Invalid(BlockValidationResult::BLOCK_CONSENSUS,
2655-
tx_state.GetRejectReason(), tx_state.GetDebugMessage());
2656-
break;
2657-
}
2658-
}
2659-
2660-
CTxUndo undoDummy;
2661-
if (i > 0) {
2662-
blockundo.vtxundo.emplace_back();
2663-
}
2664-
UpdateCoins(tx, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->nHeight);
2665-
}
2666-
const auto time_3{SteadyClock::now()};
2667-
m_chainman.time_connect += time_3 - time_2;
2668-
LogDebug(BCLog::BENCH, " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs (%.2fms/blk)]\n", (unsigned)block.vtx.size(),
2669-
Ticks<MillisecondsDouble>(time_3 - time_2), Ticks<MillisecondsDouble>(time_3 - time_2) / block.vtx.size(),
2670-
nInputs <= 1 ? 0 : Ticks<MillisecondsDouble>(time_3 - time_2) / (nInputs - 1),
2671-
Ticks<SecondsDouble>(m_chainman.time_connect),
2672-
Ticks<MillisecondsDouble>(m_chainman.time_connect) / m_chainman.num_blocks_total);
2673-
2674-
CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, params.GetConsensus());
2675-
if (block.vtx[0]->GetValueOut() > blockReward && state.IsValid()) {
2676-
state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-cb-amount",
2677-
strprintf("coinbase pays too much (actual=%d vs limit=%d)", block.vtx[0]->GetValueOut(), blockReward));
2678-
}
2679-
if (control) {
2680-
auto parallel_result = control->Complete();
2681-
if (parallel_result.has_value() && state.IsValid()) {
2682-
state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, strprintf("block-script-verify-flag-failed (%s)", ScriptErrorString(parallel_result->first)), parallel_result->second);
2683-
}
2684-
}
2685-
if (!state.IsValid()) {
2686-
LogInfo("Block validation error: %s", state.ToString());
2687-
return false;
2688-
}
2689-
const auto time_4{SteadyClock::now()};
2690-
m_chainman.time_verify += time_4 - time_2;
2691-
LogDebug(BCLog::BENCH, " - Verify %u txins: %.2fms (%.3fms/txin) [%.2fs (%.2fms/blk)]\n", nInputs - 1,
2692-
Ticks<MillisecondsDouble>(time_4 - time_2),
2693-
nInputs <= 1 ? 0 : Ticks<MillisecondsDouble>(time_4 - time_2) / (nInputs - 1),
2694-
Ticks<SecondsDouble>(m_chainman.time_verify),
2695-
Ticks<MillisecondsDouble>(m_chainman.time_verify) / m_chainman.num_blocks_total);
2696-
2697-
if (fJustCheck) {
2698-
return true;
2699-
}
2700-
2701-
if (!m_blockman.WriteBlockUndo(blockundo, state, *pindex)) {
2702-
return false;
2703-
}
2704-
2705-
const auto time_5{SteadyClock::now()};
2706-
m_chainman.time_undo += time_5 - time_4;
2707-
LogDebug(BCLog::BENCH, " - Write undo data: %.2fms [%.2fs (%.2fms/blk)]\n",
2708-
Ticks<MillisecondsDouble>(time_5 - time_4),
2709-
Ticks<SecondsDouble>(m_chainman.time_undo),
2710-
Ticks<MillisecondsDouble>(m_chainman.time_undo) / m_chainman.num_blocks_total);
2711-
2712-
if (!pindex->IsValid(BLOCK_VALID_SCRIPTS)) {
2713-
pindex->RaiseValidity(BLOCK_VALID_SCRIPTS);
2714-
m_blockman.m_dirty_blockindex.insert(pindex);
2715-
}
27162571

27172572
// add this block to the view's block chain
27182573
view.SetBestBlock(pindex->GetBlockHash());
27192574

2720-
const auto time_6{SteadyClock::now()};
2721-
m_chainman.time_index += time_6 - time_5;
2722-
LogDebug(BCLog::BENCH, " - Index writing: %.2fms [%.2fs (%.2fms/blk)]\n",
2723-
Ticks<MillisecondsDouble>(time_6 - time_5),
2724-
Ticks<SecondsDouble>(m_chainman.time_index),
2725-
Ticks<MillisecondsDouble>(m_chainman.time_index) / m_chainman.num_blocks_total);
2726-
2727-
TRACEPOINT(validation, block_connected,
2728-
block_hash.data(),
2729-
pindex->nHeight,
2730-
block.vtx.size(),
2731-
nInputs,
2732-
nSigOpsCost,
2733-
Ticks<std::chrono::nanoseconds>(time_5 - time_start)
2734-
);
2735-
27362575
return true;
27372576
}
27382577

0 commit comments

Comments
 (0)