mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-24 18:23:26 -03:00
[validation] Make script error messages uniform for parallel/single validation
This makes the debug output mostly the same for -par=1 and parallel validation runs. Of course, parallel validation is non-deterministic in what error it may encounter first if there are multiple issues. Also, the way certain script-related and non-script-related checks are performed differs between the two modes still, which may result in discrepancies.
This commit is contained in:
parent
1ac1c33f3f
commit
146a3d5426
9 changed files with 11 additions and 19 deletions
|
@ -403,8 +403,7 @@ void MinerTestingSetup::TestBasicMining(const CScript& scriptPubKey, const std::
|
|||
tx.vout[0].nValue -= LOWFEE;
|
||||
hash = tx.GetHash();
|
||||
AddToMempool(tx_mempool, entry.Fee(LOWFEE).Time(Now<NodeSeconds>()).SpendsCoinbase(false).FromTx(tx));
|
||||
// Should throw block-validation-failed
|
||||
BOOST_CHECK_EXCEPTION(AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey), std::runtime_error, HasReason("block-validation-failed"));
|
||||
BOOST_CHECK_EXCEPTION(AssemblerForTest(tx_mempool).CreateNewBlock(scriptPubKey), std::runtime_error, HasReason("mandatory-script-verify-flag-failed"));
|
||||
|
||||
// Delete the dummy blocks again.
|
||||
while (m_node.chainman->ActiveChain().Tip()->nHeight > nHeight) {
|
||||
|
|
|
@ -2688,8 +2688,7 @@ bool Chainstate::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());
|
||||
LogError("ConnectBlock(): CheckInputScripts on %s failed with %s\n",
|
||||
tx.GetHash().ToString(), state.ToString());
|
||||
LogInfo("Script validation error in block: %s\n", tx_state.GetRejectReason());
|
||||
return false;
|
||||
}
|
||||
control.Add(std::move(vChecks));
|
||||
|
@ -2717,8 +2716,9 @@ bool Chainstate::ConnectBlock(const CBlock& block, BlockValidationState& state,
|
|||
|
||||
auto parallel_result = control.Complete();
|
||||
if (parallel_result.has_value()) {
|
||||
LogPrintf("ERROR: %s: CheckQueue failed\n", __func__);
|
||||
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "block-validation-failed");
|
||||
state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(*parallel_result)));
|
||||
LogInfo("Script validation error in block: %s", state.GetRejectReason());
|
||||
return false;
|
||||
}
|
||||
const auto time_4{SteadyClock::now()};
|
||||
m_chainman.time_verify += time_4 - time_2;
|
||||
|
|
|
@ -88,7 +88,6 @@ class FullBlockTest(BitcoinTestFramework):
|
|||
self.extra_args = [[
|
||||
'-acceptnonstdtxn=1', # This is a consensus block test, we don't care about tx policy
|
||||
'-testactivationheight=bip34@2',
|
||||
'-par=1', # Until https://github.com/bitcoin/bitcoin/issues/30960 is fixed
|
||||
]]
|
||||
|
||||
def run_test(self):
|
||||
|
|
|
@ -87,7 +87,6 @@ class BIP65Test(BitcoinTestFramework):
|
|||
self.noban_tx_relay = True
|
||||
self.extra_args = [[
|
||||
f'-testactivationheight=cltv@{CLTV_HEIGHT}',
|
||||
'-par=1', # Use only one script thread to get the exact reject reason for testing
|
||||
'-acceptnonstdtxn=1', # cltv_invalidate is nonstandard
|
||||
]]
|
||||
self.setup_clean_chain = True
|
||||
|
@ -175,7 +174,7 @@ class BIP65Test(BitcoinTestFramework):
|
|||
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 {expected_cltv_reject_reason}']):
|
||||
with self.nodes[0].assert_debug_log(expected_msgs=[f'Script validation error in block: {expected_cltv_reject_reason}']):
|
||||
peer.send_and_ping(msg_block(block))
|
||||
assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip)
|
||||
peer.sync_with_ping()
|
||||
|
|
|
@ -99,7 +99,6 @@ class BIP68_112_113Test(BitcoinTestFramework):
|
|||
self.noban_tx_relay = True
|
||||
self.extra_args = [[
|
||||
f'-testactivationheight=csv@{CSV_ACTIVATION_HEIGHT}',
|
||||
'-par=1', # Use only one script thread to get the exact reject reason for testing
|
||||
]]
|
||||
self.supports_cli = False
|
||||
|
||||
|
|
|
@ -51,7 +51,6 @@ class BIP66Test(BitcoinTestFramework):
|
|||
self.noban_tx_relay = True
|
||||
self.extra_args = [[
|
||||
f'-testactivationheight=dersig@{DERSIG_HEIGHT}',
|
||||
'-par=1', # Use only one script thread to get the exact log msg for testing
|
||||
]]
|
||||
self.setup_clean_chain = True
|
||||
self.rpc_timeout = 240
|
||||
|
@ -131,7 +130,7 @@ class BIP66Test(BitcoinTestFramework):
|
|||
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 mandatory-script-verify-flag-failed (Non-canonical DER signature)']):
|
||||
with self.nodes[0].assert_debug_log(expected_msgs=[f'Script validation error in block: mandatory-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()
|
||||
|
|
|
@ -57,7 +57,6 @@ class NULLDUMMYTest(BitcoinTestFramework):
|
|||
self.extra_args = [[
|
||||
f'-testactivationheight=segwit@{COINBASE_MATURITY + 5}',
|
||||
'-addresstype=legacy',
|
||||
'-par=1', # Use only one script thread to get the exact reject reason for testing
|
||||
]]
|
||||
|
||||
def create_transaction(self, *, txid, input_details=None, addr, amount, privkey):
|
||||
|
|
|
@ -1285,7 +1285,6 @@ class TaprootTest(BitcoinTestFramework):
|
|||
def set_test_params(self):
|
||||
self.num_nodes = 1
|
||||
self.setup_clean_chain = True
|
||||
self.extra_args = [["-par=1"]]
|
||||
|
||||
def block_submit(self, node, txs, msg, err_msg, cb_pubkey=None, fees=0, sigops_weight=0, witness=False, accept=False):
|
||||
|
||||
|
|
|
@ -214,6 +214,9 @@ class SegWitTest(BitcoinTestFramework):
|
|||
self.noban_tx_relay = True
|
||||
# This test tests SegWit both pre and post-activation, so use the normal BIP9 activation.
|
||||
self.extra_args = [
|
||||
# -par=1 should not affect validation outcome or logging/reported failures. It is kept
|
||||
# here to exercise the code path still (as it is distinct for multithread script
|
||||
# validation).
|
||||
["-acceptnonstdtxn=1", f"-testactivationheight=segwit@{SEGWIT_HEIGHT}", "-par=1"],
|
||||
["-acceptnonstdtxn=0", f"-testactivationheight=segwit@{SEGWIT_HEIGHT}"],
|
||||
]
|
||||
|
@ -507,10 +510,6 @@ class SegWitTest(BitcoinTestFramework):
|
|||
# When the block is serialized without witness, validation fails because the transaction is
|
||||
# invalid (transactions are always validated with SCRIPT_VERIFY_WITNESS so a segwit v0 transaction
|
||||
# without a witness is invalid).
|
||||
# Note: The reject reason for this failure could be
|
||||
# 'block-validation-failed' (if script check threads > 1) or
|
||||
# 'mandatory-script-verify-flag-failed (Witness program was passed an
|
||||
# empty witness)' (otherwise).
|
||||
test_witness_block(self.nodes[0], self.test_node, block, accepted=False, with_witness=False,
|
||||
reason='mandatory-script-verify-flag-failed (Witness program was passed an empty witness)')
|
||||
|
||||
|
@ -1015,7 +1014,7 @@ class SegWitTest(BitcoinTestFramework):
|
|||
tx2.vout.append(CTxOut(tx.vout[0].nValue, CScript([OP_TRUE])))
|
||||
tx2.wit.vtxinwit.extend([CTxInWitness(), CTxInWitness()])
|
||||
tx2.wit.vtxinwit[0].scriptWitness.stack = [CScript([CScriptNum(1)]), CScript([CScriptNum(1)]), witness_script]
|
||||
tx2.wit.vtxinwit[1].scriptWitness.stack = [CScript([OP_TRUE])]
|
||||
tx2.wit.vtxinwit[1].scriptWitness.stack = []
|
||||
|
||||
block = self.build_next_block()
|
||||
self.update_witness_block_with_transactions(block, [tx2])
|
||||
|
|
Loading…
Add table
Reference in a new issue