From 4db9108b74a0ce4c425d5543dcf9ccd64f40165e Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Mon, 20 Sep 2021 15:22:15 +0200 Subject: [PATCH] merge bitcoin#23047: Use MiniWallet in mempool_persist --- test/functional/mempool_persist.py | 60 +++++++++++++++--------- test/functional/test_framework/wallet.py | 7 ++- 2 files changed, 42 insertions(+), 25 deletions(-) diff --git a/test/functional/mempool_persist.py b/test/functional/mempool_persist.py index 62b9b990f2..f0090a5945 100755 --- a/test/functional/mempool_persist.py +++ b/test/functional/mempool_persist.py @@ -44,6 +44,7 @@ from test_framework.util import ( assert_equal, assert_greater_than_or_equal, assert_raises_rpc_error, ) +from test_framework.wallet import MiniWallet class MempoolPersistTest(BitcoinTestFramework): @@ -51,15 +52,26 @@ class MempoolPersistTest(BitcoinTestFramework): self.num_nodes = 3 self.extra_args = [[], ["-persistmempool=0"], []] - def skip_test_if_missing_module(self): - self.skip_if_no_wallet() - def run_test(self): + self.mini_wallet = MiniWallet(self.nodes[2]) + self.mini_wallet.rescan_utxos() + if self.is_sqlite_compiled(): + self.nodes[2].createwallet( + wallet_name="watch", + descriptors=True, + disable_private_keys=True, + load_on_startup=False, + ) + wallet_watch = self.nodes[2].get_wallet_rpc("watch") + assert_equal([{'success': True}], wallet_watch.importdescriptors([{'desc': self.mini_wallet.get_descriptor(), 'timestamp': 0}])) + self.log.debug("Send 5 transactions from node2 (to its own address)") tx_creation_time_lower = self.mocktime for _ in range(5): - last_txid = self.nodes[2].sendtoaddress(self.nodes[2].getnewaddress(), Decimal("10")) - node2_balance = self.nodes[2].getbalance() + last_txid = self.mini_wallet.send_self_transfer(from_node=self.nodes[2])["txid"] + if self.is_sqlite_compiled(): + self.nodes[2].syncwithvalidationinterfacequeue() # Flush mempool to wallet + node2_balance = wallet_watch.getbalance() self.sync_all() tx_creation_time_higher = self.mocktime @@ -80,16 +92,16 @@ class MempoolPersistTest(BitcoinTestFramework): assert_equal(total_fee_old, self.nodes[0].getmempoolinfo()['total_fee']) assert_equal(total_fee_old, sum(v['fees']['base'] for k, v in self.nodes[0].getrawmempool(verbose=True).items())) - tx_creation_time = self.nodes[0].getmempoolentry(txid=last_txid)['time'] + last_entry = self.nodes[0].getmempoolentry(txid=last_txid) + tx_creation_time = last_entry['time'] assert_greater_than_or_equal(tx_creation_time, tx_creation_time_lower) assert_greater_than_or_equal(tx_creation_time_higher, tx_creation_time) # disconnect nodes & make a txn that remains in the unbroadcast set. self.disconnect_nodes(0, 1) - assert(len(self.nodes[0].getpeerinfo()) == 0) - assert(len(self.nodes[0].p2ps) == 0) - self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), Decimal("12")) - self.connect_nodes(0, 2) + assert_equal(len(self.nodes[0].getpeerinfo()), 0) + assert_equal(len(self.nodes[0].p2ps), 0) + self.mini_wallet.send_self_transfer(from_node=self.nodes[0]) self.log.debug("Stop-start the nodes. Verify that node0 has the transactions in its mempool and node1 does not. Verify that node2 calculates its balance correctly after loading wallet transactions.") self.stop_nodes() @@ -109,17 +121,19 @@ class MempoolPersistTest(BitcoinTestFramework): fees = self.nodes[0].getmempoolentry(txid=last_txid)['fees'] assert_equal(fees['base'] + Decimal('0.00001000'), fees['modified']) - self.log.debug('Verify time is loaded correctly') - assert_equal(tx_creation_time, self.nodes[0].getmempoolentry(txid=last_txid)['time']) + self.log.debug('Verify all fields are loaded correctly') + assert_equal(last_entry, self.nodes[0].getmempoolentry(txid=last_txid)) # Verify accounting of mempool transactions after restart is correct - self.nodes[2].syncwithvalidationinterfacequeue() # Flush mempool to wallet - assert_equal(node2_balance, self.nodes[2].getbalance()) + if self.is_sqlite_compiled(): + self.nodes[2].loadwallet("watch") + wallet_watch = self.nodes[2].get_wallet_rpc("watch") + self.nodes[2].syncwithvalidationinterfacequeue() # Flush mempool to wallet + assert_equal(node2_balance, wallet_watch.getbalance()) - # start node0 with wallet disabled so wallet transactions don't get resubmitted self.log.debug("Stop-start node0 with -persistmempool=0. Verify that it doesn't load its mempool.dat file.") self.stop_nodes() - self.start_node(0, extra_args=["-persistmempool=0", "-disablewallet"]) + self.start_node(0, extra_args=["-persistmempool=0"]) assert self.nodes[0].getmempoolinfo()["loaded"] assert_equal(len(self.nodes[0].getrawmempool()), 0) @@ -163,18 +177,18 @@ class MempoolPersistTest(BitcoinTestFramework): # ensure node0 doesn't have any connections # make a transaction that will remain in the unbroadcast set - assert(len(node0.getpeerinfo()) == 0) - assert(len(node0.p2ps) == 0) - node0.sendtoaddress(self.nodes[1].getnewaddress(), Decimal("12")) + assert_equal(len(node0.getpeerinfo()), 0) + assert_equal(len(node0.p2ps), 0) + self.mini_wallet.send_self_transfer(from_node=node0) # shutdown, then startup with wallet disabled - self.stop_nodes() - self.start_node(0, extra_args=["-disablewallet"]) + self.restart_node(0, extra_args=["-disablewallet"]) # check that txn gets broadcast due to unbroadcast logic # conn = node0.add_p2p_connection(P2PTxInvStore()) - # node0.mockscheduler(16*60) # 15 min + 1 for buffer + # node0.mockscheduler(16 * 60) # 15 min + 1 for buffer # self.wait_until(lambda: len(conn.get_invs()) == 1) -if __name__ == '__main__': + +if __name__ == "__main__": MempoolPersistTest().main() diff --git a/test/functional/test_framework/wallet.py b/test/functional/test_framework/wallet.py index 6323b7f39f..2007d21f71 100644 --- a/test/functional/test_framework/wallet.py +++ b/test/functional/test_framework/wallet.py @@ -81,7 +81,7 @@ class MiniWallet: def rescan_utxos(self): """Drop all utxos and rescan the utxo set""" self._utxos = [] - res = self._test_node.scantxoutset(action="start", scanobjects=[f'raw({self._scriptPubKey.hex()})']) + res = self._test_node.scantxoutset(action="start", scanobjects=[self.get_descriptor()]) assert_equal(True, res['success']) for utxo in res['unspents']: self._utxos.append({'txid': utxo['txid'], 'vout': utxo['vout'], 'value': utxo['amount'], 'height': utxo['height']}) @@ -116,13 +116,16 @@ class MiniWallet: def generate(self, num_blocks): """Generate blocks with coinbase outputs to the internal address, and append the outputs to the internal list""" - blocks = self._test_node.generatetodescriptor(num_blocks, f'raw({self._scriptPubKey.hex()})') + blocks = self._test_node.generatetodescriptor(num_blocks, self.get_descriptor()) for b in blocks: block_info = self._test_node.getblock(blockhash=b, verbosity=2) cb_tx = block_info['tx'][0] self._utxos.append({'txid': cb_tx['txid'], 'vout': 0, 'value': cb_tx['vout'][0]['value'], 'height': block_info['height']}) return blocks + def get_descriptor(self): + return self._test_node.getdescriptorinfo(f'raw({self._scriptPubKey.hex()})')['descriptor'] + def get_address(self): return self._address