dash/test/functional/mempool_compatibility.py

84 lines
3.3 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
# Copyright (c) 2017-2020 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test that mempool.dat is both backward and forward compatible between versions
NOTE: The test is designed to prevent cases when compatibility is broken accidentally.
In case we need to break mempool compatibility we can continue to use the test by just bumping the version number.
The previous release v0.15.0.0 is required by this test, see test/README.md.
"""
import os
from test_framework.test_framework import BitcoinTestFramework
from test_framework.wallet import MiniWallet
class MempoolCompatibilityTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 2
self.wallet_names = [None]
def skip_test_if_missing_module(self):
self.skip_if_no_previous_releases()
def setup_network(self):
self.add_nodes(self.num_nodes, versions=[
150000, # oldest version supported by the test framework
None,
])
self.extra_args = [
[],
[],
]
self.start_nodes()
self.import_deterministic_coinbase_privkeys()
def run_test(self):
self.log.info("Test that mempool.dat is compatible between versions")
old_node, new_node = self.nodes
new_wallet = MiniWallet(new_node)
new_wallet.generate(1)
new_node.generate(100)
# Sync the nodes to ensure old_node has the block that contains the coinbase that new_wallet will spend.
# Otherwise, because coinbases are only valid in a block and not as loose txns, if the nodes aren't synced
# unbroadcasted_tx won't pass old_node's `MemPoolAccept::PreChecks`.
self.connect_nodes(0, 1)
self.sync_blocks()
recipient = old_node.getnewaddress()
self.stop_node(1)
self.log.info("Add a transaction to mempool on old node and shutdown")
old_tx_hash = old_node.sendtoaddress(recipient, 0.0001)
assert old_tx_hash in old_node.getrawmempool()
self.stop_node(0)
self.log.info("Move mempool.dat from old to new node")
old_node_mempool = os.path.join(old_node.datadir, self.chain, 'mempool.dat')
new_node_mempool = os.path.join(new_node.datadir, self.chain, 'mempool.dat')
os.rename(old_node_mempool, new_node_mempool)
self.log.info("Start new node and verify mempool contains the tx")
self.start_node(1)
assert old_tx_hash in new_node.getrawmempool()
self.log.info("Add unbroadcasted tx to mempool on new node and shutdown")
unbroadcasted_tx_hash = new_wallet.send_self_transfer(from_node=new_node)['txid']
assert unbroadcasted_tx_hash in new_node.getrawmempool()
(partial) Merge bitcoin/bitcoin#22707: test: refactor use of getrawmempool in functional tests for efficiency 47c48b5f35b4910fcf87caa6e37407e67d879c80 test: only use verbose for getrawmempool when necessary in functional tests (Michael Dietz) 77349713b189e80f2c140db4df50177353a1cb83 test: use getmempoolentry instead of getrawmempool in functional tests when appropriate (Michael Dietz) 86dbd54ae8a8f9c693c0ea67114bbff24a0754df test: improve mempool_updatefrom efficiency by using getmempoolentry for specific txns (Michael Dietz) Pull request description: I don't think this changes the intention of the test. But it does shave ~30 seconds off the time it takes to run. From what I've seen our CI `macOS 11 native [gui] [no depends]` runs `mempool_updatefrom.py` in ~135 seconds. After this PR it should run in ~105 seconds I noticed this improvement should probably be made when testing performance/runtimes of https://github.com/bitcoin/bitcoin/pull/22698. But I wanted to separate this out from that PR so the affects of each is decoupled Edit: The major change in this PR is improving mempool_updatefrom.py's runtime as this is a very long running test. Then made the same efficiency improvements across all the functional tests as it made since to do that here ACKs for top commit: theStack: Tested ACK 47c48b5f35b4910fcf87caa6e37407e67d879c80 Tree-SHA512: 40f553715f3d4649dc18c2738554eafaca9ea800c4b028c099217896cc1c466ff457ae814d59cf8564c782a8964d8fac3eda60c1b6ffb08bbee1439b2d34434b Signed-off-by: Vijay <vijaydas.mp@gmail.com>
2021-08-20 17:38:38 +02:00
assert new_node.getmempoolentry(unbroadcasted_tx_hash)['unbroadcast']
self.stop_node(1)
self.log.info("Move mempool.dat from new to old node")
os.rename(new_node_mempool, old_node_mempool)
self.log.info("Start old node again and verify mempool contains both txs")
self.start_node(0, ['-nowallet'])
assert old_tx_hash in old_node.getrawmempool()
assert unbroadcasted_tx_hash in old_node.getrawmempool()
if __name__ == "__main__":
MempoolCompatibilityTest().main()