Skip to content

Commit a650fec

Browse files
committed
Update test_framework/wallet.py file
1 parent d48b032 commit a650fec

File tree

1 file changed

+18
-8
lines changed

1 file changed

+18
-8
lines changed

test/functional/test_framework/wallet.py

+18-8
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from copy import deepcopy
88
from decimal import Decimal
99
from enum import Enum
10+
import math
1011
from typing import (
1112
Any,
1213
Optional,
@@ -33,10 +34,13 @@
3334
CTxInWitness,
3435
CTxOut,
3536
hash256,
37+
ser_compact_size,
38+
WITNESS_SCALE_FACTOR,
3639
)
3740
from test_framework.script import (
3841
CScript,
3942
LEAF_VERSION_TAPSCRIPT,
43+
OP_1,
4044
OP_NOP,
4145
OP_RETURN,
4246
OP_TRUE,
@@ -52,9 +56,8 @@
5256
from test_framework.util import (
5357
assert_equal,
5458
assert_greater_than_or_equal,
59+
get_fee,
5560
)
56-
from enum import Enum
57-
from test_framework.blocktools import COINBASE_MATURITY
5861
from test_framework.wallet_util import generate_keypair
5962

6063
DEFAULT_FEE = Decimal("0.0001")
@@ -109,7 +112,7 @@ def __init__(self, test_node, *, mode=MiniWalletMode.ADDRESS_OP_TRUE, tag_name=N
109112

110113
# When the pre-mined test framework chain is used, it contains coinbase
111114
# outputs to the MiniWallet's default address in blocks 76-100
112-
# (see method BGLTestFramework._initialize_chain())
115+
# (see method BitcoinTestFramework._initialize_chain())
113116
# The MiniWallet needs to rescan_utxos() in order to account
114117
# for those mature UTXOs, so that all txs spend confirmed coins
115118
self.rescan_utxos()
@@ -121,13 +124,16 @@ def _bulk_tx(self, tx, target_weight):
121124
"""Pad a transaction with extra outputs until it reaches a target weight (or higher).
122125
returns the tx
123126
"""
124-
tx.vout.append(CTxOut(nValue=0, scriptPubKey=CScript([OP_RETURN, b'a'])))
127+
tx.vout.append(CTxOut(nValue=0, scriptPubKey=CScript([OP_RETURN])))
128+
# determine number of needed padding bytes by converting weight difference to vbytes
125129
dummy_vbytes = (target_weight - tx.get_weight() + 3) // 4
126-
tx.vout[-1].scriptPubKey = CScript([OP_RETURN, b'a' * dummy_vbytes])
127-
# Lower bound should always be off by at most 3
130+
# compensate for the increase of the compact-size encoded script length
131+
# (note that the length encoding of the unpadded output script needs one byte)
132+
dummy_vbytes -= len(ser_compact_size(dummy_vbytes)) - 1
133+
tx.vout[-1].scriptPubKey = CScript([OP_RETURN] + [OP_1] * dummy_vbytes)
134+
# Actual weight should be at most 3 higher than target weight
128135
assert_greater_than_or_equal(tx.get_weight(), target_weight)
129-
# Higher bound should always be off by at most 3 + 12 weight (for encoding the length)
130-
assert_greater_than_or_equal(target_weight + 15, tx.get_weight())
136+
assert_greater_than_or_equal(target_weight + 3, tx.get_weight())
131137

132138
def get_balance(self):
133139
return sum(u['value'] for u in self._utxos)
@@ -369,6 +375,10 @@ def create_self_transfer(
369375
vsize = Decimal(168) # P2PK (73 bytes scriptSig + 35 bytes scriptPubKey + 60 bytes other)
370376
else:
371377
assert False
378+
if target_weight and not fee: # respect fee_rate if target weight is passed
379+
# the actual weight might be off by 3 WUs, so calculate based on that (see self._bulk_tx)
380+
max_actual_weight = target_weight + 3
381+
fee = get_fee(math.ceil(max_actual_weight / WITNESS_SCALE_FACTOR), fee_rate)
372382
send_value = utxo_to_spend["value"] - (fee or (fee_rate * vsize / 1000))
373383

374384
# create tx

0 commit comments

Comments
 (0)