diff options
Diffstat (limited to 'test/functional/test_framework')
-rw-r--r-- | test/functional/test_framework/wallet.py | 55 |
1 files changed, 32 insertions, 23 deletions
diff --git a/test/functional/test_framework/wallet.py b/test/functional/test_framework/wallet.py index 2164627781..b671ecbaf2 100644 --- a/test/functional/test_framework/wallet.py +++ b/test/functional/test_framework/wallet.py @@ -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,6 +335,17 @@ class MiniWallet: self.scan_tx(from_node.decoderawtransaction(tx_hex)) return txid + def send_self_transfer_chain(self, *, from_node, chain_length, utxo_to_spend=None): + """Create and send a "chain" of chain_length transactions. The nth transaction in + the chain is a child of the n-1th transaction and parent of the n+1th transaction. + + Returns the chaintip (nth) utxo + """ + chaintip_utxo = utxo_to_spend or self.get_utxo() + for _ in range(chain_length): + chaintip_utxo = self.send_self_transfer(utxo_to_spend=chaintip_utxo, from_node=from_node)["new_utxo"] + return chaintip_utxo + def getnewdestination(address_type='bech32m'): """Generate a random destination of the specified type and return the @@ -409,23 +438,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 |