Merge #21200: test: Speed up rpc_blockchain.py by removing miniwallet.generate()

faa137eb9eac5554504b062a6dc865ca87fd572b test: Speed up rpc_blockchain.py by removing miniwallet.generate() (MarcoFalke)
fa1fe80c757df0adcbfaf41b5c5c8a468bc07b6f test: Change address type from P2PKH to P2WSH in rpc_blockchain (MarcoFalke)
fa4d8f3169e38cbdbae20258efebe7070c49f522 test: Cache 25 mature coins for ADDRESS_BCRT1_P2WSH_OP_TRUE (MarcoFalke)
fad25153f5c8e88f72cf666b16b0b0dbdc45d3b1 test: Remove unused bug workaround (MarcoFalke)
faabce7d07c5776e4116b1a7ad1f6c408a4a4e46 test: Start only the number of nodes that are needed (MarcoFalke)

Pull request description:

  Speed up various tests:

  * Remove unused nodes, which only consume time on start/stop
  * Remove unused "bug workarounds"
  * Remove the need for `miniwallet.generate()` by adding `miniwallet.scan_blocks()`. (On my system, with valgrind, generating 105 blocks takes 3.31 seconds. Rescanning 5 blocks takes 0.11 seconds.)

ACKs for top commit:
  laanwj:
    Code review ACK faa137eb9eac5554504b062a6dc865ca87fd572b

Tree-SHA512: ead1988d5aaa748ef9f8520af1e0bf812cf1d72e281ad22fbd172b7306d850053040526f8adbcec0b9a971c697a0ee7ee8962684644d65b791663eedd505a025
This commit is contained in:
Wladimir J. van der Laan 2021-02-25 09:48:28 +01:00 committed by Konstantin Akimov
parent 4ab6aa4598
commit 4e81732c57
No known key found for this signature in database
GPG Key ID: 2176C4A5D01EA524
5 changed files with 28 additions and 16 deletions

View File

