Skip to content

Commit

Permalink
Merge bitcoin#9274: [qa] Use cached utxo set to fix performance regre…
Browse files Browse the repository at this point in the history
…ssion

fab1af3 [qa] maxuploadtarget: Use cached utxo set (MarcoFalke)
fa2ecc4 [qa] pruning: Use cached utxo set to run faster (MarcoFalke)
  • Loading branch information
MarcoFalke authored and CryptoCentric committed Feb 25, 2019
1 parent 53570a3 commit 4f6119c
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 15 deletions.
7 changes: 5 additions & 2 deletions qa/rpc-tests/maxuploadtarget.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ def __init__(self):
self.setup_clean_chain = True
self.num_nodes = 1

# Cache for utxos, as the listunspent may take a long time later in the test
self.utxo_cache = []

def setup_network(self):
# Start a node with maxuploadtarget of 200 MB (/24h)
self.nodes = []
Expand Down Expand Up @@ -118,7 +121,7 @@ def run_test(self):
# Test logic begins here

# Now mine a big block
mine_large_block(self.nodes[0])
mine_large_block(self.nodes[0], self.utxo_cache)

# Store the hash; we'll request this later
big_old_block = self.nodes[0].getbestblockhash()
Expand All @@ -129,7 +132,7 @@ def run_test(self):
self.nodes[0].setmocktime(int(time.time()) - 2*60*60*24)

# Mine one more block, so that the prior block looks old
mine_large_block(self.nodes[0])
mine_large_block(self.nodes[0], self.utxo_cache)

# We'll be requesting this new block too
big_new_block = self.nodes[0].getbestblockhash()
Expand Down
6 changes: 3 additions & 3 deletions qa/rpc-tests/mempool_limit.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def __init__(self):

def run_test(self):
txids = []
utxos = create_confirmed_utxos(self.relayfee, self.nodes[0], 490)
utxos = create_confirmed_utxos(self.relayfee, self.nodes[0], 491)

#create a mempool tx that will be evicted
us0 = utxos.pop()
Expand All @@ -41,9 +41,9 @@ def run_test(self):

relayfee = self.nodes[0].getnetworkinfo()['relayfee']
base_fee = relayfee*100
for i in range (4):
for i in range (3):
txids.append([])
txids[i] = create_lots_of_big_transactions(self.nodes[0], self.txouts, utxos[30*i:30*i+30], (i+1)*base_fee)
txids[i] = create_lots_of_big_transactions(self.nodes[0], self.txouts, utxos[30*i:30*i+30], 30, (i+1)*base_fee)

# by now, the tx should be evicted, check confirmation state
assert(txid not in self.nodes[0].getrawmempool())
Expand Down
2 changes: 1 addition & 1 deletion qa/rpc-tests/prioritise_transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def run_test(self):
txids.append([])
start_range = i * range_size
end_range = start_range + range_size
txids[i] = create_lots_of_big_transactions(self.nodes[0], self.txouts, utxos[start_range:end_range], (i+1)*base_fee)
txids[i] = create_lots_of_big_transactions(self.nodes[0], self.txouts, utxos[start_range:end_range], end_range - start_range, (i+1)*base_fee)

# Make sure that the size of each group of transactions exceeds
# MAX_BLOCK_SIZE -- otherwise the test needs to be revised to create
Expand Down
15 changes: 11 additions & 4 deletions qa/rpc-tests/pruning.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@

from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
import time
import os


def calc_usage(blockdir):
return sum(os.path.getsize(blockdir+f) for f in os.listdir(blockdir) if os.path.isfile(blockdir+f)) / (1024. * 1024.)
Expand All @@ -24,6 +27,10 @@ def __init__(self):
self.setup_clean_chain = True
self.num_nodes = 3

# Cache for utxos, as the listunspent may take a long time later in the test
self.utxo_cache_0 = []
self.utxo_cache_1 = []

def setup_network(self):
self.nodes = []
self.is_network_split = False
Expand All @@ -48,7 +55,7 @@ def create_big_chain(self):
self.nodes[0].generate(150)
# Then mine enough full blocks to create more than 550MiB of data
for i in range(645):
mine_large_block(self.nodes[0])
mine_large_block(self.nodes[0], self.utxo_cache_0)

sync_blocks(self.nodes[0:3])

Expand All @@ -60,7 +67,7 @@ def test_height_min(self):
print("Mining 25 more blocks should cause the first block file to be pruned")
# Pruning doesn't run until we're allocating another chunk, 20 full blocks past the height cutoff will ensure this
for i in range(25):
mine_large_block(self.nodes[0])
mine_large_block(self.nodes[0], self.utxo_cache_0)

waitstart = time.time()
while os.path.isfile(self.prunedir+"blk00000.dat"):
Expand All @@ -87,13 +94,13 @@ def create_chain_with_staleblocks(self):
# Mine 24 blocks in node 1
for i in range(24):
if j == 0:
mine_large_block(self.nodes[1])
mine_large_block(self.nodes[1], self.utxo_cache_1)
else:
self.nodes[1].generate(1) #tx's already in mempool from previous disconnects

# Reorg back with 25 block chain from node 0
for i in range(25):
mine_large_block(self.nodes[0])
mine_large_block(self.nodes[0], self.utxo_cache_0)

# Create connections in the order so both nodes can see the reorg at the same time
connect_nodes(self.nodes[1], 0)
Expand Down
14 changes: 9 additions & 5 deletions qa/rpc-tests/test_framework/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -675,10 +675,10 @@ def create_tx(node, coinbase, to_address, amount):

# Create a spend of each passed-in utxo, splicing in "txouts" to each raw
# transaction to make it large. See gen_return_txouts() above.
def create_lots_of_big_transactions(node, txouts, utxos, fee):
def create_lots_of_big_transactions(node, txouts, utxos, num, fee):
addr = node.getnewaddress()
txids = []
for _ in range(len(utxos)):
for _ in range(num):
t = utxos.pop()
inputs=[{ "txid" : t["txid"], "vout" : t["vout"]}]
outputs = {}
Expand All @@ -693,13 +693,17 @@ def create_lots_of_big_transactions(node, txouts, utxos, fee):
txids.append(txid)
return txids

def mine_large_block(node):
def mine_large_block(node, utxos=None):
# generate a 66k transaction,
# and 14 of them is close to the 1MB block limit
num = 14
txouts = gen_return_txouts()
utxos = node.listunspent()[:14]
utxos = utxos if utxos is not None else []
if len(utxos) < num:
utxos.clear()
utxos.extend(node.listunspent())
fee = 100 * node.getnetworkinfo()["relayfee"]
create_lots_of_big_transactions(node, txouts, utxos, fee=fee)
create_lots_of_big_transactions(node, txouts, utxos, num, fee=fee)
node.generate(1)

def get_bip9_status(node, key):
Expand Down

0 comments on commit 4f6119c

Please sign in to comment.