diff --git a/test/functional/mempool_accept.py b/test/functional/mempool_accept.py index f4b21cd2044..a4dfda84438 100755 --- a/test/functional/mempool_accept.py +++ b/test/functional/mempool_accept.py @@ -9,6 +9,7 @@ from decimal import Decimal import math from test_framework.test_framework import BitcoinTestFramework +from test_framework.blocktools import MAX_STANDARD_TX_WEIGHT from test_framework.messages import ( MAX_BIP125_RBF_SEQUENCE, COIN, @@ -327,6 +328,52 @@ class MempoolAcceptanceTest(BitcoinTestFramework): rawtxs=[tx.serialize().hex()], ) + # OP_RETURN followed by non-push + tx = tx_from_hex(raw_tx_reference) + tx.vout[0].scriptPubKey = CScript([OP_RETURN, OP_HASH160]) + tx.vout = [tx.vout[0]] * 2 + self.check_mempool_result( + result_expected=[{'txid': tx.rehash(), 'allowed': False, 'reject-reason': 'scriptpubkey'}], + rawtxs=[tx.serialize().hex()], + ) + + # Multiple OP_RETURN and more than 83 bytes are standard since v30 + tx = tx_from_hex(raw_tx_reference) + tx.vout.append(CTxOut(0, CScript([OP_RETURN, b'\xff']))) + tx.vout.append(CTxOut(0, CScript([OP_RETURN, b'\xff' * 90]))) + + self.check_mempool_result( + result_expected=[{'txid': tx.rehash(), 'allowed': True, 'vsize': tx.get_vsize(), 'fees': {'base': Decimal('0.05')}}], + rawtxs=[tx.serialize().hex()], + maxfeerate=0 + ) + + self.log.info("A transaction with several OP_RETURN outputs.") + tx = tx_from_hex(raw_tx_reference) + op_return_count = 42 + tx.vout[0].nValue = int(tx.vout[0].nValue / op_return_count) + tx.vout[0].scriptPubKey = CScript([OP_RETURN, b'\xff']) + tx.vout = [tx.vout[0]] * op_return_count + self.check_mempool_result( + result_expected=[{"txid": tx.rehash(), "allowed": True, "vsize": tx.get_vsize(), "fees": {"base": Decimal("0.05000026")}}], + rawtxs=[tx.serialize().hex()], + ) + + self.log.info("A transaction with an OP_RETUN output that bumps into the max standardness tx size.") + tx = tx_from_hex(raw_tx_reference) + tx.vout[0].scriptPubKey = CScript([OP_RETURN]) + data_len = int(MAX_STANDARD_TX_WEIGHT / 4) - tx.get_vsize() - 5 - 4 # -5 for PUSHDATA4 and -4 for script size + tx.vout[0].scriptPubKey = CScript([OP_RETURN, b"\xff" * (data_len)]) + self.check_mempool_result( + result_expected=[{"txid": tx.rehash(), "allowed": True, "vsize": tx.get_vsize(), "fees": {"base": Decimal("0.1") - Decimal("0.05")}}], + rawtxs=[tx.serialize().hex()], + ) + tx.vout[0].scriptPubKey = CScript([OP_RETURN, b"\xff" * (data_len + 1)]) + self.check_mempool_result( + result_expected=[{"txid": tx.rehash(), "allowed": False, "reject-reason": "tx-size"}], + rawtxs=[tx.serialize().hex()], + ) + self.log.info('A timelocked transaction') tx = tx_from_hex(raw_tx_reference) tx.vin[0].nSequence -= 1 # Should be non-max, so locktime is not ignored