Merge bitcoin/bitcoin#23047: test: Use MiniWallet in mempool_persist

faae0988d6abb50039026a49543eef134eb9103f test: Check other fields are loaded correctly as well (MarcoFalke)
fa4db9261725de8c0e5c73d13df1cddd6bbaeab0 test: Remove unused self.connect_nodes (MarcoFalke)
fafb7b7a892b24405d6b6291d6d72f0e88462f2f test: pep8 (MarcoFalke)
fa32cb2467056b3fd47f0b88215311faec8fd5a4 test: Use MiniWallet in mempool_persist (MarcoFalke)
faca688a8579d7e30d056b6847789fdd56fc0bf4 test: Add MiniWallet get_descriptor function (MarcoFalke)

Pull request description:

ACKs for top commit:
  laanwj:
    Code review ACK faae0988d6abb50039026a49543eef134eb9103f

Tree-SHA512: 6124f16ee1f3f416c50dc07aebe8846ff7e2b7c8e5dd84f9517cb5f1df021b9e57ed7c7e17bc099a37c663cd93f6d417c5e0622c0b359956403d53e705eb5549
This commit is contained in:
W. J. van der Laan 2021-09-24 16:29:21 +02:00
commit 01b5cfb951
No known key found for this signature in database
GPG Key ID: 1E4AED62986CD25D
2 changed files with 42 additions and 25 deletions

View File

@ -46,6 +46,7 @@ from test_framework.util import (
assert_greater_than_or_equal, assert_greater_than_or_equal,
assert_raises_rpc_error, assert_raises_rpc_error,
) )
from test_framework.wallet import MiniWallet
class MempoolPersistTest(BitcoinTestFramework): class MempoolPersistTest(BitcoinTestFramework):
@ -53,15 +54,26 @@ class MempoolPersistTest(BitcoinTestFramework):
self.num_nodes = 3 self.num_nodes = 3
self.extra_args = [[], ["-persistmempool=0"], []] self.extra_args = [[], ["-persistmempool=0"], []]
def skip_test_if_missing_module(self):
self.skip_if_no_wallet()
def run_test(self): 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)") self.log.debug("Send 5 transactions from node2 (to its own address)")
tx_creation_time_lower = int(time.time()) tx_creation_time_lower = int(time.time())
for _ in range(5): for _ in range(5):
last_txid = self.nodes[2].sendtoaddress(self.nodes[2].getnewaddress(), Decimal("10")) last_txid = self.mini_wallet.send_self_transfer(from_node=self.nodes[2])["txid"]
node2_balance = self.nodes[2].getbalance() if self.is_sqlite_compiled():
self.nodes[2].syncwithvalidationinterfacequeue() # Flush mempool to wallet
node2_balance = wallet_watch.getbalance()
self.sync_all() self.sync_all()
tx_creation_time_higher = int(time.time()) tx_creation_time_higher = int(time.time())
@ -82,16 +94,16 @@ class MempoolPersistTest(BitcoinTestFramework):
assert_equal(total_fee_old, self.nodes[0].getmempoolinfo()['total_fee']) 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())) 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, tx_creation_time_lower)
assert_greater_than_or_equal(tx_creation_time_higher, tx_creation_time) assert_greater_than_or_equal(tx_creation_time_higher, tx_creation_time)
# disconnect nodes & make a txn that remains in the unbroadcast set. # disconnect nodes & make a txn that remains in the unbroadcast set.
self.disconnect_nodes(0, 1) self.disconnect_nodes(0, 1)
assert(len(self.nodes[0].getpeerinfo()) == 0) assert_equal(len(self.nodes[0].getpeerinfo()), 0)
assert(len(self.nodes[0].p2ps) == 0) assert_equal(len(self.nodes[0].p2ps), 0)
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), Decimal("12")) self.mini_wallet.send_self_transfer(from_node=self.nodes[0])
self.connect_nodes(0, 2)
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.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() self.stop_nodes()
@ -111,17 +123,19 @@ class MempoolPersistTest(BitcoinTestFramework):
fees = self.nodes[0].getmempoolentry(txid=last_txid)['fees'] fees = self.nodes[0].getmempoolentry(txid=last_txid)['fees']
assert_equal(fees['base'] + Decimal('0.00001000'), fees['modified']) assert_equal(fees['base'] + Decimal('0.00001000'), fees['modified'])
self.log.debug('Verify time is loaded correctly') self.log.debug('Verify all fields are loaded correctly')
assert_equal(tx_creation_time, self.nodes[0].getmempoolentry(txid=last_txid)['time']) assert_equal(last_entry, self.nodes[0].getmempoolentry(txid=last_txid))
# Verify accounting of mempool transactions after restart is correct # Verify accounting of mempool transactions after restart is correct
self.nodes[2].syncwithvalidationinterfacequeue() # Flush mempool to wallet if self.is_sqlite_compiled():
assert_equal(node2_balance, self.nodes[2].getbalance()) 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.log.debug("Stop-start node0 with -persistmempool=0. Verify that it doesn't load its mempool.dat file.")
self.stop_nodes() 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 self.nodes[0].getmempoolinfo()["loaded"]
assert_equal(len(self.nodes[0].getrawmempool()), 0) assert_equal(len(self.nodes[0].getrawmempool()), 0)
@ -164,18 +178,18 @@ class MempoolPersistTest(BitcoinTestFramework):
# ensure node0 doesn't have any connections # ensure node0 doesn't have any connections
# make a transaction that will remain in the unbroadcast set # make a transaction that will remain in the unbroadcast set
assert(len(node0.getpeerinfo()) == 0) assert_equal(len(node0.getpeerinfo()), 0)
assert(len(node0.p2ps) == 0) assert_equal(len(node0.p2ps), 0)
node0.sendtoaddress(self.nodes[1].getnewaddress(), Decimal("12")) self.mini_wallet.send_self_transfer(from_node=node0)
# shutdown, then startup with wallet disabled # shutdown, then startup with wallet disabled
self.stop_nodes() self.restart_node(0, extra_args=["-disablewallet"])
self.start_node(0, extra_args=["-disablewallet"])
# check that txn gets broadcast due to unbroadcast logic # check that txn gets broadcast due to unbroadcast logic
conn = node0.add_p2p_connection(P2PTxInvStore()) 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) self.wait_until(lambda: len(conn.get_invs()) == 1)
if __name__ == '__main__':
if __name__ == "__main__":
MempoolPersistTest().main() MempoolPersistTest().main()

