@ -780,10 +780,17 @@ void InitLogging()
LogPrintf ( " Bitcoin version %s \n " , FormatFullVersion ( ) ) ;
LogPrintf ( " Bitcoin version %s \n " , FormatFullVersion ( ) ) ;
}
}
/** Initialize bitcoin.
namespace { // Variables internal to initialization process only
* @ pre Parameters should be parsed and config file should be read .
*/
ServiceFlags nRelevantServices = NODE_NETWORK ;
bool AppInit2 ( boost : : thread_group & threadGroup , CScheduler & scheduler )
int nMaxConnections ;
int nUserMaxConnections ;
int nFD ;
ServiceFlags nLocalServices = NODE_NETWORK ;
}
bool AppInitBasicSetup ( )
{
{
// ********************************************************* Step 1: setup
// ********************************************************* Step 1: setup
# ifdef _MSC_VER
# ifdef _MSC_VER
@ -835,9 +842,13 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
// Ignore SIGPIPE, otherwise it will bring the daemon down if the client closes unexpectedly
// Ignore SIGPIPE, otherwise it will bring the daemon down if the client closes unexpectedly
signal ( SIGPIPE , SIG_IGN ) ;
signal ( SIGPIPE , SIG_IGN ) ;
# endif
# endif
return true ;
}
// ********************************************************* Step 2: parameter interactions
bool AppInitParameterInteraction ( )
{
const CChainParams & chainparams = Params ( ) ;
const CChainParams & chainparams = Params ( ) ;
// ********************************************************* Step 2: parameter interactions
// also see: InitParameterInteraction()
// also see: InitParameterInteraction()
@ -849,12 +860,12 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
// Make sure enough file descriptors are available
// Make sure enough file descriptors are available
int nBind = std : : max ( ( int ) mapArgs . count ( " -bind " ) + ( int ) mapArgs . count ( " -whitebind " ) , 1 ) ;
int nBind = std : : max ( ( int ) mapArgs . count ( " -bind " ) + ( int ) mapArgs . count ( " -whitebind " ) , 1 ) ;
int nUserMaxConnections = GetArg ( " -maxconnections " , DEFAULT_MAX_PEER_CONNECTIONS ) ;
nUserMaxConnections = GetArg ( " -maxconnections " , DEFAULT_MAX_PEER_CONNECTIONS ) ;
int nMaxConnections = std : : max ( nUserMaxConnections , 0 ) ;
nMaxConnections = std : : max ( nUserMaxConnections , 0 ) ;
// Trim requested connection counts, to fit into system limitations
// Trim requested connection counts, to fit into system limitations
nMaxConnections = std : : max ( std : : min ( nMaxConnections , ( int ) ( FD_SETSIZE - nBind - MIN_CORE_FILEDESCRIPTORS ) ) , 0 ) ;
nMaxConnections = std : : max ( std : : min ( nMaxConnections , ( int ) ( FD_SETSIZE - nBind - MIN_CORE_FILEDESCRIPTORS ) ) , 0 ) ;
int nFD = RaiseFileDescriptorLimit ( nMaxConnections + MIN_CORE_FILEDESCRIPTORS ) ;
nFD = RaiseFileDescriptorLimit ( nMaxConnections + MIN_CORE_FILEDESCRIPTORS ) ;
if ( nFD < MIN_CORE_FILEDESCRIPTORS )
if ( nFD < MIN_CORE_FILEDESCRIPTORS )
return InitError ( _ ( " Not enough file descriptors available. " ) ) ;
return InitError ( _ ( " Not enough file descriptors available. " ) ) ;
nMaxConnections = std : : min ( nFD - MIN_CORE_FILEDESCRIPTORS , nMaxConnections ) ;
nMaxConnections = std : : min ( nFD - MIN_CORE_FILEDESCRIPTORS , nMaxConnections ) ;
@ -912,8 +923,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
else if ( nScriptCheckThreads > MAX_SCRIPTCHECK_THREADS )
else if ( nScriptCheckThreads > MAX_SCRIPTCHECK_THREADS )
nScriptCheckThreads = MAX_SCRIPTCHECK_THREADS ;
nScriptCheckThreads = MAX_SCRIPTCHECK_THREADS ;
fServer = GetBoolArg ( " -server " , false ) ;
// block pruning; get the amount of disk space (in MiB) to allot for block & undo files
// block pruning; get the amount of disk space (in MiB) to allot for block & undo files
int64_t nSignedPruneTarget = GetArg ( " -prune " , 0 ) * 1024 * 1024 ;
int64_t nSignedPruneTarget = GetArg ( " -prune " , 0 ) * 1024 * 1024 ;
if ( nSignedPruneTarget < 0 ) {
if ( nSignedPruneTarget < 0 ) {
@ -969,9 +978,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
// Option to startup with mocktime set (used for regression testing):
// Option to startup with mocktime set (used for regression testing):
SetMockTime ( GetArg ( " -mocktime " , 0 ) ) ; // SetMockTime(0) is a no-op
SetMockTime ( GetArg ( " -mocktime " , 0 ) ) ; // SetMockTime(0) is a no-op
ServiceFlags nLocalServices = NODE_NETWORK ;
ServiceFlags nRelevantServices = NODE_NETWORK ;
if ( GetBoolArg ( " -peerbloomfilters " , DEFAULT_PEERBLOOMFILTERS ) )
if ( GetBoolArg ( " -peerbloomfilters " , DEFAULT_PEERBLOOMFILTERS ) )
nLocalServices = ServiceFlags ( nLocalServices | NODE_BLOOM ) ;
nLocalServices = ServiceFlags ( nLocalServices | NODE_BLOOM ) ;
@ -1020,17 +1026,11 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
}
}
}
}
}
}
return true ;
}
// ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log
static bool LockDataDirectory ( bool probeOnly )
{
// Initialize elliptic curve code
ECC_Start ( ) ;
globalVerifyHandle . reset ( new ECCVerifyHandle ( ) ) ;
// Sanity check
if ( ! InitSanityCheck ( ) )
return InitError ( strprintf ( _ ( " Initialization sanity check failed. %s is shutting down. " ) , _ ( PACKAGE_NAME ) ) ) ;
std : : string strDataDir = GetDataDir ( ) . string ( ) ;
std : : string strDataDir = GetDataDir ( ) . string ( ) ;
// Make sure only a single Bitcoin process is using the data directory.
// Make sure only a single Bitcoin process is using the data directory.
@ -1040,11 +1040,45 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
try {
try {
static boost : : interprocess : : file_lock lock ( pathLockFile . string ( ) . c_str ( ) ) ;
static boost : : interprocess : : file_lock lock ( pathLockFile . string ( ) . c_str ( ) ) ;
if ( ! lock . try_lock ( ) )
if ( ! lock . try_lock ( ) ) {
return InitError ( strprintf ( _ ( " Cannot obtain a lock on data directory %s. %s is probably already running. " ) , strDataDir , _ ( PACKAGE_NAME ) ) ) ;
return InitError ( strprintf ( _ ( " Cannot obtain a lock on data directory %s. %s is probably already running. " ) , strDataDir , _ ( PACKAGE_NAME ) ) ) ;
}
if ( probeOnly ) {
lock . unlock ( ) ;
}
} catch ( const boost : : interprocess : : interprocess_exception & e ) {
} catch ( const boost : : interprocess : : interprocess_exception & e ) {
return InitError ( strprintf ( _ ( " Cannot obtain a lock on data directory %s. %s is probably already running. " ) + " %s. " , strDataDir , _ ( PACKAGE_NAME ) , e . what ( ) ) ) ;
return InitError ( strprintf ( _ ( " Cannot obtain a lock on data directory %s. %s is probably already running. " ) + " %s. " , strDataDir , _ ( PACKAGE_NAME ) , e . what ( ) ) ) ;
}
}
return true ;
}
bool AppInitSanityChecks ( )
{
// ********************************************************* Step 4: sanity checks
// Initialize elliptic curve code
ECC_Start ( ) ;
globalVerifyHandle . reset ( new ECCVerifyHandle ( ) ) ;
// Sanity check
if ( ! InitSanityCheck ( ) )
return InitError ( strprintf ( _ ( " Initialization sanity check failed. %s is shutting down. " ) , _ ( PACKAGE_NAME ) ) ) ;
// Probe the data directory lock to give an early error message, if possible
return LockDataDirectory ( true ) ;
}
bool AppInitMain ( boost : : thread_group & threadGroup , CScheduler & scheduler )
{
const CChainParams & chainparams = Params ( ) ;
// ********************************************************* Step 4a: application initialization
// After daemonization get the data directory lock again and hold on to it until exit
// This creates a slight window for a race condition to happen, however this condition is harmless: it
// will at most make us exit without printing a message to console.
if ( ! LockDataDirectory ( false ) ) {
// Detailed error printed inside LockDataDirectory
return false ;
}
# ifndef WIN32
# ifndef WIN32
CreatePidFile ( GetPidFile ( ) , getpid ( ) ) ;
CreatePidFile ( GetPidFile ( ) , getpid ( ) ) ;
@ -1058,7 +1092,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
if ( ! fLogTimestamps )
if ( ! fLogTimestamps )
LogPrintf ( " Startup time: %s \n " , DateTimeStrFormat ( " %Y-%m-%d %H:%M:%S " , GetTime ( ) ) ) ;
LogPrintf ( " Startup time: %s \n " , DateTimeStrFormat ( " %Y-%m-%d %H:%M:%S " , GetTime ( ) ) ) ;
LogPrintf ( " Default data directory %s \n " , GetDefaultDataDir ( ) . string ( ) ) ;
LogPrintf ( " Default data directory %s \n " , GetDefaultDataDir ( ) . string ( ) ) ;
LogPrintf ( " Using data directory %s \n " , strDataDir ) ;
LogPrintf ( " Using data directory %s \n " , GetDataDir ( ) . string ( ) ) ;
LogPrintf ( " Using config file %s \n " , GetConfigFile ( GetArg ( " -conf " , BITCOIN_CONF_FILENAME ) ) . string ( ) ) ;
LogPrintf ( " Using config file %s \n " , GetConfigFile ( GetArg ( " -conf " , BITCOIN_CONF_FILENAME ) ) . string ( ) ) ;
LogPrintf ( " Using at most %i connections (%i file descriptors available) \n " , nMaxConnections , nFD ) ;
LogPrintf ( " Using at most %i connections (%i file descriptors available) \n " , nMaxConnections , nFD ) ;
@ -1077,7 +1111,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
* that the server is there and will be ready later ) . Warmup mode will
* that the server is there and will be ready later ) . Warmup mode will
* be disabled when initialisation is finished .
* be disabled when initialisation is finished .
*/
*/
if ( fServer )
if ( GetBoolArg ( " -server " , false ) )
{
{
uiInterface . InitMessage . connect ( SetRPCWarmupStatus ) ;
uiInterface . InitMessage . connect ( SetRPCWarmupStatus ) ;
if ( ! AppInitServers ( threadGroup ) )
if ( ! AppInitServers ( threadGroup ) )