diff --git a/src/validation.cpp b/src/validation.cpp index cf41a8aa2d..0b32d0d1ce 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2442,6 +2442,14 @@ bool CheckInputScripts(const CTransaction& tx, TxValidationState& state, if (check2()) { return state.Invalid(TxValidationResult::TX_NOT_STANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(serror))); } + + // If the second check failed, it failed due to a mandatory script verification + // flag, but the first check might have failed on a non-mandatory script + // verification flag. + // + // Avoid reporting a mandatory script check failure with a non-mandatory error + // string by reporting the error from the second check. + serror = check2.GetScriptError(); } // MANDATORY flag failures correspond to // TxValidationResult::TX_CONSENSUS. Because CONSENSUS diff --git a/test/functional/data/invalid_txs.py b/test/functional/data/invalid_txs.py index c677f86e88..eee82f1d4f 100644 --- a/test/functional/data/invalid_txs.py +++ b/test/functional/data/invalid_txs.py @@ -191,7 +191,6 @@ class NonexistentInput(BadTxTemplate): class SpendTooMuch(BadTxTemplate): reject_reason = 'bad-txns-in-ne-out' - block_reject_reason = 'block-validation-failed' expect_disconnect = True def get_tx(self): @@ -268,6 +267,19 @@ def getDisabledOpcodeTemplate(opcode): 'valid_in_block' : True }) +class NonStandardAndInvalid(BadTxTemplate): + """A non-standard transaction which is also consensus-invalid should return the consensus error.""" + reject_reason = "mandatory-script-verify-flag-failed (OP_RETURN was encountered)" + expect_disconnect = True + # ELEMENTS: In the block test context sign_tx() replaces the scriptSig with a valid + # P2PK signature, making this tx valid in a block. Skip the block test. + valid_in_block = True + + def get_tx(self): + return create_tx_with_script( + self.spend_tx, 0, script_sig=b'\x00' * 3 + b'\xab\x6a', + amount=self.spend_avail) + # Disabled opcode tx templates (CVE-2010-5137) # ELEMENTS: many of these are re-enabled DisabledOpcodeTemplates = [getDisabledOpcodeTemplate(opcode) for opcode in [ diff --git a/test/functional/feature_block.py b/test/functional/feature_block.py index 1a2abc7d34..792e2a361d 100755 --- a/test/functional/feature_block.py +++ b/test/functional/feature_block.py @@ -89,6 +89,7 @@ class FullBlockTest(BitcoinTestFramework): '-acceptnonstdtxn=1', # This is a consensus block test, we don't care about tx policy '-testactivationheight=bip34@2', "-con_bip34height=2", # ELEMENTS + '-par=1', # Until https://github.com/bitcoin/bitcoin/issues/30960 is fixed ]] def run_test(self): @@ -821,7 +822,7 @@ class FullBlockTest(BitcoinTestFramework): self.next_block(59) tx = self.create_and_sign_transaction(out[17], 51 * COIN) b59 = self.update_block(59, [tx]) - self.send_blocks([b59], success=False, reject_reason='block-validation-failed', reconnect=True) + self.send_blocks([b59], success=False, reject_reason='bad-txns-in-ne-out', reconnect=True) # reset to good chain self.move_tip(57) diff --git a/test/functional/p2p_invalid_tx.py b/test/functional/p2p_invalid_tx.py index 11164d32cd..8ce5f625be 100755 --- a/test/functional/p2p_invalid_tx.py +++ b/test/functional/p2p_invalid_tx.py @@ -168,7 +168,7 @@ class InvalidTxRequestTest(BitcoinTestFramework): node.p2ps[0].send_txs_and_test([rejected_parent], node, success=False) self.log.info('Test that a peer disconnection causes erase its transactions from the orphan pool') - with node.assert_debug_log(['Erased 100 orphan transaction(s) from peer=15']): + with node.assert_debug_log(['Erased 100 orphan transaction(s) from peer=16']): self.reconnect_p2p(num_connections=1) self.log.info('Test that a transaction in the orphan pool is included in a new tip block causes erase this transaction from the orphan pool')