2525# Assert functions
2626##################
2727
28+
2829def assert_approx (v , vexp , vspan = 0.00001 ):
2930 """Assert that `v` is within `vspan` of `vexp`"""
3031 if v < vexp - vspan :
3132 raise AssertionError ("%s < [%s..%s]" % (str (v ), str (vexp - vspan ), str (vexp + vspan )))
3233 if v > vexp + vspan :
3334 raise AssertionError ("%s > [%s..%s]" % (str (v ), str (vexp - vspan ), str (vexp + vspan )))
3435
36+
3537def assert_fee_amount (fee , tx_size , fee_per_kB ):
3638 """Assert the fee was in range"""
3739 target_fee = round (tx_size * fee_per_kB / 1000 , 8 )
@@ -41,21 +43,26 @@ def assert_fee_amount(fee, tx_size, fee_per_kB):
4143 if fee > (tx_size + 2 ) * fee_per_kB / 1000 :
4244 raise AssertionError ("Fee of %s BTC too high! (Should be %s BTC)" % (str (fee ), str (target_fee )))
4345
46+
4447def assert_equal (thing1 , thing2 , * args ):
4548 if thing1 != thing2 or any (thing1 != arg for arg in args ):
4649 raise AssertionError ("not(%s)" % " == " .join (str (arg ) for arg in (thing1 , thing2 ) + args ))
4750
51+
4852def assert_greater_than (thing1 , thing2 ):
4953 if thing1 <= thing2 :
5054 raise AssertionError ("%s <= %s" % (str (thing1 ), str (thing2 )))
5155
56+
5257def assert_greater_than_or_equal (thing1 , thing2 ):
5358 if thing1 < thing2 :
5459 raise AssertionError ("%s < %s" % (str (thing1 ), str (thing2 )))
5560
61+
5662def assert_raises (exc , fun , * args , ** kwds ):
5763 assert_raises_message (exc , None , fun , * args , ** kwds )
5864
65+
5966def assert_raises_message (exc , message , fun , * args , ** kwds ):
6067 try :
6168 fun (* args , ** kwds )
@@ -71,6 +78,7 @@ def assert_raises_message(exc, message, fun, *args, **kwds):
7178 else :
7279 raise AssertionError ("No exception raised" )
7380
81+
7482def assert_raises_process_error (returncode , output , fun , * args , ** kwds ):
7583 """Execute a process and asserts the process return code and output.
7684
@@ -95,6 +103,7 @@ def assert_raises_process_error(returncode, output, fun, *args, **kwds):
95103 else :
96104 raise AssertionError ("No exception raised" )
97105
106+
98107def assert_raises_rpc_error (code , message , fun , * args , ** kwds ):
99108 """Run an RPC and verify that a specific JSONRPC exception code and message is raised.
100109
@@ -113,6 +122,7 @@ def assert_raises_rpc_error(code, message, fun, *args, **kwds):
113122 """
114123 assert try_rpc (code , message , fun , * args , ** kwds ), "No exception raised"
115124
125+
116126def try_rpc (code , message , fun , * args , ** kwds ):
117127 """Tries to run an rpc command.
118128
@@ -134,22 +144,22 @@ def try_rpc(code, message, fun, *args, **kwds):
134144 else :
135145 return False
136146
147+
137148def assert_is_hex_string (string ):
138149 try :
139150 int (string , 16 )
140151 except Exception as e :
141- raise AssertionError (
142- "Couldn't interpret %r as hexadecimal; raised: %s" % ( string , e ))
152+ raise AssertionError ("Couldn't interpret %r as hexadecimal; raised: %s" % ( string , e ))
153+
143154
144155def assert_is_hash_string (string , length = 64 ):
145156 if not isinstance (string , str ):
146157 raise AssertionError ("Expected a string, got type %r" % type (string ))
147158 elif length and len (string ) != length :
148- raise AssertionError (
149- "String of length %d expected; got %d" % (length , len (string )))
159+ raise AssertionError ("String of length %d expected; got %d" % (length , len (string )))
150160 elif not re .match ('[abcdef0-9]+$' , string ):
151- raise AssertionError (
152- "String %r contains invalid characters for a hash." % string )
161+ raise AssertionError ("String %r contains invalid characters for a hash." % string )
162+
153163
154164def assert_array_result (object_array , to_match , expected , should_not_find = False ):
155165 """
@@ -180,34 +190,41 @@ def assert_array_result(object_array, to_match, expected, should_not_find=False)
180190 if num_matched > 0 and should_not_find :
181191 raise AssertionError ("Objects were found %s" % (str (to_match )))
182192
193+
183194# Utility functions
184195###################
185196
197+
186198def check_json_precision ():
187199 """Make sure json library being used does not lose precision converting BTC values"""
188200 n = Decimal ("20000000.00000003" )
189201 satoshis = int (json .loads (json .dumps (float (n ))) * 1.0e8 )
190202 if satoshis != 2000000000000003 :
191203 raise RuntimeError ("JSON encode/decode loses precision" )
192204
205+
193206def EncodeDecimal (o ):
194207 if isinstance (o , Decimal ):
195208 return str (o )
196209 raise TypeError (repr (o ) + " is not JSON serializable" )
197210
211+
198212def count_bytes (hex_string ):
199213 return len (bytearray .fromhex (hex_string ))
200214
201215
202216def hex_str_to_bytes (hex_str ):
203217 return unhexlify (hex_str .encode ('ascii' ))
204218
219+
205220def str_to_b64str (string ):
206221 return b64encode (string .encode ('utf-8' )).decode ('ascii' )
207222
223+
208224def satoshi_round (amount ):
209225 return Decimal (amount ).quantize (Decimal ('0.00000001' ), rounding = ROUND_DOWN )
210226
227+
211228def wait_until (predicate , * , attempts = float ('inf' ), timeout = float ('inf' ), lock = None , timeout_factor = 1.0 ):
212229 if attempts == float ('inf' ) and timeout == float ('inf' ):
213230 timeout = 60
@@ -235,6 +252,7 @@ def wait_until(predicate, *, attempts=float('inf'), timeout=float('inf'), lock=N
235252 raise AssertionError ("Predicate {} not true after {} seconds" .format (predicate_source , timeout ))
236253 raise RuntimeError ('Unreachable' )
237254
255+
238256# RPC/P2P connection constants and functions
239257############################################
240258
@@ -250,6 +268,7 @@ class PortSeed:
250268 # Must be initialized with a unique integer for each process
251269 n = None
252270
271+
253272def get_rpc_proxy (url , node_number , * , timeout = None , coveragedir = None ):
254273 """
255274 Args:
@@ -271,18 +290,20 @@ def get_rpc_proxy(url, node_number, *, timeout=None, coveragedir=None):
271290 proxy = AuthServiceProxy (url , ** proxy_kwargs )
272291 proxy .url = url # store URL on proxy for info
273292
274- coverage_logfile = coverage .get_filename (
275- coveragedir , node_number ) if coveragedir else None
293+ coverage_logfile = coverage .get_filename (coveragedir , node_number ) if coveragedir else None
276294
277295 return coverage .AuthServiceProxyWrapper (proxy , coverage_logfile )
278296
297+
279298def p2p_port (n ):
280299 assert n <= MAX_NODES
281300 return PORT_MIN + n + (MAX_NODES * PortSeed .n ) % (PORT_RANGE - 1 - MAX_NODES )
282301
302+
283303def rpc_port (n ):
284304 return PORT_MIN + PORT_RANGE + n + (MAX_NODES * PortSeed .n ) % (PORT_RANGE - 1 - MAX_NODES )
285305
306+
286307def rpc_url (datadir , i , chain , rpchost ):
287308 rpc_u , rpc_p = get_auth_cookie (datadir , chain )
288309 host = '127.0.0.1'
@@ -295,9 +316,11 @@ def rpc_url(datadir, i, chain, rpchost):
295316 host = rpchost
296317 return "http://%s:%s@%s:%d" % (rpc_u , rpc_p , host , int (port ))
297318
319+
298320# Node functions
299321################
300322
323+
301324def initialize_datadir (dirname , n , chain ):
302325 datadir = get_datadir_path (dirname , n )
303326 if not os .path .isdir (datadir ):
@@ -327,21 +350,17 @@ def initialize_datadir(dirname, n, chain):
327350 os .makedirs (os .path .join (datadir , 'stdout' ), exist_ok = True )
328351 return datadir
329352
330- def adjust_bitcoin_conf_for_pre_17 (conf_file ):
331- with open (conf_file ,'r' , encoding = 'utf8' ) as conf :
332- conf_data = conf .read ()
333- with open (conf_file , 'w' , encoding = 'utf8' ) as conf :
334- conf_data_changed = conf_data .replace ('[regtest]' , '' )
335- conf .write (conf_data_changed )
336353
337354def get_datadir_path (dirname , n ):
338355 return os .path .join (dirname , "node" + str (n ))
339356
357+
340358def append_config (datadir , options ):
341359 with open (os .path .join (datadir , "bitcoin.conf" ), 'a' , encoding = 'utf8' ) as f :
342360 for option in options :
343361 f .write (option + "\n " )
344362
363+
345364def get_auth_cookie (datadir , chain ):
346365 user = None
347366 password = None
@@ -366,20 +385,24 @@ def get_auth_cookie(datadir, chain):
366385 raise ValueError ("No RPC credentials" )
367386 return user , password
368387
388+
369389# If a cookie file exists in the given datadir, delete it.
370390def delete_cookie_file (datadir , chain ):
371391 if os .path .isfile (os .path .join (datadir , chain , ".cookie" )):
372392 logger .debug ("Deleting leftover cookie file" )
373393 os .remove (os .path .join (datadir , chain , ".cookie" ))
374394
395+
375396def softfork_active (node , key ):
376397 """Return whether a softfork is active."""
377398 return node .getblockchaininfo ()['softforks' ][key ]['active' ]
378399
400+
379401def set_node_times (nodes , t ):
380402 for node in nodes :
381403 node .setmocktime (t )
382404
405+
383406def disconnect_nodes (from_connection , node_num ):
384407 def get_peer_ids ():
385408 result = []
@@ -392,7 +415,7 @@ def get_peer_ids():
392415 if not peer_ids :
393416 logger .warning ("disconnect_nodes: {} and {} were not connected" .format (
394417 from_connection .index ,
395- node_num
418+ node_num ,
396419 ))
397420 return
398421 for peer_id in peer_ids :
@@ -402,12 +425,13 @@ def get_peer_ids():
402425 # If this node is disconnected between calculating the peer id
403426 # and issuing the disconnect, don't worry about it.
404427 # This avoids a race condition if we're mass-disconnecting peers.
405- if e .error ['code' ] != - 29 : # RPC_CLIENT_NODE_NOT_CONNECTED
428+ if e .error ['code' ] != - 29 : # RPC_CLIENT_NODE_NOT_CONNECTED
406429 raise
407430
408431 # wait to disconnect
409432 wait_until (lambda : not get_peer_ids (), timeout = 5 )
410433
434+
411435def connect_nodes (from_connection , node_num ):
412436 ip_port = "127.0.0.1:" + str (p2p_port (node_num ))
413437 from_connection .addnode (ip_port , "onetry" )
@@ -479,6 +503,7 @@ def find_output(node, txid, amount, *, blockhash=None):
479503 return i
480504 raise RuntimeError ("find_output txid %s : %s not found" % (txid , str (amount )))
481505
506+
482507def gather_inputs (from_node , amount_needed , confirmations_required = 1 ):
483508 """
484509 Return a random set of unspent txouts that are enough to pay amount_needed
@@ -496,6 +521,7 @@ def gather_inputs(from_node, amount_needed, confirmations_required=1):
496521 raise RuntimeError ("Insufficient funds: need %d, have %d" % (amount_needed , total_in ))
497522 return (total_in , inputs )
498523
524+
499525def make_change (from_node , amount_in , amount_out , fee ):
500526 """
501527 Create change output(s), return them
@@ -513,6 +539,7 @@ def make_change(from_node, amount_in, amount_out, fee):
513539 outputs [from_node .getnewaddress ()] = change
514540 return outputs
515541
542+
516543def random_transaction (nodes , amount , min_fee , fee_increment , fee_variants ):
517544 """
518545 Create a random transaction.
@@ -532,6 +559,7 @@ def random_transaction(nodes, amount, min_fee, fee_increment, fee_variants):
532559
533560 return (txid , signresult ["hex" ], fee )
534561
562+
535563# Helper to create at least "count" utxos
536564# Pass in a fee that is sufficient for relay and mining new transactions.
537565def create_confirmed_utxos (fee , node , count ):
@@ -564,6 +592,7 @@ def create_confirmed_utxos(fee, node, count):
564592 assert len (utxos ) >= count
565593 return utxos
566594
595+
567596# Create large OP_RETURN txouts that can be appended to a transaction
568597# to make it large (helper for constructing large transactions).
569598def gen_return_txouts ():
@@ -583,6 +612,7 @@ def gen_return_txouts():
583612 txouts .append (txout )
584613 return txouts
585614
615+
586616# Create a spend of each passed-in utxo, splicing in "txouts" to each raw
587617# transaction to make it large. See gen_return_txouts() above.
588618def create_lots_of_big_transactions (node , txouts , utxos , num , fee ):
@@ -606,6 +636,7 @@ def create_lots_of_big_transactions(node, txouts, utxos, num, fee):
606636 txids .append (txid )
607637 return txids
608638
639+
609640def mine_large_block (node , utxos = None ):
610641 # generate a 66k transaction,
611642 # and 14 of them is close to the 1MB block limit
@@ -619,6 +650,7 @@ def mine_large_block(node, utxos=None):
619650 create_lots_of_big_transactions (node , txouts , utxos , num , fee = fee )
620651 node .generate (1 )
621652
653+
622654def find_vout_for_address (node , txid , addr ):
623655 """
624656 Locate the vout index of the given transaction sending to the
0 commit comments