Repository: bitcoin/bitcoin
File: test/functional/mempool_accept.py (Python)

Code before:
        # Note it's only non-witness size that matters!
        assert_equal(len(tx.serialize_without_witness()), 64)
        assert_equal(MIN_STANDARD_TX_NONWITNESS_SIZE - 1, 64)
        assert_greater_than(len(tx.serialize()), 64)

        self.check_mempool_result(
            result_expected=[{'txid': tx.rehash(), 'allowed': False, 'reject-reason': 'tx-size-small'}],
            rawtxs=[tx.serialize().hex()],
            maxfeerate=0,
        )

        self.log.info('Minimally-small transaction(in non-witness bytes) that is allowed')
        tx.vout[0] = CTxOut(COIN - 1000, DUMMY_MIN_OP_RETURN_SCRIPT)
        assert_equal(len(tx.serialize_without_witness()), MIN_STANDARD_TX_NONWITNESS_SIZE)
        self.check_mempool_result(
            result_expected=[{'txid': tx.rehash(), 'allowed': True, 'vsize': tx.get_vsize(), 'fees': { 'base': Decimal('0.00001000')}}],
            rawtxs=[tx.serialize().hex()],
            maxfeerate=0,
        )

        self.log.info('Spending a confirmed bare multisig is okay')
        address = self.wallet.get_address()
        tx = tx_from_hex(raw_tx_reference)
        privkey, pubkey = generate_keypair()
        tx.vout[0].scriptPubKey = keys_to_multisig_script([pubkey] * 3, k=1)  # Some bare multisig script (1-of-3)
        tx.rehash()
        self.generateblock(node, address, [tx.serialize().hex()])
        tx_spend = CTransaction()
        tx_spend.vin.append(CTxIn(COutPoint(tx.sha256, 0), b""))
        tx_spend.vout.append(CTxOut(tx.vout[0].nValue - int(fee*COIN), script_to_p2wsh_script(CScript([OP_TRUE]))))
        tx_spend.rehash()
        sign_input_legacy(tx_spend, 0, tx.vout[0].scriptPubKey, privkey, sighash_type=SIGHASH_ALL)
        tx_spend.vin[0].scriptSig = bytes(CScript([OP_0])) + tx_spend.vin[0].scriptSig
        self.check_mempool_result(
            result_expected=[{'txid': tx_spend.rehash(), 'allowed': True, 'vsize': tx_spend.get_vsize(), 'fees': { 'base': Decimal('0.00000700')}}],
            rawtxs=[tx_spend.serialize().hex()],
            maxfeerate=0,
        )

if __name__ == '__main__':
    MempoolAcceptanceTest(__file__).main()


Review comment (suggestion):
This isn't testing that mempool accepts a tx creating a p2a, assuming that's what you were going for.
Perhaps we want something like this (passes for me on master as well, as expected):
```suggestion
        true_tx = self.wallet.create_self_transfer_multi(sequence=SEQUENCE_FINAL, num_outputs=2)['tx']
        true_tx.vout[0].scriptPubKey = bytes(PAY_TO_ANCHOR)
        node.sendrawtransaction(true_tx.serialize().hex()
        self.generate(node, 1)
```

Code after:
        tx.vout.append(CTxOut(0, CScript([OP_RETURN] + ([OP_0] * (MIN_PADDING - 2)))))
        # Note it's only non-witness size that matters!
        assert_equal(len(tx.serialize_without_witness()), 64)
        assert_equal(MIN_STANDARD_TX_NONWITNESS_SIZE - 1, 64)
        assert_greater_than(len(tx.serialize()), 64)

        self.check_mempool_result(
            result_expected=[{'txid': tx.rehash(), 'allowed': False, 'reject-reason': 'tx-size-small'}],
            rawtxs=[tx.serialize().hex()],
            maxfeerate=0,
        )

        self.log.info('Minimally-small transaction(in non-witness bytes) that is allowed')
        tx.vout[0] = CTxOut(COIN - 1000, DUMMY_MIN_OP_RETURN_SCRIPT)
        assert_equal(len(tx.serialize_without_witness()), MIN_STANDARD_TX_NONWITNESS_SIZE)
        self.check_mempool_result(
            result_expected=[{'txid': tx.rehash(), 'allowed': True, 'vsize': tx.get_vsize(), 'fees': { 'base': Decimal('0.00001000')}}],
            rawtxs=[tx.serialize().hex()],
            maxfeerate=0,
        )

        self.log.info('OP_1 <0x4e73> is able to be created and spent')
        anchor_value = 10000
        create_anchor_tx = self.wallet.send_to(from_node=node, scriptPubKey=PAY_TO_ANCHOR, amount=anchor_value)
        self.generate(node, 1)

        # First spend has non-empty witness, will be rejected to prevent third party wtxid malleability
        anchor_nonempty_wit_spend = CTransaction()
        anchor_nonempty_wit_spend.vin.append(CTxIn(COutPoint(int(create_anchor_tx["txid"], 16), create_anchor_tx["sent_vout"]), b""))
        anchor_nonempty_wit_spend.vout.append(CTxOut(anchor_value - int(fee*COIN), script_to_p2wsh_script(CScript([OP_TRUE]))))
        anchor_nonempty_wit_spend.wit.vtxinwit.append(CTxInWitness())
        anchor_nonempty_wit_spend.wit.vtxinwit[0].scriptWitness.stack.append(b"f")
        anchor_nonempty_wit_spend.rehash()

        self.check_mempool_result(
            result_expected=[{'txid': anchor_nonempty_wit_spend.rehash(), 'allowed': False, 'reject-reason': 'bad-witness-nonstandard'}],
            rawtxs=[anchor_nonempty_wit_spend.serialize().hex()],
            maxfeerate=0,
        )

        # Clear witness stuffing
        anchor_spend = anchor_nonempty_wit_spend
        anchor_spend.wit.vtxinwit[0].scriptWitness.stack = []
        anchor_spend.rehash()

        self.check_mempool_result(
            result_expected=[{'txid': anchor_spend.rehash(), 'allowed': True, 'vsize': anchor_spend.get_vsize(), 'fees': { 'base': Decimal('0.00000700')}}],
            rawtxs=[anchor_spend.serialize().hex()],
            maxfeerate=0,
        )