Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1#!/usr/bin/env python32# Copyright (c) 2021-present The Bitcoin Core developers3# Distributed under the MIT software license, see the accompanying4# file COPYING or http://www.opensource.org/licenses/mit-license.php.5"""6Test mempool acceptance in case of an already known transaction7with identical non-witness data but different witness.8"""10from test_framework.p2p import P2PTxInvStore11from test_framework.script_util import build_malleated_tx_package12from test_framework.test_framework import BitcoinTestFramework13from test_framework.util import (14assert_not_equal,15assert_equal,16)17from test_framework.wallet import (18MiniWallet,19)21class MempoolWtxidTest(BitcoinTestFramework):22def set_test_params(self):23self.num_nodes = 125def run_test(self):26node = self.nodes[0]27mini_wallet = MiniWallet(node)28self.log.info('Start with pre-generated blocks')30assert_equal(node.getmempoolinfo()['size'], 0)32self.log.info("Submit parent with multiple script branches to mempool")34parent = mini_wallet.create_self_transfer()["tx"]35parent_amount = parent.vout[0].nValue - 1000036child_amount = parent_amount - 1000037parent, child_one, child_two = build_malleated_tx_package(38parent=parent,39rebalance_parent_output_amount=parent_amount,40child_amount=child_amount41)43mini_wallet.sendrawtransaction(from_node=node, tx_hex=parent.serialize().hex())45self.generate(node, 1)47peer_wtxid_relay = node.add_p2p_connection(P2PTxInvStore())49assert_equal(child_one.txid_hex, child_two.txid_hex)50assert_not_equal(child_one.wtxid_hex, child_two.wtxid_hex)52self.log.info("Submit child_one to the mempool")53txid_submitted = node.sendrawtransaction(child_one.serialize().hex())54assert_equal(node.getmempoolentry(txid_submitted)['wtxid'], child_one.wtxid_hex)55peer_wtxid_relay.wait_for_broadcast([child_one.wtxid_hex])56assert_equal(node.getmempoolinfo()["unbroadcastcount"], 0)58# testmempoolaccept reports the "already in mempool" error59assert_equal(node.testmempoolaccept([child_one.serialize().hex()]), [{60"txid": child_one.txid_hex,61"wtxid": child_one.wtxid_hex,62"allowed": False,63"reject-reason": "txn-already-in-mempool",64"reject-details": "txn-already-in-mempool"65}])66assert_equal(node.testmempoolaccept([child_two.serialize().hex()])[0], {67"txid": child_two.txid_hex,68"wtxid": child_two.wtxid_hex,69"allowed": False,70"reject-reason": "txn-same-nonwitness-data-in-mempool",71"reject-details": "txn-same-nonwitness-data-in-mempool"72})74# sendrawtransaction will not throw but quits early when the exact same transaction is already in mempool75node.sendrawtransaction(child_one.serialize().hex())77self.log.info("Connect another peer that hasn't seen child_one before")78peer_wtxid_relay_2 = node.add_p2p_connection(P2PTxInvStore())80self.log.info("Submit child_two to the mempool")81# sendrawtransaction will not throw but quits early when a transaction with the same non-witness data is already in mempool82node.sendrawtransaction(child_two.serialize().hex())84# The node should rebroadcast the transaction using the wtxid of the correct transaction85# (child_one, which is in its mempool).86peer_wtxid_relay_2.wait_for_broadcast([child_one.wtxid_hex])87assert_equal(node.getmempoolinfo()["unbroadcastcount"], 0)89if __name__ == '__main__':90MempoolWtxidTest(__file__).main()
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.