It is my understanding that the feature_block.py test suites turns on -acceptnonstdtxn=1 which turns off this policy check. Thus we don’t receive any error message when submitting the transaction to the mempool.
I assume you are referring to the functional test p2p_invalid_tx.py rather than feature_block.py, as the latter only sends blocks to the node rather than individual txs? Specifying the error message as reject_reason (meaning the invalid tx case is used to test both via block and individual tx submission) seems to work after increasing the tx size, in order to avoid a “tx-size-small” rejection:
0diff --git a/test/functional/data/invalid_txs.py b/test/functional/data/invalid_txs.py
1index db8871e001..d128ac1682 100644
2--- a/test/functional/data/invalid_txs.py
3+++ b/test/functional/data/invalid_txs.py
4@@ -135,14 +135,13 @@ class SizeTooSmall(BadTxTemplate):
5 # reject a transaction that contains a witness
6 # but doesnt spend a segwit output
7 class ExtraWitness(BadTxTemplate):
8- expect_disconnect = False
9- valid_in_block = False
10- block_reject_reason = "mandatory-script-verify-flag-failed (Witness provided for non-witness script)"
11+ expect_disconnect = True
12+ reject_reason = "mandatory-script-verify-flag-failed (Witness provided for non-witness script)"
13
14 def get_tx(self):
15 tx = CTransaction()
16 tx.vin.append(self.valid_txin)
17- tx.vout.append(CTxOut(0, CScript()))
18+ tx.vout.append(CTxOut(0, basic_p2sh))
19 tx.wit.vtxinwit = [CTxInWitness()]
20 tx.wit.vtxinwit[0].scriptWitness.stack = [CScript([OP_TRUE])]
21 return tx
22diff --git a/test/functional/p2p_invalid_tx.py b/test/functional/p2p_invalid_tx.py
23index ae9771e7cb..b1979cc76d 100755
24--- a/test/functional/p2p_invalid_tx.py
25+++ b/test/functional/p2p_invalid_tx.py
26@@ -160,7 +160,7 @@ class InvalidTxRequestTest(BitcoinTestFramework):
27 node.p2ps[0].send_txs_and_test([rejected_parent], node, success=False)
28
29 self.log.info('Test that a peer disconnection causes erase its transactions from the orphan pool')
30- with node.assert_debug_log(['Erased 100 orphan transaction(s) from peer=26']):
31+ with node.assert_debug_log(['Erased 100 orphan transaction(s) from peer=27']):
32 self.reconnect_p2p(num_connections=1)
33
34 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')
In general, I think only specifying a block_reject_reason rarely makes sense, as a consensus-invalid tx is usually also rejected by mempool. The only exception I could think of is txs that land in the orphanage due to missing inputs. Currently that’s the case for the invalid tx classes BadInputOutpointIndex and NonexistentInput.