Browse Source

Merge pull request #1369 from sipa/bootorder

Reorder AppInit2
0.8
Pieter Wuille 13 years ago
parent
commit
fa638ec8af
  1. 398
      src/init.cpp

398
src/init.cpp

@ -275,6 +275,7 @@ std::string HelpMessage()
*/ */
bool AppInit2() bool AppInit2()
{ {
// ********************************************************* Step 1: setup
#ifdef _MSC_VER #ifdef _MSC_VER
// Turn off microsoft heap dump noise // Turn off microsoft heap dump noise
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
@ -304,12 +305,35 @@ bool AppInit2()
sigaction(SIGHUP, &sa_hup, NULL); sigaction(SIGHUP, &sa_hup, NULL);
#endif #endif
// ********************************************************* Step 2: parameter interactions
fTestNet = GetBoolArg("-testnet"); fTestNet = GetBoolArg("-testnet");
if (fTestNet) if (fTestNet)
{ {
SoftSetBoolArg("-irc", true); SoftSetBoolArg("-irc", true);
} }
if (mapArgs.count("-connect"))
SoftSetBoolArg("-dnsseed", false);
// even in Tor mode, if -bind is specified, you really want -listen
if (mapArgs.count("-bind"))
SoftSetBoolArg("-listen", true);
bool fTor = (fUseProxy && addrProxy.GetPort() == 9050);
if (fTor)
{
// Use SoftSetBoolArg here so user can override any of these if they wish.
// Note: the GetBoolArg() calls for all of these must happen later.
SoftSetBoolArg("-listen", false);
SoftSetBoolArg("-irc", false);
SoftSetBoolArg("-proxydns", true);
SoftSetBoolArg("-upnp", false);
SoftSetBoolArg("-discover", false);
}
// ********************************************************* Step 3: parameter-to-internal-flags
fDebug = GetBoolArg("-debug"); fDebug = GetBoolArg("-debug");
fDetachDB = GetBoolArg("-detachdb", false); fDetachDB = GetBoolArg("-detachdb", false);
@ -332,6 +356,38 @@ bool AppInit2()
fPrintToDebugger = GetBoolArg("-printtodebugger"); fPrintToDebugger = GetBoolArg("-printtodebugger");
fLogTimestamps = GetBoolArg("-logtimestamps"); fLogTimestamps = GetBoolArg("-logtimestamps");
if (mapArgs.count("-timeout"))
{
int nNewTimeout = GetArg("-timeout", 5000);
if (nNewTimeout > 0 && nNewTimeout < 600000)
nConnectTimeout = nNewTimeout;
}
// Continue to put "/P2SH/" in the coinbase to monitor
// BIP16 support.
// This can be removed eventually...
const char* pszP2SH = "/P2SH/";
COINBASE_FLAGS << std::vector<unsigned char>(pszP2SH, pszP2SH+strlen(pszP2SH));
if (mapArgs.count("-paytxfee"))
{
if (!ParseMoney(mapArgs["-paytxfee"], nTransactionFee))
return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s'"), mapArgs["-paytxfee"].c_str()));
if (nTransactionFee > 0.25 * COIN)
InitWarning(_("Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction."));
}
// ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log
// Make sure only a single Bitcoin process is using the data directory.
boost::filesystem::path pathLockFile = GetDataDir() / ".lock";
FILE* file = fopen(pathLockFile.string().c_str(), "a"); // empty lock file; created if it doesn't exist.
if (file) fclose(file);
static boost::interprocess::file_lock lock(pathLockFile.string().c_str());
if (!lock.try_lock())
return InitError(strprintf(_("Cannot obtain a lock on data directory %s. Bitcoin is probably already running."), GetDataDir().string().c_str()));
#if !defined(WIN32) && !defined(QT_GUI) #if !defined(WIN32) && !defined(QT_GUI)
if (fDaemon) if (fDaemon)
{ {
@ -359,43 +415,104 @@ bool AppInit2()
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
printf("Bitcoin version %s (%s)\n", FormatFullVersion().c_str(), CLIENT_DATE.c_str()); printf("Bitcoin version %s (%s)\n", FormatFullVersion().c_str(), CLIENT_DATE.c_str());
printf("Default data directory %s\n", GetDefaultDataDir().string().c_str()); printf("Default data directory %s\n", GetDefaultDataDir().string().c_str());
std::ostringstream strErrors;
if (GetBoolArg("-loadblockindextest")) if (fDaemon)
fprintf(stdout, "Bitcoin server starting\n");
int64 nStart;
// ********************************************************* Step 5: network initialization
if (mapArgs.count("-proxy"))
{ {
CTxDB txdb("r"); fUseProxy = true;
txdb.LoadBlockIndex(); addrProxy = CService(mapArgs["-proxy"], 9050);
PrintBlockTree(); if (!addrProxy.IsValid())
return false; return InitError(strprintf(_("Invalid -proxy address: '%s'"), mapArgs["-proxy"].c_str()));
} }
// Make sure only a single Bitcoin process is using the data directory. if (mapArgs.count("-noproxy"))
boost::filesystem::path pathLockFile = GetDataDir() / ".lock"; {
FILE* file = fopen(pathLockFile.string().c_str(), "a"); // empty lock file; created if it doesn't exist. BOOST_FOREACH(std::string snet, mapMultiArgs["-noproxy"]) {
if (file) fclose(file); enum Network net = ParseNetwork(snet);
static boost::interprocess::file_lock lock(pathLockFile.string().c_str()); if (net == NET_UNROUTABLE)
if (!lock.try_lock()) return InitError(strprintf(_("Unknown network specified in -noproxy: '%s'"), snet.c_str()));
return InitError(strprintf(_("Cannot obtain a lock on data directory %s. Bitcoin is probably already running."), GetDataDir().string().c_str())); SetNoProxy(net);
}
}
std::ostringstream strErrors; fNameLookup = GetBoolArg("-dns");
// fProxyNameLookup = GetBoolArg("-proxydns");
// Load data files if (fProxyNameLookup)
// fNameLookup = true;
if (fDaemon) fNoListen = !GetBoolArg("-listen", true);
fprintf(stdout, "Bitcoin server starting\n"); nSocksVersion = GetArg("-socks", 5);
int64 nStart; if (nSocksVersion != 4 && nSocksVersion != 5)
return InitError(strprintf(_("Unknown -socks proxy version requested: %i"), nSocksVersion));
uiInterface.InitMessage(_("Loading addresses...")); if (mapArgs.count("-onlynet")) {
printf("Loading addresses...\n"); std::set<enum Network> nets;
nStart = GetTimeMillis(); BOOST_FOREACH(std::string snet, mapMultiArgs["-onlynet"]) {
enum Network net = ParseNetwork(snet);
if (net == NET_UNROUTABLE)
return InitError(strprintf(_("Unknown network specified in -onlynet: '%s'"), snet.c_str()));
nets.insert(net);
}
for (int n = 0; n < NET_MAX; n++) {
enum Network net = (enum Network)n;
if (!nets.count(net))
SetLimited(net);
}
}
BOOST_FOREACH(string strDest, mapMultiArgs["-seednode"])
AddOneShot(strDest);
bool fBound = false;
if (!fNoListen)
{ {
CAddrDB adb; std::string strError;
if (!adb.Read(addrman)) if (mapArgs.count("-bind")) {
printf("Invalid or missing peers.dat; recreating\n"); BOOST_FOREACH(std::string strBind, mapMultiArgs["-bind"]) {
CService addrBind;
if (!Lookup(strBind.c_str(), addrBind, GetListenPort(), false))
return InitError(strprintf(_("Cannot resolve -bind address: '%s'"), strBind.c_str()));
fBound |= Bind(addrBind);
}
} else {
struct in_addr inaddr_any;
inaddr_any.s_addr = INADDR_ANY;
if (!IsLimited(NET_IPV4))
fBound |= Bind(CService(inaddr_any, GetListenPort()));
#ifdef USE_IPV6
if (!IsLimited(NET_IPV6))
fBound |= Bind(CService(in6addr_any, GetListenPort()));
#endif
}
if (!fBound)
return InitError(_("Not listening on any port"));
} }
printf("Loaded %i addresses from peers.dat %"PRI64d"ms\n", if (mapArgs.count("-externalip"))
addrman.size(), GetTimeMillis() - nStart); {
BOOST_FOREACH(string strAddr, mapMultiArgs["-externalip"]) {
CService addrLocal(strAddr, GetListenPort(), fNameLookup);
if (!addrLocal.IsValid())
return InitError(strprintf(_("Cannot resolve -externalip address: '%s'"), strAddr.c_str()));
AddLocal(CService(strAddr, GetListenPort(), fNameLookup), LOCAL_MANUAL);
}
}
// ********************************************************* Step 6: load blockchain
if (GetBoolArg("-loadblockindextest"))
{
CTxDB txdb("r");
txdb.LoadBlockIndex();
PrintBlockTree();
return false;
}
uiInterface.InitMessage(_("Loading block index...")); uiInterface.InitMessage(_("Loading block index..."));
printf("Loading block index...\n"); printf("Loading block index...\n");
@ -413,16 +530,37 @@ bool AppInit2()
} }
printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart); printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart);
if (mapArgs.count("-loadblock")) if (GetBoolArg("-printblockindex") || GetBoolArg("-printblocktree"))
{ {
BOOST_FOREACH(string strFile, mapMultiArgs["-loadblock"]) PrintBlockTree();
return false;
}
if (mapArgs.count("-printblock"))
{
string strMatch = mapArgs["-printblock"];
int nFound = 0;
for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
{ {
FILE *file = fopen(strFile.c_str(), "rb"); uint256 hash = (*mi).first;
if (file) if (strncmp(hash.ToString().c_str(), strMatch.c_str(), strMatch.size()) == 0)
LoadExternalBlockFile(file); {
CBlockIndex* pindex = (*mi).second;
CBlock block;
block.ReadFromDisk(pindex);
block.BuildMerkleTree();
block.print();
printf("\n");
nFound++;
}
} }
if (nFound == 0)
printf("No blocks matching %s were found\n", strMatch.c_str());
return false;
} }
// ********************************************************* Step 7: load wallet
uiInterface.InitMessage(_("Loading wallet...")); uiInterface.InitMessage(_("Loading wallet..."));
printf("Loading wallet...\n"); printf("Loading wallet...\n");
nStart = GetTimeMillis(); nStart = GetTimeMillis();
@ -498,192 +636,64 @@ bool AppInit2()
printf(" rescan %15"PRI64d"ms\n", GetTimeMillis() - nStart); printf(" rescan %15"PRI64d"ms\n", GetTimeMillis() - nStart);
} }
uiInterface.InitMessage(_("Done loading")); // ********************************************************* Step 8: import blocks
printf("Done loading\n");
//// debug print
printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size());
printf("nBestHeight = %d\n", nBestHeight);
printf("setKeyPool.size() = %d\n", pwalletMain->setKeyPool.size());
printf("mapWallet.size() = %d\n", pwalletMain->mapWallet.size());
printf("mapAddressBook.size() = %d\n", pwalletMain->mapAddressBook.size());
if (!strErrors.str().empty())
return InitError(strErrors.str());
// Add wallet transactions that aren't already in a block to mapTransactions
pwalletMain->ReacceptWalletTransactions();
// Note: Bitcoin-Qt stores several settings in the wallet, so we want
// to load the wallet BEFORE parsing command-line arguments, so
// the command-line/bitcoin.conf settings override GUI setting.
// if (mapArgs.count("-loadblock"))
// Parameters
//
if (GetBoolArg("-printblockindex") || GetBoolArg("-printblocktree"))
{
PrintBlockTree();
return false;
}
if (mapArgs.count("-timeout"))
{
int nNewTimeout = GetArg("-timeout", 5000);
if (nNewTimeout > 0 && nNewTimeout < 600000)
nConnectTimeout = nNewTimeout;
}
if (mapArgs.count("-printblock"))
{ {
string strMatch = mapArgs["-printblock"]; BOOST_FOREACH(string strFile, mapMultiArgs["-loadblock"])
int nFound = 0;
for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
{ {
uint256 hash = (*mi).first; FILE *file = fopen(strFile.c_str(), "rb");
if (strncmp(hash.ToString().c_str(), strMatch.c_str(), strMatch.size()) == 0) if (file)
{ LoadExternalBlockFile(file);
CBlockIndex* pindex = (*mi).second;
CBlock block;
block.ReadFromDisk(pindex);
block.BuildMerkleTree();
block.print();
printf("\n");
nFound++;
}
}
if (nFound == 0)
printf("No blocks matching %s were found\n", strMatch.c_str());
return false;
}
if (mapArgs.count("-proxy"))
{
fUseProxy = true;
addrProxy = CService(mapArgs["-proxy"], 9050);
if (!addrProxy.IsValid())
return InitError(strprintf(_("Invalid -proxy address: '%s'"), mapArgs["-proxy"].c_str()));
}
if (mapArgs.count("-noproxy"))
{
BOOST_FOREACH(std::string snet, mapMultiArgs["-noproxy"]) {
enum Network net = ParseNetwork(snet);
if (net == NET_UNROUTABLE)
return InitError(strprintf(_("Unknown network specified in -noproxy: '%s'"), snet.c_str()));
SetNoProxy(net);
}
}
if (mapArgs.count("-connect"))
SoftSetBoolArg("-dnsseed", false);
// even in Tor mode, if -bind is specified, you really want -listen
if (mapArgs.count("-bind"))
SoftSetBoolArg("-listen", true);
bool fTor = (fUseProxy && addrProxy.GetPort() == 9050);
if (fTor)
{
// Use SoftSetBoolArg here so user can override any of these if they wish.
// Note: the GetBoolArg() calls for all of these must happen later.
SoftSetBoolArg("-listen", false);
SoftSetBoolArg("-irc", false);
SoftSetBoolArg("-proxydns", true);
SoftSetBoolArg("-upnp", false);
SoftSetBoolArg("-discover", false);
}
if (mapArgs.count("-onlynet")) {
std::set<enum Network> nets;
BOOST_FOREACH(std::string snet, mapMultiArgs["-onlynet"]) {
enum Network net = ParseNetwork(snet);
if (net == NET_UNROUTABLE)
return InitError(strprintf(_("Unknown network specified in -onlynet: '%s'"), snet.c_str()));
nets.insert(net);
}
for (int n = 0; n < NET_MAX; n++) {
enum Network net = (enum Network)n;
if (!nets.count(net))
SetLimited(net);
} }
} }
fNameLookup = GetBoolArg("-dns"); // ********************************************************* Step 9: load peers
fProxyNameLookup = GetBoolArg("-proxydns");
if (fProxyNameLookup)
fNameLookup = true;
fNoListen = !GetBoolArg("-listen", true);
nSocksVersion = GetArg("-socks", 5);
if (nSocksVersion != 4 && nSocksVersion != 5)
return InitError(strprintf(_("Unknown -socks proxy version requested: %i"), nSocksVersion));
BOOST_FOREACH(string strDest, mapMultiArgs["-seednode"]) uiInterface.InitMessage(_("Loading addresses..."));
AddOneShot(strDest); printf("Loading addresses...\n");
nStart = GetTimeMillis();
// Continue to put "/P2SH/" in the coinbase to monitor
// BIP16 support.
// This can be removed eventually...
const char* pszP2SH = "/P2SH/";
COINBASE_FLAGS << std::vector<unsigned char>(pszP2SH, pszP2SH+strlen(pszP2SH));
bool fBound = false;
if (!fNoListen)
{ {
std::string strError; CAddrDB adb;
if (mapArgs.count("-bind")) { if (!adb.Read(addrman))
BOOST_FOREACH(std::string strBind, mapMultiArgs["-bind"]) { printf("Invalid or missing peers.dat; recreating\n");
CService addrBind;
if (!Lookup(strBind.c_str(), addrBind, GetListenPort(), false))
return InitError(strprintf(_("Cannot resolve -bind address: '%s'"), strBind.c_str()));
fBound |= Bind(addrBind);
}
} else {
struct in_addr inaddr_any;
inaddr_any.s_addr = INADDR_ANY;
if (!IsLimited(NET_IPV4))
fBound |= Bind(CService(inaddr_any, GetListenPort()));
#ifdef USE_IPV6
if (!IsLimited(NET_IPV6))
fBound |= Bind(CService(in6addr_any, GetListenPort()));
#endif
}
if (!fBound)
return InitError(_("Not listening on any port"));
} }
if (mapArgs.count("-externalip")) printf("Loaded %i addresses from peers.dat %"PRI64d"ms\n",
{ addrman.size(), GetTimeMillis() - nStart);
BOOST_FOREACH(string strAddr, mapMultiArgs["-externalip"]) {
CService addrLocal(strAddr, GetListenPort(), fNameLookup);
if (!addrLocal.IsValid())
return InitError(strprintf(_("Cannot resolve -externalip address: '%s'"), strAddr.c_str()));
AddLocal(CService(strAddr, GetListenPort(), fNameLookup), LOCAL_MANUAL);
}
}
if (mapArgs.count("-paytxfee")) // ********************************************************* Step 10: start node
{
if (!ParseMoney(mapArgs["-paytxfee"], nTransactionFee))
return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s'"), mapArgs["-paytxfee"].c_str()));
if (nTransactionFee > 0.25 * COIN)
InitWarning(_("Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction."));
}
//
// Start the node
//
if (!CheckDiskSpace()) if (!CheckDiskSpace())
return false; return false;
RandAddSeedPerfmon(); RandAddSeedPerfmon();
//// debug print
printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size());
printf("nBestHeight = %d\n", nBestHeight);
printf("setKeyPool.size() = %d\n", pwalletMain->setKeyPool.size());
printf("mapWallet.size() = %d\n", pwalletMain->mapWallet.size());
printf("mapAddressBook.size() = %d\n", pwalletMain->mapAddressBook.size());
if (!CreateThread(StartNode, NULL)) if (!CreateThread(StartNode, NULL))
InitError(_("Error: could not start node")); InitError(_("Error: could not start node"));
if (fServer) if (fServer)
CreateThread(ThreadRPCServer, NULL); CreateThread(ThreadRPCServer, NULL);
// ********************************************************* Step 11: finished
uiInterface.InitMessage(_("Done loading"));
printf("Done loading\n");
if (!strErrors.str().empty())
return InitError(strErrors.str());
// Add wallet transactions that aren't already in a block to mapTransactions
pwalletMain->ReacceptWalletTransactions();
#if !defined(QT_GUI) #if !defined(QT_GUI)
// Loop until process is exit()ed from shutdown() function, // Loop until process is exit()ed from shutdown() function,
// called from ThreadRPCServer thread when a "stop" command is received. // called from ThreadRPCServer thread when a "stop" command is received.

Loading…
Cancel
Save