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) 2017-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"""Test that mempool.dat is both backward and forward compatible between versions7NOTE: The test is designed to prevent cases when compatibility is broken accidentally.8In case we need to break mempool compatibility we can continue to use the test by just bumping the version number.10Previous releases are required by this test, see test/README.md.11"""13from test_framework.blocktools import COINBASE_MATURITY14from test_framework.test_framework import BitcoinTestFramework15from test_framework.wallet import (16MiniWallet,17MiniWalletMode,18)21class MempoolCompatibilityTest(BitcoinTestFramework):22def set_test_params(self):23self.num_nodes = 224self.setup_clean_chain = True26def skip_test_if_missing_module(self):27self.skip_if_no_previous_releases()29def setup_network(self):30self.add_nodes(self.num_nodes, versions=[31200100, # Last release without unbroadcast serialization and without XOR32None,33])34self.start_nodes()36def run_test(self):37self.log.info("Test that mempool.dat is compatible between versions")39old_node, new_node = self.nodes40assert "unbroadcastcount" not in old_node.getmempoolinfo()41new_wallet = MiniWallet(new_node, mode=MiniWalletMode.RAW_P2PK)42self.generate(new_wallet, 1, sync_fun=self.no_op)43self.generate(new_node, COINBASE_MATURITY, sync_fun=self.no_op)44# Sync the nodes to ensure old_node has the block that contains the coinbase that new_wallet will spend.45# Otherwise, because coinbases are only valid in a block and not as loose txns, if the nodes aren't synced46# unbroadcasted_tx won't pass old_node's `MemPoolAccept::PreChecks`.47self.connect_nodes(0, 1)48self.sync_blocks()50self.log.info("Add a transaction to mempool on old node and shutdown")51old_tx_hash = new_wallet.send_self_transfer(from_node=old_node)["txid"]52assert old_tx_hash in old_node.getrawmempool()53self.stop_node(0)54self.stop_node(1)56self.log.info("Move mempool.dat from old to new node")57old_node_mempool = old_node.chain_path / "mempool.dat"58new_node_mempool = new_node.chain_path / "mempool.dat"59new_node_mempool.unlink()60old_node_mempool.rename(new_node_mempool)62self.log.info("Start new node and verify mempool contains the tx")63self.start_node(1, extra_args=["-persistmempoolv1=1"])64assert old_tx_hash in new_node.getrawmempool()66self.log.info("Add unbroadcasted tx to mempool on new node and shutdown")67unbroadcasted_tx_hash = new_wallet.send_self_transfer(from_node=new_node)['txid']68assert unbroadcasted_tx_hash in new_node.getrawmempool()69assert new_node.getmempoolentry(unbroadcasted_tx_hash)['unbroadcast']70self.stop_node(1)72self.log.info("Move mempool.dat from new to old node")73new_node_mempool.rename(old_node_mempool)75self.log.info("Start old node again and verify mempool contains both txs")76self.start_node(0, ['-nowallet'])77assert old_tx_hash in old_node.getrawmempool()78assert unbroadcasted_tx_hash in old_node.getrawmempool()81if __name__ == "__main__":82MempoolCompatibilityTest(__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.