Skip to content

Commit 0cc8b6b

Browse files
committed
init: Split up AppInit2 into multiple phases
This allows doing some of the steps before e.g. daemonization and some fater.
1 parent 67728a3 commit 0cc8b6b

File tree

4 files changed

+95
-21
lines changed

4 files changed

+95
-21
lines changed

src/bitcoind.cpp

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,26 @@ bool AppInit(int argc, char* argv[])
128128
fprintf(stderr, "Error: There is no RPC client functionality in bitcoind anymore. Use the bitcoin-cli utility instead.\n");
129129
exit(1);
130130
}
131+
// -server defaults to true for bitcoind but not for the GUI so do this here
132+
SoftSetBoolArg("-server", true);
133+
// Set this early so that parameter interactions go to console
134+
InitLogging();
135+
InitParameterInteraction();
136+
if (!AppInitBasicSetup())
137+
{
138+
// InitError will have been called with detailed error, which ends up on console
139+
exit(1);
140+
}
141+
if (!AppInitParameterInteraction())
142+
{
143+
// InitError will have been called with detailed error, which ends up on console
144+
exit(1);
145+
}
146+
if (!AppInitSanityChecks())
147+
{
148+
// InitError will have been called with detailed error, which ends up on console
149+
exit(1);
150+
}
131151
if (GetBoolArg("-daemon", false))
132152
{
133153
#if HAVE_DECL_DAEMON
@@ -143,12 +163,8 @@ bool AppInit(int argc, char* argv[])
143163
return false;
144164
#endif // HAVE_DECL_DAEMON
145165
}
146-
SoftSetBoolArg("-server", true);
147166

148-
// Set this early so that parameter interactions go to console
149-
InitLogging();
150-
InitParameterInteraction();
151-
fRet = AppInit2(threadGroup, scheduler);
167+
fRet = AppInitMain(threadGroup, scheduler);
152168
}
153169
catch (const std::exception& e) {
154170
PrintExceptionContinue(&e, "AppInit()");

src/init.cpp

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -788,10 +788,17 @@ void InitLogging()
788788
LogPrintf("Bitcoin version %s\n", FormatFullVersion());
789789
}
790790

791-
/** Initialize bitcoin.
792-
* @pre Parameters should be parsed and config file should be read.
793-
*/
794-
bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
791+
namespace { // Variables internal to initialization process only
792+
793+
ServiceFlags nRelevantServices = NODE_NETWORK;
794+
int nMaxConnections;
795+
int nUserMaxConnections;
796+
int nFD;
797+
ServiceFlags nLocalServices = NODE_NETWORK;
798+
799+
}
800+
801+
bool AppInitBasicSetup()
795802
{
796803
// ********************************************************* Step 1: setup
797804
#ifdef _MSC_VER
@@ -843,9 +850,13 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
843850
// Ignore SIGPIPE, otherwise it will bring the daemon down if the client closes unexpectedly
844851
signal(SIGPIPE, SIG_IGN);
845852
#endif
853+
return true;
854+
}
846855

847-
// ********************************************************* Step 2: parameter interactions
856+
bool AppInitParameterInteraction()
857+
{
848858
const CChainParams& chainparams = Params();
859+
// ********************************************************* Step 2: parameter interactions
849860

850861
// also see: InitParameterInteraction()
851862

@@ -857,12 +868,12 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
857868

858869
// Make sure enough file descriptors are available
859870
int nBind = std::max((int)mapArgs.count("-bind") + (int)mapArgs.count("-whitebind"), 1);
860-
int nUserMaxConnections = GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS);
861-
int nMaxConnections = std::max(nUserMaxConnections, 0);
871+
nUserMaxConnections = GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS);
872+
nMaxConnections = std::max(nUserMaxConnections, 0);
862873

863874
// Trim requested connection counts, to fit into system limitations
864875
nMaxConnections = std::max(std::min(nMaxConnections, (int)(FD_SETSIZE - nBind - MIN_CORE_FILEDESCRIPTORS)), 0);
865-
int nFD = RaiseFileDescriptorLimit(nMaxConnections + MIN_CORE_FILEDESCRIPTORS);
876+
nFD = RaiseFileDescriptorLimit(nMaxConnections + MIN_CORE_FILEDESCRIPTORS);
866877
if (nFD < MIN_CORE_FILEDESCRIPTORS)
867878
return InitError(_("Not enough file descriptors available."));
868879
nMaxConnections = std::min(nFD - MIN_CORE_FILEDESCRIPTORS, nMaxConnections);
@@ -977,9 +988,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
977988
// Option to startup with mocktime set (used for regression testing):
978989
SetMockTime(GetArg("-mocktime", 0)); // SetMockTime(0) is a no-op
979990

