diff options
author | Michael Dietz <michael.dietz@waya.ai> | 2020-12-08 13:55:12 -0600 |
---|---|---|
committer | Michael Dietz <michael.dietz@waya.ai> | 2020-12-10 10:14:35 -0600 |
commit | 3b064fcb9dd3df6c438a440f0fea86e9cf7b5f57 (patch) | |
tree | 397fa6c5836f5a41c494cf76908f994a28392114 /test/functional | |
parent | 854b36cfa2ef017567dcf1e7d0304107a8700f2b (diff) | |
download | bitcoin-3b064fcb9dd3df6c438a440f0fea86e9cf7b5f57.tar.xz |
test: run mempool_expiry.py even with wallet disabled
Test coverage is also extended in this commit to:
Ensure that another transaction in the mempool is not evicted
when other transactions expire. Note: this other transaction does
not have any ancestors in the mempool that expired. Otherwise it
would be evicted from the mempool, and we already test this case.
Diffstat (limited to 'test/functional')
-rwxr-xr-x | test/functional/mempool_expiry.py | 52 |
1 files changed, 31 insertions, 21 deletions
diff --git a/test/functional/mempool_expiry.py b/test/functional/mempool_expiry.py index 8b9b7b155a..4c46075ae9 100755 --- a/test/functional/mempool_expiry.py +++ b/test/functional/mempool_expiry.py @@ -16,8 +16,8 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, assert_raises_rpc_error, - find_vout_for_address, ) +from test_framework.wallet import MiniWallet DEFAULT_MEMPOOL_EXPIRY = 336 # hours CUSTOM_MEMPOOL_EXPIRY = 10 # hours @@ -26,44 +26,50 @@ CUSTOM_MEMPOOL_EXPIRY = 10 # hours class MempoolExpiryTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 - - def skip_test_if_missing_module(self): - self.skip_if_no_wallet() + self.setup_clean_chain = True def test_transaction_expiry(self, timeout): """Tests that a transaction expires after the expiry timeout and its children are removed as well.""" node = self.nodes[0] + self.wallet = MiniWallet(node) + + # Add enough mature utxos to the wallet so that all txs spend confirmed coins. + self.wallet.generate(4) + node.generate(100) # Send a parent transaction that will expire. - parent_address = node.getnewaddress() - parent_txid = node.sendtoaddress(parent_address, 1.0) + parent_txid = self.wallet.send_self_transfer(from_node=node)['txid'] + parent_utxo = self.wallet.get_utxo(txid=parent_txid) + independent_utxo = self.wallet.get_utxo() + + # Ensure the transactions we send to trigger the mempool check spend utxos that are independent of + # the transactions being tested for expiration. + trigger_utxo1 = self.wallet.get_utxo() + trigger_utxo2 = self.wallet.get_utxo() # Set the mocktime to the arrival time of the parent transaction. entry_time = node.getmempoolentry(parent_txid)['time'] node.setmocktime(entry_time) - # Create child transaction spending the parent transaction - vout = find_vout_for_address(node, parent_txid, parent_address) - inputs = [{'txid': parent_txid, 'vout': vout}] - outputs = {node.getnewaddress(): 0.99} - child_raw = node.createrawtransaction(inputs, outputs) - child_signed = node.signrawtransactionwithwallet(child_raw)['hex'] - - # Let half of the timeout elapse and broadcast the child transaction. + # Let half of the timeout elapse and broadcast the child transaction spending the parent transaction. half_expiry_time = entry_time + int(60 * 60 * timeout/2) node.setmocktime(half_expiry_time) - child_txid = node.sendrawtransaction(child_signed) + child_txid = self.wallet.send_self_transfer(from_node=node, utxo_to_spend=parent_utxo)['txid'] + assert_equal(parent_txid, node.getmempoolentry(child_txid)['depends'][0]) self.log.info('Broadcast child transaction after {} hours.'.format( timedelta(seconds=(half_expiry_time-entry_time)))) + # Broadcast another (independent) transaction. + independent_txid = self.wallet.send_self_transfer(from_node=node, utxo_to_spend=independent_utxo)['txid'] + # Let most of the timeout elapse and check that the parent tx is still # in the mempool. nearly_expiry_time = entry_time + 60 * 60 * timeout - 5 node.setmocktime(nearly_expiry_time) - # Expiry of mempool transactions is only checked when a new transaction - # is added to the to the mempool. - node.sendtoaddress(node.getnewaddress(), 1.0) + # Broadcast a transaction as the expiry of transactions in the mempool is only checked + # when a new transaction is added to the mempool. + self.wallet.send_self_transfer(from_node=node, utxo_to_spend=trigger_utxo1) self.log.info('Test parent tx not expired after {} hours.'.format( timedelta(seconds=(nearly_expiry_time-entry_time)))) assert_equal(entry_time, node.getmempoolentry(parent_txid)['time']) @@ -72,9 +78,8 @@ class MempoolExpiryTest(BitcoinTestFramework): # has passed. expiry_time = entry_time + 60 * 60 * timeout + 5 node.setmocktime(expiry_time) - # Expiry of mempool transactions is only checked when a new transaction - # is added to the to the mempool. - node.sendtoaddress(node.getnewaddress(), 1.0) + # Again, broadcast a transaction so the expiry of transactions in the mempool is checked. + self.wallet.send_self_transfer(from_node=node, utxo_to_spend=trigger_utxo2) self.log.info('Test parent tx expiry after {} hours.'.format( timedelta(seconds=(expiry_time-entry_time)))) assert_raises_rpc_error(-5, 'Transaction not in mempool', @@ -85,6 +90,11 @@ class MempoolExpiryTest(BitcoinTestFramework): assert_raises_rpc_error(-5, 'Transaction not in mempool', node.getmempoolentry, child_txid) + # Check that the independent tx is still in the mempool. + self.log.info('Test the independent tx not expired after {} hours.'.format( + timedelta(seconds=(expiry_time-half_expiry_time)))) + assert_equal(half_expiry_time, node.getmempoolentry(independent_txid)['time']) + def run_test(self): self.log.info('Test default mempool expiry timeout of %d hours.' % DEFAULT_MEMPOOL_EXPIRY) |