test: use MiniWallet to simplify mempool_package_limits.py tests

Moved `bulk_transaction` into MiniWallet class as `_bulk_tx` private
helper method to be used when the newly added `target_weight` option is
passed to `create_self_transfer*`
This commit is contained in:
Andreas Kouloumos
2022-06-15 15:43:56 +03:00
parent ce3b75690d
commit 1d6b438ef0
2 changed files with 94 additions and 249 deletions

View File

@ -7,7 +7,6 @@
from copy import deepcopy
from decimal import Decimal
from enum import Enum
from random import choice
from typing import (
Any,
List,
@ -104,6 +103,16 @@ class MiniWallet:
def _create_utxo(self, *, txid, vout, value, height):
return {"txid": txid, "vout": vout, "value": value, "height": height}
def _bulk_tx(self, tx, target_weight):
"""Pad a transaction with extra outputs until it reaches a target weight (or higher).
returns the tx
"""
assert_greater_than_or_equal(target_weight, tx.get_weight())
while tx.get_weight() < target_weight:
script_pubkey = ( b"6a4d0200" # OP_RETURN OP_PUSH2 512 bytes
+ b"01" * 512 )
tx.vout.append(CTxOut(0, script_pubkey))
def get_balance(self):
return sum(u['value'] for u in self._utxos)
@ -235,6 +244,7 @@ class MiniWallet:
amount_per_output=0,
sequence=0,
fee_per_output=1000,
target_weight=0
):
"""
Create and return a transaction that spends the given UTXOs and creates a
@ -265,6 +275,10 @@ class MiniWallet:
outputs_value_total = inputs_value_total - fee_per_output * num_outputs
for o in tx.vout:
o.nValue = amount_per_output or (outputs_value_total // num_outputs)
if target_weight:
self._bulk_tx(tx, target_weight)
txid = tx.rehash()
return {
"new_utxos": [self._create_utxo(
@ -278,7 +292,7 @@ class MiniWallet:
"tx": tx,
}
def create_self_transfer(self, *, fee_rate=Decimal("0.003"), fee=Decimal("0"), utxo_to_spend=None, locktime=0, sequence=0):
def create_self_transfer(self, *, fee_rate=Decimal("0.003"), fee=Decimal("0"), utxo_to_spend=None, locktime=0, sequence=0, target_weight=0):
"""Create and return a tx with the specified fee. If fee is 0, use fee_rate, where the resulting fee may be exact or at most one satoshi higher than needed."""
utxo_to_spend = utxo_to_spend or self.get_utxo()
assert fee_rate >= 0
@ -305,9 +319,13 @@ class MiniWallet:
tx.wit.vtxinwit[0].scriptWitness.stack = [CScript([OP_TRUE]), bytes([LEAF_VERSION_TAPSCRIPT]) + self._internal_key]
else:
assert False
tx_hex = tx.serialize().hex()
assert_equal(tx.get_vsize(), vsize)
if target_weight:
self._bulk_tx(tx, target_weight)
tx_hex = tx.serialize().hex()
new_utxo = self._create_utxo(txid=tx.rehash(), vout=0, value=send_value, height=0)
return {"txid": new_utxo["txid"], "wtxid": tx.getwtxid(), "hex": tx_hex, "tx": tx, "new_utxo": new_utxo}
@ -317,7 +335,6 @@ class MiniWallet:
self.scan_tx(from_node.decoderawtransaction(tx_hex))
return txid
def getnewdestination(address_type='bech32m'):
"""Generate a random destination of the specified type and return the
corresponding public key, scriptPubKey and address. Supported types are
@ -409,23 +426,3 @@ def create_raw_chain(node, first_coin, address, privkeys, chain_length=25):
chain_txns.append(tx)
return (chain_hex, chain_txns)
def bulk_transaction(tx, node, target_weight, privkeys, prevtxs=None):
"""Pad a transaction with extra outputs until it reaches a target weight (or higher).
returns CTransaction object
"""
tx_heavy = deepcopy(tx)
assert_greater_than_or_equal(target_weight, tx_heavy.get_weight())
while tx_heavy.get_weight() < target_weight:
random_spk = "6a4d0200" # OP_RETURN OP_PUSH2 512 bytes
for _ in range(512*2):
random_spk += choice("0123456789ABCDEF")
tx_heavy.vout.append(CTxOut(0, bytes.fromhex(random_spk)))
# Re-sign the transaction
if privkeys:
signed = node.signrawtransactionwithkey(tx_heavy.serialize().hex(), privkeys, prevtxs)
return tx_from_hex(signed["hex"])
# OP_TRUE
tx_heavy.wit.vtxinwit = [CTxInWitness()]
tx_heavy.wit.vtxinwit[0].scriptWitness.stack = [CScript([OP_TRUE])]
return tx_heavy