@ -25,6 +25,7 @@ import http.client
import os import os
import subprocess import subprocess
from test_framework.address import ADDRESS_BCRT1_P2SH_OP_TRUE
from test_framework.blocktools import ( from test_framework.blocktools import (
create_block, create_block,
create_coinbase, create_coinbase,
@ -81,11 +82,10 @@ class BlockchainTest(BitcoinTestFramework):
def mine_chain(self): def mine_chain(self):
self.log.info(f"Generate {HEIGHT} blocks after the genesis block in 156 sec") self.log.info(f"Generate {HEIGHT} blocks after the genesis block in 156 sec")
address = self.nodes[0].get_deterministic_priv_key().address
for t in range(TIME_GENESIS_BLOCK, TIME_RANGE_END, TIME_RANGE_STEP): for t in range(TIME_GENESIS_BLOCK, TIME_RANGE_END, TIME_RANGE_STEP):
# 156 sec steps from genesis block time # 156 sec steps from genesis block time
set_node_times(self.nodes, t) set_node_times(self.nodes, t)
self.nodes[0].generatetoaddress(1, address) self.nodes[0].generatetoaddress(1, ADDRESS_BCRT1_P2SH_OP_TRUE)
assert_equal(self.nodes[0].getblockchaininfo()['blocks'], 200) assert_equal(self.nodes[0].getblockchaininfo()['blocks'], 200)
def _test_getblockchaininfo(self): def _test_getblockchaininfo(self):
@ -258,7 +258,7 @@ class BlockchainTest(BitcoinTestFramework):
assert_equal(res['transactions'], HEIGHT) assert_equal(res['transactions'], HEIGHT)
assert_equal(res['height'], HEIGHT) assert_equal(res['height'], HEIGHT)
assert_equal(res['txouts'], HEIGHT) assert_equal(res['txouts'], HEIGHT)
assert_equal(res['bogosize'], 15000), assert_equal(res['bogosize'], 14600),
size = res['disk_size'] size = res['disk_size']
assert size > 6400 assert size > 6400
assert size < 64000 assert size < 64000
@ -365,12 +365,12 @@ class BlockchainTest(BitcoinTestFramework):
def _test_stopatheight(self): def _test_stopatheight(self):
assert_equal(self.nodes[0].getblockcount(), HEIGHT) assert_equal(self.nodes[0].getblockcount(), HEIGHT)
self.nodes[0].generatetoaddress(6, self.nodes[0].get_deterministic_priv_key().address) self.nodes[0].generatetoaddress(6, ADDRESS_BCRT1_P2SH_OP_TRUE)
assert_equal(self.nodes[0].getblockcount(), HEIGHT + 6) assert_equal(self.nodes[0].getblockcount(), HEIGHT + 6)
self.log.debug('Node should not stop at this height') self.log.debug('Node should not stop at this height')
assert_raises(subprocess.TimeoutExpired, lambda: self.nodes[0].process.wait(timeout=3)) assert_raises(subprocess.TimeoutExpired, lambda: self.nodes[0].process.wait(timeout=3))
try: try:
self.nodes[0].generatetoaddress(1, self.nodes[0].get_deterministic_priv_key().address) self.nodes[0].generatetoaddress(1, ADDRESS_BCRT1_P2SH_OP_TRUE)
except (ConnectionError, http.client.BadStatusLine): except (ConnectionError, http.client.BadStatusLine):
pass # The node already shut down before response pass # The node already shut down before response
self.log.debug('Node should stop at this height...') self.log.debug('Node should stop at this height...')
@ -420,8 +420,7 @@ class BlockchainTest(BitcoinTestFramework):
node = self.nodes[0] node = self.nodes[0]
miniwallet = MiniWallet(node) miniwallet = MiniWallet(node)
miniwallet.generate(5) miniwallet.scan_blocks(num=5)
node.generate(100)
fee_per_byte = Decimal('0.00000010') fee_per_byte = Decimal('0.00000010')
fee_per_kb = 1000 * fee_per_byte fee_per_kb = 1000 * fee_per_byte

View File

@ -23,6 +23,7 @@ import time
from concurrent.futures import ThreadPoolExecutor from concurrent.futures import ThreadPoolExecutor
from typing import List from typing import List
from .address import ADDRESS_BCRT1_P2SH_OP_TRUE
from .authproxy import JSONRPCException from .authproxy import JSONRPCException
from test_framework.blocktools import TIME_GENESIS_BLOCK from test_framework.blocktools import TIME_GENESIS_BLOCK
from . import coverage from . import coverage
@ -905,18 +906,19 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
# Set a time in the past, so that blocks don't end up in the future # Set a time in the past, so that blocks don't end up in the future
cache_node.setmocktime(cache_node.getblockheader(cache_node.getbestblockhash())['time']) cache_node.setmocktime(cache_node.getblockheader(cache_node.getbestblockhash())['time'])
# Create a 199-block-long chain; each of the 4 first nodes # Create a 199-block-long chain; each of the 3 first nodes
# gets 25 mature blocks and 25 immature. # gets 25 mature blocks and 25 immature.
# The 4th node gets only 24 immature blocks so that the very last # The 4th address gets 25 mature and only 24 immature blocks so that the very last
# block in the cache does not age too much (have an old tip age). # block in the cache does not age too much (have an old tip age).
# This is needed so that we are out of IBD when the test starts, # This is needed so that we are out of IBD when the test starts,
# see the tip age check in IsInitialBlockDownload(). # see the tip age check in IsInitialBlockDownload().
self.set_genesis_mocktime() self.set_genesis_mocktime()
gen_addresses = [k.address for k in TestNode.PRIV_KEYS] + [ADDRESS_BCRT1_P2SH_OP_TRUE]
for i in range(8): for i in range(8):
self.bump_mocktime((25 if i != 7 else 24) * 156) self.bump_mocktime((25 if i != 7 else 24) * 156)
cache_node.generatetoaddress( cache_node.generatetoaddress(
nblocks=25 if i != 7 else 24, nblocks=25 if i != 7 else 24,
address=TestNode.PRIV_KEYS[i % 4].address, address=gen_addresses[i % 4],
) )
assert_equal(cache_node.getblockchaininfo()["blocks"], 199) assert_equal(cache_node.getblockchaininfo()["blocks"], 199)

View File

@ -32,6 +32,15 @@ class MiniWallet:
self._address = ADDRESS_BCRT1_P2SH_OP_TRUE self._address = ADDRESS_BCRT1_P2SH_OP_TRUE
self._scriptPubKey = hex_str_to_bytes(self._test_node.validateaddress(self._address)['scriptPubKey']) self._scriptPubKey = hex_str_to_bytes(self._test_node.validateaddress(self._address)['scriptPubKey'])
def scan_blocks(self, *, start=1, num):
"""Scan the blocks for self._address outputs and add them to self._utxos"""
for i in range(start, start + num):
block = self._test_node.getblock(blockhash=self._test_node.getblockhash(i), verbosity=2)
for tx in block['tx']:
for out in tx['vout']:
if out['scriptPubKey']['hex'] == self._scriptPubKey.hex():
self._utxos.append({'txid': tx['txid'], 'vout': out['n'], 'value': out['value']})
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.generatetoaddress(num_blocks, self._address) blocks = self._test_node.generatetoaddress(num_blocks, self._address)

View File

@ -13,9 +13,10 @@ from test_framework.messages import (
tx_from_hex, tx_from_hex,
) )
class TxnMallTest(BitcoinTestFramework): class TxnMallTest(BitcoinTestFramework):
def set_test_params(self): def set_test_params(self):
self.num_nodes = 4 self.num_nodes = 3
self.supports_cli = False self.supports_cli = False
def skip_test_if_missing_module(self): def skip_test_if_missing_module(self):
@ -33,9 +34,8 @@ class TxnMallTest(BitcoinTestFramework):
def run_test(self): def run_test(self):
# All nodes should start with 12,500 DASH: # All nodes should start with 12,500 DASH:
starting_balance = 12500 starting_balance = 12500
for i in range(4): for i in range(3):
assert_equal(self.nodes[i].getbalance(), starting_balance) assert_equal(self.nodes[i].getbalance(), starting_balance)
self.nodes[i].getnewaddress() # bug workaround, coins generated assigned to first getnewaddress!
self.nodes[0].settxfee(.001) self.nodes[0].settxfee(.001)
@ -129,5 +129,6 @@ class TxnMallTest(BitcoinTestFramework):
expected -= 500 expected -= 500
assert_equal(self.nodes[0].getbalance(), expected) assert_equal(self.nodes[0].getbalance(), expected)
if __name__ == '__main__': if __name__ == '__main__':
TxnMallTest().main() TxnMallTest().main()

View File

@ -11,9 +11,10 @@ from test_framework.util import (
find_output, find_output,
) )
class TxnMallTest(BitcoinTestFramework): class TxnMallTest(BitcoinTestFramework):
def set_test_params(self): def set_test_params(self):
self.num_nodes = 4 self.num_nodes = 3
self.supports_cli = False self.supports_cli = False
def skip_test_if_missing_module(self): def skip_test_if_missing_module(self):
@ -39,9 +40,8 @@ class TxnMallTest(BitcoinTestFramework):
for n in self.nodes: for n in self.nodes:
assert n.getblockchaininfo()["initialblockdownload"] == False assert n.getblockchaininfo()["initialblockdownload"] == False
for i in range(4): for i in range(3):
assert_equal(self.nodes[i].getbalance(), starting_balance) assert_equal(self.nodes[i].getbalance(), starting_balance)
self.nodes[i].getnewaddress("") # bug workaround, coins generated assigned to first getnewaddress!
# Assign coins to foo and bar addresses: # Assign coins to foo and bar addresses:
node0_address_foo = self.nodes[0].getnewaddress() node0_address_foo = self.nodes[0].getnewaddress()
@ -136,5 +136,6 @@ class TxnMallTest(BitcoinTestFramework):
# Node1's balance should be its initial balance (12500 for 25 block rewards) plus the doublespend: # Node1's balance should be its initial balance (12500 for 25 block rewards) plus the doublespend:
assert_equal(self.nodes[1].getbalance(), 12500 + 12400) assert_equal(self.nodes[1].getbalance(), 12500 + 12400)
if __name__ == '__main__': if __name__ == '__main__':
TxnMallTest().main() TxnMallTest().main()