diff --git a/src/validation.cpp b/src/validation.cpp index d351937c37..64564dceb0 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2403,8 +2403,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state, for (const auto& tx : block.vtx) { for (size_t o = 0; o < tx->vout.size(); o++) { if (view.HaveCoin(COutPoint(tx->GetHash(), o))) { - LogPrintf("ERROR: ConnectBlock(): tried to overwrite transaction\n"); - return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-txns-BIP30"); + state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-txns-BIP30"); } } } @@ -2463,6 +2462,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state, for (unsigned int i = 0; i < block.vtx.size(); i++) { + if (!state.IsValid()) break; const CTransaction &tx = *(block.vtx[i]); nInputs += tx.vin.size(); @@ -2483,8 +2483,8 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state, control.Add(vChecks); if (!MoneyRange(fee_map)) { - LogPrintf("ERROR: %s: accumulated fee in the block out of range.\n", __func__); - return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-txns-accumulated-fee-outofrange"); + state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-txns-accumulated-fee-outofrange"); + break; } // Check that transaction is BIP68 final @@ -2500,8 +2500,8 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state, } if (!SequenceLocks(tx, nLockTimeFlags, prevheights, *pindex)) { - LogPrintf("ERROR: %s: contains a non-BIP68-final transaction\n", __func__); - return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-txns-nonfinal"); + state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-txns-nonfinal"); + break; } } @@ -2511,8 +2511,8 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state, // * witness (when witness enabled in flags and excludes coinbase) nSigOpsCost += GetTransactionSigOpCost(tx, view, flags); if (nSigOpsCost > MAX_BLOCK_SIGOPS_COST) { - LogPrintf("ERROR: ConnectBlock(): too many sigops\n"); - return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-blk-sigops"); + state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-blk-sigops"); + break; } if (!tx.IsCoinBase()) @@ -2524,8 +2524,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state, // Any transaction validation failure in ConnectBlock is a block consensus failure state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, tx_state.GetRejectReason(), tx_state.GetDebugMessage()); - return error("ConnectBlock(): CheckInputScripts on %s failed with %s", - tx.GetHash().ToString(), state.ToString()); + break; } control.Add(vChecks); } @@ -2542,24 +2541,28 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state, CAmountMap block_reward = fee_map; block_reward[consensusParams.subsidy_asset] += GetBlockSubsidy(pindex->nHeight, consensusParams); - if (!MoneyRange(block_reward)) { - LogPrintf("ERROR: ConnectBlock(): total block reward overflowed\n"); - return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-blockreward-outofrange"); + if (!MoneyRange(block_reward) && state.IsValid()) { + state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-blockreward-outofrange"); } - if (!VerifyCoinbaseAmount(*(block.vtx[0]), block_reward)) { - LogPrintf("ERROR: ConnectBlock(): coinbase pays too much\n"); - return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-cb-amount"); + if (!VerifyCoinbaseAmount(*(block.vtx[0]), block_reward) && state.IsValid()) { + state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-cb-amount"); } - if (!control.Wait()) { - LogPrintf("ERROR: %s: CheckQueue failed\n", __func__); - return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "block-validation-failed"); + if (!control.Wait() && state.IsValid()) { + state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "block-validation-failed"); } + + if (!state.IsValid()) { + LogPrintf("Block validation error: %s", state.ToString()); + return false; + } + int64_t nTime4 = GetTimeMicros(); nTimeVerify += nTime4 - nTime2; LogPrint(BCLog::BENCH, " - Verify %u txins: %.2fms (%.3fms/txin) [%.2fs (%.2fms/blk)]\n", nInputs - 1, MILLI * (nTime4 - nTime2), nInputs <= 1 ? 0 : MILLI * (nTime4 - nTime2) / (nInputs-1), nTimeVerify * MICRO, nTimeVerify * MILLI / nBlocksTotal); - if (fJustCheck) + if (fJustCheck) { return true; + } if (!m_blockman.WriteUndoDataForBlock(blockundo, state, pindex, m_params)) { return false; diff --git a/test/functional/feature_cltv.py b/test/functional/feature_cltv.py index 0f47a1656c..687c7eeb98 100755 --- a/test/functional/feature_cltv.py +++ b/test/functional/feature_cltv.py @@ -175,7 +175,7 @@ def run_test(self): block.hashMerkleRoot = block.calc_merkle_root() block.solve() - with self.nodes[0].assert_debug_log(expected_msgs=[f'CheckInputScripts on {block.vtx[-1].hash} failed with {tx_rej + expected_cltv_reject_reason}']): + with self.nodes[0].assert_debug_log(expected_msgs=[f'Block validation error: mempool-script-verify-flag-failed{expected_cltv_reject_reason}']): peer.send_and_ping(msg_block(block)) assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip) peer.sync_with_ping() diff --git a/test/functional/feature_dersig.py b/test/functional/feature_dersig.py index 52acd2af49..2864226a1c 100755 --- a/test/functional/feature_dersig.py +++ b/test/functional/feature_dersig.py @@ -131,7 +131,7 @@ def run_test(self): block.hashMerkleRoot = block.calc_merkle_root() block.solve() - with self.nodes[0].assert_debug_log(expected_msgs=[f'CheckInputScripts on {block.vtx[-1].hash} failed with mempool-script-verify-flag-failed (Non-canonical DER signature)']): + with self.nodes[0].assert_debug_log(expected_msgs=[f'Block validation error: mempool-script-verify-flag-failed (Non-canonical DER signature)']): peer.send_and_ping(msg_block(block)) assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip) peer.sync_with_ping()