980-
ServiceFlags nLocalServices = NODE_NETWORK;
981-
ServiceFlags nRelevantServices = NODE_NETWORK;
982-
983991
if (GetBoolArg("-peerbloomfilters", DEFAULT_PEERBLOOMFILTERS))
984992
nLocalServices = ServiceFlags(nLocalServices | NODE_BLOOM);
985993

@@ -1028,8 +1036,12 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
10281036
}
10291037
}
10301038
}
1039+
return true;
1040+
}
10311041

1032-
// ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log
1042+
bool AppInitSanityChecks()
1043+
{
1044+
// ********************************************************* Step 4: sanity checks
10331045

10341046
// Initialize elliptic curve code
10351047
ECC_Start();
@@ -1048,11 +1060,19 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
10481060

10491061
try {
10501062
static boost::interprocess::file_lock lock(pathLockFile.string().c_str());
1051-
if (!lock.try_lock())
1063+
if (!lock.try_lock()) {
10521064
return InitError(strprintf(_("Cannot obtain a lock on data directory %s. %s is probably already running."), strDataDir, _(PACKAGE_NAME)));
1065+
}
10531066
} catch(const boost::interprocess::interprocess_exception& e) {
10541067
return InitError(strprintf(_("Cannot obtain a lock on data directory %s. %s is probably already running.") + " %s.", strDataDir, _(PACKAGE_NAME), e.what()));
10551068
}
1069+
return true;
1070+
}
1071+
1072+
bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
1073+
{
1074+
const CChainParams& chainparams = Params();
1075+
// ********************************************************* Step 4a: application initialization
10561076

10571077
#ifndef WIN32
10581078
CreatePidFile(GetPidFile(), getpid());
@@ -1066,7 +1086,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
10661086
if (!fLogTimestamps)
10671087
LogPrintf("Startup time: %s\n", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()));
10681088
LogPrintf("Default data directory %s\n", GetDefaultDataDir().string());
1069-
LogPrintf("Using data directory %s\n", strDataDir);
1089+
LogPrintf("Using data directory %s\n", GetDataDir().string());
10701090
LogPrintf("Using config file %s\n", GetConfigFile(GetArg("-conf", BITCOIN_CONF_FILENAME)).string());
10711091
LogPrintf("Using at most %i connections (%i file descriptors available)\n", nMaxConnections, nFD);
10721092

src/init.h

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,30 @@ void Shutdown();
2525
void InitLogging();
2626
//!Parameter interaction: change current parameters depending on various rules
2727
void InitParameterInteraction();
28-
bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler);
28+
29+
/** Initialize bitcoin core: Basic context setup.
30+
* @note This can be done before daemonization.
31+
* @pre Parameters should be parsed and config file should be read.
32+
*/
33+
bool AppInitBasicSetup();
34+
/**
35+
* Initialization: parameter interaction.
36+
* @note This can be done before daemonization.
37+
* @pre Parameters should be parsed and config file should be read, AppInitBasicSetup should have been called.
38+
*/
39+
bool AppInitParameterInteraction();
40+
/**
41+
* Initialization sanity checks: ecc init, sanity checks, dir lock.
42+
* @note This can be done before daemonization.
43+
* @pre Parameters should be parsed and config file should be read, AppInitParameterInteraction should have been called.
44+
*/
45+
bool AppInitSanityChecks();
46+
/**
47+
* Bitcoin core main initialization.
48+
* @note This should only be done after daemonization.
49+
* @pre Parameters should be parsed and config file should be read, AppInitSanityChecks should have been called.
50+
*/
51+
bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler);
2952

3053
/** The help message mode determines what help message to show */
3154
enum HelpMessageMode {

src/qt/bitcoin.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,22 @@ void BitcoinCore::initialize()
267267
try
268268
{
269269
qDebug() << __func__ << ": Running AppInit2 in thread";
270-
int rv = AppInit2(threadGroup, scheduler);
270+
if (!AppInitBasicSetup())
271+
{
272+
Q_EMIT initializeResult(false);
273+
return;
274+
}
275+
if (!AppInitParameterInteraction())
276+
{
277+
Q_EMIT initializeResult(false);
278+
return;
279+
}
280+
if (!AppInitSanityChecks())
281+
{
282+
Q_EMIT initializeResult(false);
283+
return;
284+
}
285+
int rv = AppInitMain(threadGroup, scheduler);
271286
Q_EMIT initializeResult(rv);
272287
} catch (const std::exception& e) {
273288
handleRunawayException(&e);

0 commit comments

Comments
 (0)