Skip to content

Commit d119f2e

Browse files
author
John Newbery
committed
[tests] Fix style warnings in feature_fee_estimation.py
1 parent 4cad916 commit d119f2e

File tree

1 file changed

+60
-61
lines changed

1 file changed

+60
-61
lines changed

test/functional/feature_fee_estimation.py

+60-61
Original file line numberDiff line numberDiff line change
@@ -3,39 +3,41 @@
33
# Distributed under the MIT software license, see the accompanying
44
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
55
"""Test fee estimation code."""
6+
from decimal import Decimal
7+
import random
68

7-
from test_framework.test_framework import BitcoinTestFramework
8-
from test_framework.util import *
9-
from test_framework.script import CScript, OP_1, OP_DROP, OP_2, OP_HASH160, OP_EQUAL, hash160, OP_TRUE
109
from test_framework.mininode import CTransaction, CTxIn, CTxOut, COutPoint, ToHex, COIN
10+
from test_framework.script import CScript, OP_1, OP_DROP, OP_2, OP_HASH160, OP_EQUAL, hash160, OP_TRUE
11+
from test_framework.test_framework import BitcoinTestFramework
12+
from test_framework.util import satoshi_round, sync_mempools, sync_blocks, connect_nodes, assert_greater_than
1113

1214
# Construct 2 trivial P2SH's and the ScriptSigs that spend them
1315
# So we can create many transactions without needing to spend
1416
# time signing.
15-
redeem_script_1 = CScript([OP_1, OP_DROP])
16-
redeem_script_2 = CScript([OP_2, OP_DROP])
17-
P2SH_1 = CScript([OP_HASH160, hash160(redeem_script_1), OP_EQUAL])
18-
P2SH_2 = CScript([OP_HASH160, hash160(redeem_script_2), OP_EQUAL])
17+
REDEEM_SCRIPT_1 = CScript([OP_1, OP_DROP])
18+
REDEEM_SCRIPT_2 = CScript([OP_2, OP_DROP])
19+
P2SH_1 = CScript([OP_HASH160, hash160(REDEEM_SCRIPT_1), OP_EQUAL])
20+
P2SH_2 = CScript([OP_HASH160, hash160(REDEEM_SCRIPT_2), OP_EQUAL])
1921

2022
# Associated ScriptSig's to spend satisfy P2SH_1 and P2SH_2
21-
SCRIPT_SIG = [CScript([OP_TRUE, redeem_script_1]), CScript([OP_TRUE, redeem_script_2])]
23+
SCRIPT_SIG = [CScript([OP_TRUE, REDEEM_SCRIPT_1]), CScript([OP_TRUE, REDEEM_SCRIPT_2])]
2224

2325
global log
2426