View File

@ -82,7 +82,7 @@ class MiniWallet:
def rescan_utxos(self): def rescan_utxos(self):
"""Drop all utxos and rescan the utxo set""" """Drop all utxos and rescan the utxo set"""
self._utxos = [] 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']) assert_equal(True, res['success'])
for utxo in res['unspents']: for utxo in res['unspents']:
self._utxos.append({'txid': utxo['txid'], 'vout': utxo['vout'], 'value': utxo['amount']}) self._utxos.append({'txid': utxo['txid'], 'vout': utxo['vout'], 'value': utxo['amount']})
@ -110,12 +110,15 @@ class MiniWallet:
def generate(self, num_blocks): def generate(self, num_blocks):
"""Generate blocks with coinbase outputs to the internal address, and append the outputs to the internal list""" """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: for b in blocks:
cb_tx = self._test_node.getblock(blockhash=b, verbosity=2)['tx'][0] cb_tx = self._test_node.getblock(blockhash=b, verbosity=2)['tx'][0]
self._utxos.append({'txid': cb_tx['txid'], 'vout': 0, 'value': cb_tx['vout'][0]['value']}) self._utxos.append({'txid': cb_tx['txid'], 'vout': 0, 'value': cb_tx['vout'][0]['value']})
return blocks return blocks
def get_descriptor(self):
return self._test_node.getdescriptorinfo(f'raw({self._scriptPubKey.hex()})')['descriptor']
def get_address(self): def get_address(self):
return self._address return self._address