0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-03-05 14:06:27 -05:00

test: simplify and speedup mempool_updatefromblock.py by using MiniWallet

This commit is contained in:
Sebastian Falbesoner 2023-02-03 17:23:26 +01:00
parent aaa55971f6
commit dee8549be3

View file

@ -7,14 +7,12 @@
Test mempool update of transaction descendants/ancestors information (count, size) Test mempool update of transaction descendants/ancestors information (count, size)
when transactions have been re-added from a disconnected block to the mempool. when transactions have been re-added from a disconnected block to the mempool.
""" """
from math import ceil
import time import time
from decimal import Decimal
from test_framework.test_framework import BitcoinTestFramework from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal from test_framework.util import assert_equal
from test_framework.address import key_to_p2pkh from test_framework.wallet import MiniWallet
from test_framework.wallet_util import bytes_to_wif
from test_framework.key import ECKey
class MempoolUpdateFromBlockTest(BitcoinTestFramework): class MempoolUpdateFromBlockTest(BitcoinTestFramework):
@ -22,15 +20,7 @@ class MempoolUpdateFromBlockTest(BitcoinTestFramework):
self.num_nodes = 1 self.num_nodes = 1
self.extra_args = [['-limitdescendantsize=1000', '-limitancestorsize=1000', '-limitancestorcount=100']] self.extra_args = [['-limitdescendantsize=1000', '-limitancestorsize=1000', '-limitancestorcount=100']]
def get_new_address(self): def transaction_graph_test(self, size, n_tx_to_mine=None, fee=100_000):
key = ECKey()
key.generate()
pubkey = key.get_pubkey().get_bytes()
address = key_to_p2pkh(pubkey)
self.priv_keys.append(bytes_to_wif(key.get_bytes()))
return address
def transaction_graph_test(self, size, n_tx_to_mine=None, start_input_txid='', end_address='', fee=Decimal(0.00100000)):
"""Create an acyclic tournament (a type of directed graph) of transactions and use it for testing. """Create an acyclic tournament (a type of directed graph) of transactions and use it for testing.
Keyword arguments: Keyword arguments:
@ -45,14 +35,7 @@ class MempoolUpdateFromBlockTest(BitcoinTestFramework):
More details: https://en.wikipedia.org/wiki/Tournament_(graph_theory) More details: https://en.wikipedia.org/wiki/Tournament_(graph_theory)
""" """
wallet = MiniWallet(self.nodes[0])
self.priv_keys = [self.nodes[0].get_deterministic_priv_key().key]
if not start_input_txid:
start_input_txid = self.nodes[0].getblock(self.nodes[0].getblockhash(1))['tx'][0]
if not end_address:
end_address = self.get_new_address()
first_block_hash = '' first_block_hash = ''
tx_id = [] tx_id = []
tx_size = [] tx_size = []
@ -61,41 +44,31 @@ class MempoolUpdateFromBlockTest(BitcoinTestFramework):
self.log.debug('Preparing transaction #{}...'.format(i)) self.log.debug('Preparing transaction #{}...'.format(i))
# Prepare inputs. # Prepare inputs.
if i == 0: if i == 0:
inputs = [{'txid': start_input_txid, 'vout': 0}] inputs = [wallet.get_utxo()] # let MiniWallet provide a start UTXO
inputs_value = self.nodes[0].gettxout(start_input_txid, 0)['value']
else: else:
inputs = [] inputs = []
inputs_value = 0
for j, tx in enumerate(tx_id[0:i]): for j, tx in enumerate(tx_id[0:i]):
# Transaction tx[K] is a child of each of previous transactions tx[0]..tx[K-1] at their output K-1. # Transaction tx[K] is a child of each of previous transactions tx[0]..tx[K-1] at their output K-1.
vout = i - j - 1 vout = i - j - 1
inputs.append({'txid': tx_id[j], 'vout': vout}) inputs.append(wallet.get_utxo(txid=tx_id[j], vout=vout))
inputs_value += self.nodes[0].gettxout(tx, vout)['value']
self.log.debug('inputs={}'.format(inputs))
self.log.debug('inputs_value={}'.format(inputs_value))
# Prepare outputs. # Prepare outputs.
tx_count = i + 1 tx_count = i + 1
if tx_count < size: if tx_count < size:
# Transaction tx[K] is an ancestor of each of subsequent transactions tx[K+1]..tx[N-1]. # Transaction tx[K] is an ancestor of each of subsequent transactions tx[K+1]..tx[N-1].
n_outputs = size - tx_count n_outputs = size - tx_count
output_value = ((inputs_value - fee) / Decimal(n_outputs)).quantize(Decimal('0.00000001'))
outputs = {}
for _ in range(n_outputs):
outputs[self.get_new_address()] = output_value
else: else:
output_value = (inputs_value - fee).quantize(Decimal('0.00000001')) n_outputs = 1
outputs = {end_address: output_value}
self.log.debug('output_value={}'.format(output_value))
self.log.debug('outputs={}'.format(outputs))
# Create a new transaction. # Create a new transaction.
unsigned_raw_tx = self.nodes[0].createrawtransaction(inputs, outputs) new_tx = wallet.send_self_transfer_multi(
signed_raw_tx = self.nodes[0].signrawtransactionwithkey(unsigned_raw_tx, self.priv_keys) from_node=self.nodes[0],
tx_id.append(self.nodes[0].sendrawtransaction(signed_raw_tx['hex'])) utxos_to_spend=inputs,
tx_size.append(self.nodes[0].getmempoolentry(tx_id[-1])['vsize']) num_outputs=n_outputs,
fee_per_output=ceil(fee / n_outputs)
)
tx_id.append(new_tx['txid'])
tx_size.append(new_tx['tx'].get_vsize())
if tx_count in n_tx_to_mine: if tx_count in n_tx_to_mine:
# The created transactions are mined into blocks by batches. # The created transactions are mined into blocks by batches.