2527
def small_txpuzzle_randfee(from_node, conflist, unconflist, amount, min_fee, fee_increment):
26-
"""
27-
Create and send a transaction with a random fee.
28+
"""Create and send a transaction with a random fee.
29+
2830
The transaction pays to a trivial P2SH script, and assumes that its inputs
2931
are of the same form.
3032
The function takes a list of confirmed outputs and unconfirmed outputs
3133
and attempts to use the confirmed list first for its inputs.
3234
It adds the newly created outputs to the unconfirmed list.
33-
Returns (raw transaction, fee)
34-
"""
35+
Returns (raw transaction, fee)."""
36+
3537
# It's best to exponentially distribute our random fees
3638
# because the buckets are exponentially spaced.
3739
# Exponentially distributed from 1-128 * fee_increment
38-
rand_fee = float(fee_increment)*(1.1892**random.randint(0,28))
40+
rand_fee = float(fee_increment) * (1.1892 ** random.randint(0, 28))
3941
# Total fee ranges from min_fee to min_fee + 127*fee_increment
4042
fee = min_fee - fee_increment + satoshi_round(rand_fee)
4143
tx = CTransaction()
@@ -50,83 +52,81 @@ def small_txpuzzle_randfee(from_node, conflist, unconflist, amount, min_fee, fee
5052
total_in += t["amount"]
5153
tx.vin.append(CTxIn(COutPoint(int(t["txid"], 16), t["vout"]), b""))
5254
if total_in <= amount + fee:
53-
raise RuntimeError("Insufficient funds: need %d, have %d"%(amount+fee, total_in))
54-
tx.vout.append(CTxOut(int((total_in - amount - fee)*COIN), P2SH_1))
55-
tx.vout.append(CTxOut(int(amount*COIN), P2SH_2))
55+
raise RuntimeError("Insufficient funds: need %d, have %d" % (amount + fee, total_in))
56+
tx.vout.append(CTxOut(int((total_in - amount - fee) * COIN), P2SH_1))
57+
tx.vout.append(CTxOut(int(amount * COIN), P2SH_2))
5658
# These transactions don't need to be signed, but we still have to insert
5759
# the ScriptSig that will satisfy the ScriptPubKey.
5860
for inp in tx.vin:
5961
inp.scriptSig = SCRIPT_SIG[inp.prevout.n]
6062
txid = from_node.sendrawtransaction(ToHex(tx), True)
61-
unconflist.append({ "txid" : txid, "vout" : 0 , "amount" : total_in - amount - fee})
62-
unconflist.append({ "txid" : txid, "vout" : 1 , "amount" : amount})
63+
unconflist.append({"txid": txid, "vout": 0, "amount": total_in - amount - fee})
64+
unconflist.append({"txid": txid, "vout": 1, "amount": amount})
6365

6466
return (ToHex(tx), fee)
6567

66-
def split_inputs(from_node, txins, txouts, initial_split = False):
67-
"""
68-
We need to generate a lot of inputs so we can generate a ton of transactions.
68+
def split_inputs(from_node, txins, txouts, initial_split=False):
69+
"""Generate a lot of inputs so we can generate a ton of transactions.
70+
6971
This function takes an input from txins, and creates and sends a transaction
7072
which splits the value into 2 outputs which are appended to txouts.
7173
Previously this was designed to be small inputs so they wouldn't have
72-
a high coin age when the notion of priority still existed.
73-
"""
74+
a high coin age when the notion of priority still existed."""
75+
7476
prevtxout = txins.pop()
7577
tx = CTransaction()
7678
tx.vin.append(CTxIn(COutPoint(int(prevtxout["txid"], 16), prevtxout["vout"]), b""))
7779

78-
half_change = satoshi_round(prevtxout["amount"]/2)
79-
rem_change = prevtxout["amount"] - half_change - Decimal("0.00001000")
80-
tx.vout.append(CTxOut(int(half_change*COIN), P2SH_1))
81-
tx.vout.append(CTxOut(int(rem_change*COIN), P2SH_2))
80+
half_change = satoshi_round(prevtxout["amount"] / 2)
81+
rem_change = prevtxout["amount"] - half_change - Decimal("0.00001000")
82+
tx.vout.append(CTxOut(int(half_change * COIN), P2SH_1))
83+
tx.vout.append(CTxOut(int(rem_change * COIN), P2SH_2))
8284

8385
# If this is the initial split we actually need to sign the transaction
8486
# Otherwise we just need to insert the proper ScriptSig
85-
if (initial_split) :
87+
if (initial_split):
8688
completetx = from_node.signrawtransaction(ToHex(tx))["hex"]
87-
else :
89+
else:
8890
tx.vin[0].scriptSig = SCRIPT_SIG[prevtxout["vout"]]
8991
completetx = ToHex(tx)
9092
txid = from_node.sendrawtransaction(completetx, True)
91-
txouts.append({ "txid" : txid, "vout" : 0 , "amount" : half_change})
92-
txouts.append({ "txid" : txid, "vout" : 1 , "amount" : rem_change})
93-
94-
def check_estimates(node, fees_seen, max_invalid, print_estimates = True):
95-
"""
96-
This function calls estimatefee and verifies that the estimates
97-
meet certain invariants.
98-
"""
99-
all_estimates = [ node.estimatefee(i) for i in range(1,26) ]
93+
txouts.append({"txid": txid, "vout": 0, "amount": half_change})
94+
txouts.append({"txid": txid, "vout": 1, "amount": rem_change})
95+
96+
def check_estimates(node, fees_seen, max_invalid, print_estimates=True):
97+
"""Call estimatefee and verify that the estimates meet certain invariants."""
98+
99+
all_estimates = [node.estimatefee(i) for i in range(1, 26)]
100100
if print_estimates:
101-
log.info([str(all_estimates[e-1]) for e in [1,2,3,6,15,25]])
102-
delta = 1.0e-6 # account for rounding error
101+
log.info([str(all_estimates[e - 1]) for e in [1, 2, 3, 6, 15, 25]])
102+
delta = 1.0e-6 # account for rounding error
103103
last_e = max(fees_seen)
104104
for e in [x for x in all_estimates if x >= 0]:
105105
# Estimates should be within the bounds of what transactions fees actually were:
106-
if float(e)+delta < min(fees_seen) or float(e)-delta > max(fees_seen):
106+
if float(e) + delta < min(fees_seen) or float(e) - delta > max(fees_seen):
107107
raise AssertionError("Estimated fee (%f) out of range (%f,%f)"
108-
%(float(e), min(fees_seen), max(fees_seen)))
108+
% (float(e), min(fees_seen), max(fees_seen)))
109109
# Estimates should be monotonically decreasing
110-
if float(e)-delta > last_e:
110+
if float(e) - delta > last_e:
111111
raise AssertionError("Estimated fee (%f) larger than last fee (%f) for lower number of confirms"
112-
%(float(e),float(last_e)))
112+
% (float(e), float(last_e)))
113113
last_e = e
114114
valid_estimate = False
115115
invalid_estimates = 0
116-
for i,e in enumerate(all_estimates): # estimate is for i+1
116+
for i, e in enumerate(all_estimates): # estimate is for i+1
117117
if e >= 0:
118118
valid_estimate = True
119119
if i >= 13: # for n>=14 estimatesmartfee(n/2) should be at least as high as estimatefee(n)
120-
assert(node.estimatesmartfee((i+1)//2)["feerate"] > float(e) - delta)
120+
assert_greater_than(node.estimatesmartfee((i + 1) // 2)["feerate"], float(e) - delta)
121121

122122
else:
123123
invalid_estimates += 1
124124

125125
# estimatesmartfee should still be valid
126-
approx_estimate = node.estimatesmartfee(i+1)["feerate"]
127-
answer_found = node.estimatesmartfee(i+1)["blocks"]
128-
assert(approx_estimate > 0)
129-
assert(answer_found > i+1)
126+
approx_estimate = node.estimatesmartfee(i + 1)["feerate"]
127+
answer_found = node.estimatesmartfee(i + 1)["blocks"]
128+
assert_greater_than(approx_estimate, 0)
129+
assert_greater_than(answer_found, i + 1)
130130

131131
# Once we're at a high enough confirmation count that we can give an estimate
132132
# We should have estimates for all higher confirmation counts
@@ -136,7 +136,7 @@ def check_estimates(node, fees_seen, max_invalid, print_estimates = True):
136136
# Check on the expected number of different confirmation counts
137137
# that we might not have valid estimates for
138138
if invalid_estimates > max_invalid:
139-
raise AssertionError("More than (%d) invalid estimates"%(max_invalid))
139+
raise AssertionError("More than (%d) invalid estimates" % (max_invalid))
140140
return all_estimates
141141

142142

@@ -160,7 +160,6 @@ def setup_network(self):
160160
# Node2 is a stingy miner, that
161161
# produces too small blocks (room for only 55 or so transactions)
162162

163-
164163
def transact_and_mine(self, numblocks, mining_node):
165164
min_fee = Decimal("0.00001")
166165
# We will now mine numblocks blocks generating on average 100 transactions between each block
@@ -169,14 +168,14 @@ def transact_and_mine(self, numblocks, mining_node):
169168
# resorting to tx's that depend on the mempool when those run out
170169
for i in range(numblocks):
171170
random.shuffle(self.confutxo)
172-
for j in range(random.randrange(100-50,100+50)):
173-
from_index = random.randint(1,2)
171+
for j in range(random.randrange(100 - 50, 100 + 50)):
172+
from_index = random.randint(1, 2)
174173
(txhex, fee) = small_txpuzzle_randfee(self.nodes[from_index], self.confutxo,
175174
self.memutxo, Decimal("0.005"), min_fee, min_fee)
176175
tx_kbytes = (len(txhex) // 2) / 1000.0
177-
self.fees_per_kb.append(float(fee)/tx_kbytes)
176+
self.fees_per_kb.append(float(fee) / tx_kbytes)
178177
sync_mempools(self.nodes[0:3], wait=.1)
179-
mined = mining_node.getblock(mining_node.generate(1)[0],True)["tx"]
178+
mined = mining_node.getblock(mining_node.generate(1)[0], True)["tx"]
180179
sync_blocks(self.nodes[0:3], wait=.1)
181180
# update which txouts are confirmed
182181
newmem = []
@@ -210,13 +209,13 @@ def run_test(self):
210209
# Use txouts to monitor the available utxo, since these won't be tracked in wallet
211210
reps = 0
212211
while (reps < 5):
213-
#Double txouts to txouts2
214-
while (len(self.txouts)>0):
212+
# Double txouts to txouts2
213+
while (len(self.txouts) > 0):
215214
split_inputs(self.nodes[0], self.txouts, self.txouts2)
216215
while (len(self.nodes[0].getrawmempool()) > 0):
217216
self.nodes[0].generate(1)
218-
#Double txouts2 to txouts
219-
while (len(self.txouts2)>0):
217+
# Double txouts2 to txouts
218+
while (len(self.txouts2) > 0):
220219
split_inputs(self.nodes[0], self.txouts2, self.txouts)
221220
while (len(self.nodes[0].getrawmempool()) > 0):
222221
self.nodes[0].generate(1)
@@ -235,7 +234,7 @@ def run_test(self):
235234

236235
self.fees_per_kb = []
237236
self.memutxo = []
238-
self.confutxo = self.txouts # Start with the set of confirmed txouts after splitting
237+
self.confutxo = self.txouts # Start with the set of confirmed txouts after splitting
239238
self.log.info("Will output estimates for 1/2/3/6/15/25 blocks")
240239

241240
for i in range(2):

0 commit comments

Comments
 (0)