0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-02-02 09:46:52 -05:00

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

@ -6,28 +6,16 @@
from decimal import Decimal
from test_framework.address import ADDRESS_BCRT1_P2WSH_OP_TRUE
from test_framework.blocktools import COINBASE_MATURITY
from test_framework.test_framework import BitcoinTestFramework
from test_framework.messages import (
COIN,
CTransaction,
CTxInWitness,
tx_from_hex,
WITNESS_SCALE_FACTOR,
)
from test_framework.script import (
CScript,
OP_TRUE,
)
from test_framework.util import (
assert_equal,
)
from test_framework.wallet import (
bulk_transaction,
create_child_with_parents,
make_chain,
DEFAULT_FEE,
)
from test_framework.wallet import MiniWallet
class MempoolPackageLimitsTest(BitcoinTestFramework):
def set_test_params(self):
@ -35,19 +23,10 @@ class MempoolPackageLimitsTest(BitcoinTestFramework):
self.setup_clean_chain = True
def run_test(self):
self.log.info("Generate blocks to create UTXOs")
node = self.nodes[0]
self.privkeys = [node.get_deterministic_priv_key().key]
self.address = node.get_deterministic_priv_key().address
self.coins = []
# The last 100 coinbase transactions are premature
for b in self.generatetoaddress(node, 200, self.address)[:100]:
coinbase = node.getblock(blockhash=b, verbosity=2)["tx"][0]
self.coins.append({
"txid": coinbase["txid"],
"amount": coinbase["vout"][0]["value"],
"scriptPubKey": coinbase["vout"][0]["scriptPubKey"],
})
self.wallet = MiniWallet(self.nodes[0])
# Add enough mature utxos to the wallet so that all txs spend confirmed coins.
self.generate(self.wallet, 35)
self.generate(self.nodes[0], COINBASE_MATURITY)
self.test_chain_limits()
self.test_desc_count_limits()
@ -64,22 +43,19 @@ class MempoolPackageLimitsTest(BitcoinTestFramework):
def test_chain_limits_helper(self, mempool_count, package_count):
node = self.nodes[0]
assert_equal(0, node.getmempoolinfo()["size"])
first_coin = self.coins.pop()
spk = None
txid = first_coin["txid"]
chain_hex = []
chain_txns = []
value = first_coin["amount"]
chaintip_utxo = None
for i in range(mempool_count + package_count):
(tx, txhex, value, spk) = make_chain(node, self.address, self.privkeys, txid, value, 0, spk)
txid = tx.rehash()
tx = self.wallet.create_self_transfer(utxo_to_spend=chaintip_utxo)
chaintip_utxo = tx["new_utxo"]
if i < mempool_count:
node.sendrawtransaction(txhex)
# in-mempool transactions
txid = self.wallet.sendrawtransaction(from_node=node, tx_hex=tx["hex"])
assert_equal(node.getmempoolentry(txid)["ancestorcount"], i + 1)
else:
chain_hex.append(txhex)
chain_txns.append(tx)
# in-package transactions
chain_hex.append(tx["hex"])
testres_too_long = node.testmempoolaccept(rawtxs=chain_hex)
for txres in testres_too_long:
assert_equal(txres["package-error"], "package-mempool-limits")
@ -125,49 +101,28 @@ class MempoolPackageLimitsTest(BitcoinTestFramework):
assert_equal(0, node.getmempoolinfo()["size"])
self.log.info("Check that in-mempool and in-package descendants are calculated properly in packages")
# Top parent in mempool, M1
first_coin = self.coins.pop()
parent_value = (first_coin["amount"] - Decimal("0.0002")) / 2 # Deduct reasonable fee and make 2 outputs
inputs = [{"txid": first_coin["txid"], "vout": 0}]
outputs = [{self.address : parent_value}, {ADDRESS_BCRT1_P2WSH_OP_TRUE : parent_value}]
rawtx = node.createrawtransaction(inputs, outputs)
parent_signed = node.signrawtransactionwithkey(hexstring=rawtx, privkeys=self.privkeys)
assert parent_signed["complete"]
parent_tx = tx_from_hex(parent_signed["hex"])
parent_txid = parent_tx.rehash()
node.sendrawtransaction(parent_signed["hex"])
m1_utxos = self.wallet.send_self_transfer_multi(from_node=node, num_outputs=2)['new_utxos']
package_hex = []
# Chain A
spk = parent_tx.vout[0].scriptPubKey.hex()
value = parent_value
txid = parent_txid
chain_a_utxo = m1_utxos[0]
for i in range(12):
(tx, txhex, value, spk) = make_chain(node, self.address, self.privkeys, txid, value, 0, spk)
txid = tx.rehash()
tx = self.wallet.create_self_transfer(utxo_to_spend=chain_a_utxo)
chain_a_utxo = tx["new_utxo"]
if i < 11: # M2a... M12a
node.sendrawtransaction(txhex)
self.wallet.sendrawtransaction(from_node=node, tx_hex=tx["hex"])
else: # Pa
package_hex.append(txhex)
package_hex.append(tx["hex"])
# Chain B
value = parent_value - Decimal("0.0001")
rawtx_b = node.createrawtransaction([{"txid": parent_txid, "vout": 1}], {self.address : value})
tx_child_b = tx_from_hex(rawtx_b) # M2b
tx_child_b.wit.vtxinwit = [CTxInWitness()]
tx_child_b.wit.vtxinwit[0].scriptWitness.stack = [CScript([OP_TRUE])]
tx_child_b_hex = tx_child_b.serialize().hex()
node.sendrawtransaction(tx_child_b_hex)
spk = tx_child_b.vout[0].scriptPubKey.hex()
txid = tx_child_b.rehash()
for i in range(12):
(tx, txhex, value, spk) = make_chain(node, self.address, self.privkeys, txid, value, 0, spk)
txid = tx.rehash()
if i < 11: # M3b... M13b
node.sendrawtransaction(txhex)
chain_b_utxo = m1_utxos[1]
for i in range(13):
tx = self.wallet.create_self_transfer(utxo_to_spend=chain_b_utxo)
chain_b_utxo = tx["new_utxo"]
if i < 12: # M3b... M13b
self.wallet.sendrawtransaction(from_node=node, tx_hex=tx["hex"])
else: # Pb
package_hex.append(txhex)
package_hex.append(tx["hex"])
assert_equal(24, node.getmempoolinfo()["size"])
assert_equal(2, len(package_hex))
@ -200,41 +155,20 @@ class MempoolPackageLimitsTest(BitcoinTestFramework):
node = self.nodes[0]
package_hex = []
# M1
first_coin_a = self.coins.pop()
parent_value = (first_coin_a["amount"] - DEFAULT_FEE) / 2 # Deduct reasonable fee and make 2 outputs
inputs = [{"txid": first_coin_a["txid"], "vout": 0}]
outputs = [{self.address : parent_value}, {ADDRESS_BCRT1_P2WSH_OP_TRUE : parent_value}]
rawtx = node.createrawtransaction(inputs, outputs)
parent_signed = node.signrawtransactionwithkey(hexstring=rawtx, privkeys=self.privkeys)
assert parent_signed["complete"]
parent_tx = tx_from_hex(parent_signed["hex"])
parent_txid = parent_tx.rehash()
node.sendrawtransaction(parent_signed["hex"])
m1_utxos = self.wallet.send_self_transfer_multi(from_node=node, num_outputs=2)['new_utxos']
# Chain M2...M24
spk = parent_tx.vout[0].scriptPubKey.hex()
value = parent_value
txid = parent_txid
for i in range(23): # M2...M24
(tx, txhex, value, spk) = make_chain(node, self.address, self.privkeys, txid, value, 0, spk)
txid = tx.rehash()
node.sendrawtransaction(txhex)
chain_utxo = m1_utxos[0]
for _ in range(23): # M2...M24
chain_utxo = self.wallet.send_self_transfer(from_node=node, utxo_to_spend=chain_utxo)["new_utxo"]
# P1
value_p1 = (parent_value - DEFAULT_FEE)
rawtx_p1 = node.createrawtransaction([{"txid": parent_txid, "vout": 1}], [{self.address : value_p1}])
tx_child_p1 = tx_from_hex(rawtx_p1)
tx_child_p1.wit.vtxinwit = [CTxInWitness()]
tx_child_p1.wit.vtxinwit[0].scriptWitness.stack = [CScript([OP_TRUE])]
tx_child_p1_hex = tx_child_p1.serialize().hex()
txid_child_p1 = tx_child_p1.rehash()
package_hex.append(tx_child_p1_hex)
tx_child_p1_spk = tx_child_p1.vout[0].scriptPubKey.hex()
p1_tx = self.wallet.create_self_transfer(utxo_to_spend=m1_utxos[1])
package_hex.append(p1_tx["hex"])
# P2
(_, tx_child_p2_hex, _, _) = make_chain(node, self.address, self.privkeys, txid_child_p1, value_p1, 0, tx_child_p1_spk)
package_hex.append(tx_child_p2_hex)
p2_tx = self.wallet.create_self_transfer(utxo_to_spend=p1_tx["new_utxo"])
package_hex.append(p2_tx["hex"])
assert_equal(24, node.getmempoolinfo()["size"])
assert_equal(2, len(package_hex))
@ -266,32 +200,25 @@ class MempoolPackageLimitsTest(BitcoinTestFramework):
node = self.nodes[0]
assert_equal(0, node.getmempoolinfo()["size"])
package_hex = []
parents_tx = []
values = []
scripts = []
pc_parent_utxos = []
self.log.info("Check that in-mempool and in-package ancestors are calculated properly in packages")
# Two chains of 13 transactions each
for _ in range(2):
spk = None
top_coin = self.coins.pop()
txid = top_coin["txid"]
value = top_coin["amount"]
chaintip_utxo = None
for i in range(13):
(tx, txhex, value, spk) = make_chain(node, self.address, self.privkeys, txid, value, 0, spk)
txid = tx.rehash()
tx = self.wallet.create_self_transfer(utxo_to_spend=chaintip_utxo)
chaintip_utxo = tx["new_utxo"]
if i < 12:
node.sendrawtransaction(txhex)
self.wallet.sendrawtransaction(from_node=node, tx_hex=tx["hex"])
else: # Save the 13th transaction for the package
package_hex.append(txhex)
parents_tx.append(tx)
scripts.append(spk)
values.append(value)
package_hex.append(tx["hex"])
pc_parent_utxos.append(chaintip_utxo)
# Child Pc
child_hex = create_child_with_parents(node, self.address, self.privkeys, parents_tx, values, scripts)
package_hex.append(child_hex)
pc_hex = self.wallet.create_self_transfer_multi(utxos_to_spend=pc_parent_utxos)["hex"]
package_hex.append(pc_hex)
assert_equal(24, node.getmempoolinfo()["size"])
assert_equal(3, len(package_hex))
@ -321,45 +248,32 @@ class MempoolPackageLimitsTest(BitcoinTestFramework):
"""
node = self.nodes[0]
assert_equal(0, node.getmempoolinfo()["size"])
parents_tx = []
values = []
scripts = []
pc_parent_utxos = []
self.log.info("Check that in-mempool and in-package ancestors are calculated properly in packages")
# Two chains of 12 transactions each
for _ in range(2):
spk = None
top_coin = self.coins.pop()
txid = top_coin["txid"]
value = top_coin["amount"]
chaintip_utxo = None
for i in range(12):
(tx, txhex, value, spk) = make_chain(node, self.address, self.privkeys, txid, value, 0, spk)
txid = tx.rehash()
value -= Decimal("0.0001")
node.sendrawtransaction(txhex)
chaintip_utxo = self.wallet.send_self_transfer(from_node=node, utxo_to_spend=chaintip_utxo)["new_utxo"]
if i == 11:
# last 2 transactions will be the parents of Pc
parents_tx.append(tx)
values.append(value)
scripts.append(spk)
pc_parent_utxos.append(chaintip_utxo)
# Child Pc
pc_hex = create_child_with_parents(node, self.address, self.privkeys, parents_tx, values, scripts)
pc_tx = tx_from_hex(pc_hex)
pc_value = sum(values) - Decimal("0.0002")
pc_spk = pc_tx.vout[0].scriptPubKey.hex()
pc_tx = self.wallet.create_self_transfer_multi(utxos_to_spend=pc_parent_utxos)
# Child Pd
(_, pd_hex, _, _) = make_chain(node, self.address, self.privkeys, pc_tx.rehash(), pc_value, 0, pc_spk)
pd_tx = self.wallet.create_self_transfer(utxo_to_spend=pc_tx["new_utxos"][0])
assert_equal(24, node.getmempoolinfo()["size"])
testres_too_long = node.testmempoolaccept(rawtxs=[pc_hex, pd_hex])
testres_too_long = node.testmempoolaccept(rawtxs=[pc_tx["hex"], pd_tx["hex"]])
for txres in testres_too_long:
assert_equal(txres["package-error"], "package-mempool-limits")
# Clear mempool and check that the package passes now
self.generate(node, 1)
assert all([res["allowed"] for res in node.testmempoolaccept(rawtxs=[pc_hex, pd_hex])])
assert all([res["allowed"] for res in node.testmempoolaccept(rawtxs=[pc_tx["hex"], pd_tx["hex"]])])
def test_anc_count_limits_bushy(self):
"""Create a tree with 20 transactions in the mempool and 6 in the package:
@ -375,31 +289,18 @@ class MempoolPackageLimitsTest(BitcoinTestFramework):
node = self.nodes[0]
assert_equal(0, node.getmempoolinfo()["size"])
package_hex = []
parent_txns = []
parent_values = []
scripts = []
pc_parent_utxos = []
for _ in range(5): # Make package transactions P0 ... P4
gp_tx = []
gp_values = []
gp_scripts = []
pc_grandparent_utxos = []
for _ in range(4): # Make mempool transactions M(4i+1)...M(4i+4)
parent_coin = self.coins.pop()
value = parent_coin["amount"]
txid = parent_coin["txid"]
(tx, txhex, value, spk) = make_chain(node, self.address, self.privkeys, txid, value)
gp_tx.append(tx)
gp_values.append(value)
gp_scripts.append(spk)
node.sendrawtransaction(txhex)
pc_grandparent_utxos.append(self.wallet.send_self_transfer(from_node=node)["new_utxo"])
# Package transaction Pi
pi_hex = create_child_with_parents(node, self.address, self.privkeys, gp_tx, gp_values, gp_scripts)
package_hex.append(pi_hex)
pi_tx = tx_from_hex(pi_hex)
parent_txns.append(pi_tx)
parent_values.append(Decimal(pi_tx.vout[0].nValue) / COIN)
scripts.append(pi_tx.vout[0].scriptPubKey.hex())
pi_tx = self.wallet.create_self_transfer_multi(utxos_to_spend=pc_grandparent_utxos)
package_hex.append(pi_tx["hex"])
pc_parent_utxos.append(pi_tx["new_utxos"][0])
# Package transaction PC
package_hex.append(create_child_with_parents(node, self.address, self.privkeys, parent_txns, parent_values, scripts))
pc_hex = self.wallet.create_self_transfer_multi(utxos_to_spend=pc_parent_utxos)["hex"]
package_hex.append(pc_hex)
assert_equal(20, node.getmempoolinfo()["size"])
assert_equal(6, len(package_hex))
@ -424,51 +325,30 @@ class MempoolPackageLimitsTest(BitcoinTestFramework):
"""
node = self.nodes[0]
assert_equal(0, node.getmempoolinfo()["size"])
parents_tx = []
values = []
scripts = []
parent_utxos = []
target_weight = WITNESS_SCALE_FACTOR * 1000 * 30 # 30KvB
high_fee = Decimal("0.003") # 10 sats/vB
self.log.info("Check that in-mempool and in-package ancestor size limits are calculated properly in packages")
# Mempool transactions A and B
for _ in range(2):
spk = None
top_coin = self.coins.pop()
txid = top_coin["txid"]
value = top_coin["amount"]
(tx, _, _, _) = make_chain(node, self.address, self.privkeys, txid, value, 0, spk, high_fee)
bulked_tx = bulk_transaction(tx, node, target_weight, self.privkeys)
node.sendrawtransaction(bulked_tx.serialize().hex())
parents_tx.append(bulked_tx)
values.append(Decimal(bulked_tx.vout[0].nValue) / COIN)
scripts.append(bulked_tx.vout[0].scriptPubKey.hex())
bulked_tx = self.wallet.create_self_transfer(target_weight=target_weight)
self.wallet.sendrawtransaction(from_node=node, tx_hex=bulked_tx["hex"])
parent_utxos.append(bulked_tx["new_utxo"])
# Package transaction C
small_pc_hex = create_child_with_parents(node, self.address, self.privkeys, parents_tx, values, scripts, high_fee)
pc_tx = bulk_transaction(tx_from_hex(small_pc_hex), node, target_weight, self.privkeys)
pc_value = Decimal(pc_tx.vout[0].nValue) / COIN
pc_spk = pc_tx.vout[0].scriptPubKey.hex()
pc_hex = pc_tx.serialize().hex()
pc_tx = self.wallet.create_self_transfer_multi(utxos_to_spend=parent_utxos, fee_per_output=int(high_fee * COIN), target_weight=target_weight)
# Package transaction D
(small_pd, _, val, spk) = make_chain(node, self.address, self.privkeys, pc_tx.rehash(), pc_value, 0, pc_spk, high_fee)
prevtxs = [{
"txid": pc_tx.rehash(),
"vout": 0,
"scriptPubKey": spk,
"amount": val,
}]
pd_tx = bulk_transaction(small_pd, node, target_weight, self.privkeys, prevtxs)
pd_hex = pd_tx.serialize().hex()
pd_tx = self.wallet.create_self_transfer(utxo_to_spend=pc_tx["new_utxos"][0], target_weight=target_weight)
assert_equal(2, node.getmempoolinfo()["size"])
testres_too_heavy = node.testmempoolaccept(rawtxs=[pc_hex, pd_hex])
testres_too_heavy = node.testmempoolaccept(rawtxs=[pc_tx["hex"], pd_tx["hex"]])
for txres in testres_too_heavy:
assert_equal(txres["package-error"], "package-mempool-limits")
# Clear mempool and check that the package passes now
self.generate(node, 1)
assert all([res["allowed"] for res in node.testmempoolaccept(rawtxs=[pc_hex, pd_hex])])
assert all([res["allowed"] for res in node.testmempoolaccept(rawtxs=[pc_tx["hex"], pd_tx["hex"]])])
def test_desc_size_limits(self):
"""Create 3 mempool transactions and 2 package transactions (25KvB each):
@ -486,50 +366,18 @@ class MempoolPackageLimitsTest(BitcoinTestFramework):
high_fee = Decimal("0.0021") # 10 sats/vB
self.log.info("Check that in-mempool and in-package descendant sizes are calculated properly in packages")
# Top parent in mempool, Ma
first_coin = self.coins.pop()
parent_value = (first_coin["amount"] - high_fee) / 2 # Deduct fee and make 2 outputs
inputs = [{"txid": first_coin["txid"], "vout": 0}]
outputs = [{self.address : parent_value}, {ADDRESS_BCRT1_P2WSH_OP_TRUE: parent_value}]
rawtx = node.createrawtransaction(inputs, outputs)
parent_tx = bulk_transaction(tx_from_hex(rawtx), node, target_weight, self.privkeys)
node.sendrawtransaction(parent_tx.serialize().hex())
ma_tx = self.wallet.create_self_transfer_multi(num_outputs=2, fee_per_output=int(high_fee / 2 * COIN), target_weight=target_weight)
self.wallet.sendrawtransaction(from_node=node, tx_hex=ma_tx["hex"])
package_hex = []
for j in range(2): # Two legs (left and right)
# Mempool transaction (Mb and Mc)
mempool_tx = CTransaction()
spk = parent_tx.vout[j].scriptPubKey.hex()
value = Decimal(parent_tx.vout[j].nValue) / COIN
txid = parent_tx.rehash()
prevtxs = [{
"txid": txid,
"vout": j,
"scriptPubKey": spk,
"amount": value,
}]
if j == 0: # normal key
(tx_small, _, _, _) = make_chain(node, self.address, self.privkeys, txid, value, j, spk, high_fee)
mempool_tx = bulk_transaction(tx_small, node, target_weight, self.privkeys, prevtxs)
else: # OP_TRUE
inputs = [{"txid": txid, "vout": 1}]
outputs = {self.address: value - high_fee}
small_tx = tx_from_hex(node.createrawtransaction(inputs, outputs))
mempool_tx = bulk_transaction(small_tx, node, target_weight, None, prevtxs)
node.sendrawtransaction(mempool_tx.serialize().hex())
mempool_tx = self.wallet.create_self_transfer(utxo_to_spend=ma_tx["new_utxos"][j], target_weight=target_weight)
self.wallet.sendrawtransaction(from_node=node, tx_hex=mempool_tx["hex"])
# Package transaction (Pd and Pe)
spk = mempool_tx.vout[0].scriptPubKey.hex()
value = Decimal(mempool_tx.vout[0].nValue) / COIN
txid = mempool_tx.rehash()
(tx_small, _, _, _) = make_chain(node, self.address, self.privkeys, txid, value, 0, spk, high_fee)
prevtxs = [{
"txid": txid,
"vout": 0,
"scriptPubKey": spk,
"amount": value,
}]
package_tx = bulk_transaction(tx_small, node, target_weight, self.privkeys, prevtxs)
package_hex.append(package_tx.serialize().hex())
package_tx = self.wallet.create_self_transfer(utxo_to_spend=mempool_tx["new_utxo"], target_weight=target_weight)
package_hex.append(package_tx["hex"])
assert_equal(3, node.getmempoolinfo()["size"])
assert_equal(2, len(package_hex))

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