@ -16,6 +16,7 @@ import shutil
import subprocess
import subprocess
import time
import time
import re
import re
import errno
from . import coverage
from . import coverage
from . authproxy import AuthServiceProxy , JSONRPCException
from . authproxy import AuthServiceProxy , JSONRPCException
@ -130,11 +131,33 @@ def initialize_datadir(dirname, n):
f . write ( " listenonion=0 \n " )
f . write ( " listenonion=0 \n " )
return datadir
return datadir
def rpc_url ( i , rpchost = None ) :
return " http://rt:rt@ %s : %d " % ( rpchost or ' 127.0.0.1 ' , rpc_port ( i ) )
def wait_for_bitcoind_start ( process , url , i ) :
'''
Wait for bitcoind to start . This means that RPC is accessible and fully initialized .
Raise an exception if bitcoind exits during initialization .
'''
while True :
if process . poll ( ) is not None :
raise Exception ( ' bitcoind exited with status %i during initialization ' % process . returncode )
try :
rpc = get_rpc_proxy ( url , i )
blocks = rpc . getblockcount ( )
break # break out of loop on success
except IOError as e :
if e . errno != errno . ECONNREFUSED : # Port not yet open?
raise # unknown IO error
except JSONRPCException as e : # Initialization phase
if e . error [ ' code ' ] != - 28 : # RPC in warmup?
raise # unkown JSON RPC exception
time . sleep ( 0.25 )
def initialize_chain ( test_dir ) :
def initialize_chain ( test_dir ) :
"""
"""
Create ( or copy from cache ) a 200 - block - long chain and
Create ( or copy from cache ) a 200 - block - long chain and
4 wallets .
4 wallets .
bitcoind and bitcoin - cli must be in search path .
"""
"""
if ( not os . path . isdir ( os . path . join ( " cache " , " node0 " ) )
if ( not os . path . isdir ( os . path . join ( " cache " , " node0 " ) )
@ -147,7 +170,6 @@ def initialize_chain(test_dir):
if os . path . isdir ( os . path . join ( " cache " , " node " + str ( i ) ) ) :
if os . path . isdir ( os . path . join ( " cache " , " node " + str ( i ) ) ) :
shutil . rmtree ( os . path . join ( " cache " , " node " + str ( i ) ) )
shutil . rmtree ( os . path . join ( " cache " , " node " + str ( i ) ) )
devnull = open ( os . devnull , " w " )
# Create cache directories, run bitcoinds:
# Create cache directories, run bitcoinds:
for i in range ( 4 ) :
for i in range ( 4 ) :
datadir = initialize_datadir ( " cache " , i )
datadir = initialize_datadir ( " cache " , i )
@ -156,19 +178,15 @@ def initialize_chain(test_dir):
args . append ( " -connect=127.0.0.1: " + str ( p2p_port ( 0 ) ) )
args . append ( " -connect=127.0.0.1: " + str ( p2p_port ( 0 ) ) )
bitcoind_processes [ i ] = subprocess . Popen ( args )
bitcoind_processes [ i ] = subprocess . Popen ( args )
if os . getenv ( " PYTHON_DEBUG " , " " ) :
if os . getenv ( " PYTHON_DEBUG " , " " ) :
print " initialize_chain: bitcoind started, calling bitcoin-cli -rpcwait getblockcount "
print " initialize_chain: bitcoind started, waiting for RPC to come up "
subprocess . check_call ( [ os . getenv ( " BITCOINCLI " , " bitcoin-cli " ) , " -datadir= " + datadir ,
wait_for_bitcoind_start ( bitcoind_processes [ i ] , rpc_url ( i ) , i )
" -rpcwait " , " getblockcount " ] , stdout = devnull )
if os . getenv ( " PYTHON_DEBUG " , " " ) :
if os . getenv ( " PYTHON_DEBUG " , " " ) :
print " initialize_chain: bitcoin-cli -rpcwait getblockcount completed "
print " initialize_chain: RPC succesfully started "
devnull . close ( )
rpcs = [ ]
rpcs = [ ]
for i in range ( 4 ) :
for i in range ( 4 ) :
try :
try :
url = " http://rt:rt@127.0.0.1: %d " % ( rpc_port ( i ) , )
rpcs . append ( get_rpc_proxy ( rpc_url ( i ) , i ) )
rpcs . append ( get_rpc_proxy ( url , i ) )
except :
except :
sys . stderr . write ( " Error connecting to " + url + " \n " )
sys . stderr . write ( " Error connecting to " + url + " \n " )
sys . exit ( 1 )
sys . exit ( 1 )
@ -243,17 +261,12 @@ def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary=
args = [ binary , " -datadir= " + datadir , " -server " , " -keypool=1 " , " -discover=0 " , " -rest " , " -mocktime= " + str ( get_mocktime ( ) ) ]
args = [ binary , " -datadir= " + datadir , " -server " , " -keypool=1 " , " -discover=0 " , " -rest " , " -mocktime= " + str ( get_mocktime ( ) ) ]
if extra_args is not None : args . extend ( extra_args )
if extra_args is not None : args . extend ( extra_args )
bitcoind_processes [ i ] = subprocess . Popen ( args )
bitcoind_processes [ i ] = subprocess . Popen ( args )
devnull = open ( os . devnull , " w " )
if os . getenv ( " PYTHON_DEBUG " , " " ) :
if os . getenv ( " PYTHON_DEBUG " , " " ) :
print " start_node: bitcoind started, calling bitcoin-cli -rpcwait getblockcount "
print " start_node: bitcoind started, waiting for RPC to come up "
subprocess . check_call ( [ os . getenv ( " BITCOINCLI " , " bitcoin-cli " ) , " -datadir= " + datadir ] +
url = rpc_url ( i , rpchost )
_rpchost_to_args ( rpchost ) +
wait_for_bitcoind_start ( bitcoind_processes [ i ] , url , i )
[ " -rpcwait " , " getblockcount " ] , stdout = devnull )
if os . getenv ( " PYTHON_DEBUG " , " " ) :
if os . getenv ( " PYTHON_DEBUG " , " " ) :
print " start_node: calling bitcoin-cli -rpcwait getblockcount returned "
print " start_node: RPC succesfully started "
devnull . close ( )
url = " http://rt:rt@ %s : %d " % ( rpchost or ' 127.0.0.1 ' , rpc_port ( i ) )
proxy = get_rpc_proxy ( url , i , timeout = timewait )
proxy = get_rpc_proxy ( url , i , timeout = timewait )
if COVERAGE_DIR :
if COVERAGE_DIR :
@ -267,7 +280,14 @@ def start_nodes(num_nodes, dirname, extra_args=None, rpchost=None, binary=None):
"""
"""
if extra_args is None : extra_args = [ None for i in range ( num_nodes ) ]
if extra_args is None : extra_args = [ None for i in range ( num_nodes ) ]
if binary is None : binary = [ None for i in range ( num_nodes ) ]
if binary is None : binary = [ None for i in range ( num_nodes ) ]
return [ start_node ( i , dirname , extra_args [ i ] , rpchost , binary = binary [ i ] ) for i in range ( num_nodes ) ]
rpcs = [ ]
try :
for i in range ( num_nodes ) :
rpcs . append ( start_node ( i , dirname , extra_args [ i ] , rpchost , binary = binary [ i ] ) )
except : # If one node failed to start, stop the others
stop_nodes ( rpcs )
raise
return rpcs
def log_filename ( dirname , n_node , logname ) :
def log_filename ( dirname , n_node , logname ) :
return os . path . join ( dirname , " node " + str ( n_node ) , " regtest " , logname )
return os . path . join ( dirname , " node " + str ( n_node ) , " regtest " , logname )